Merge
diff --git a/nashorn/.hgignore b/nashorn/.hgignore
new file mode 100644
index 0000000..d07a19d
--- /dev/null
+++ b/nashorn/.hgignore
@@ -0,0 +1,25 @@
+syntax: glob
+
+^.hgtip
+build/*
+dist/*
+/nbproject/private/
+private.xml
+private.properties
+webrev/*
+webrev.zip
+*.class
+*.clazz
+*.log
+*.orig
+genfiles.properties
+hotspot.log
+.DS_Store*
+TEST-*.xml
+TESTS-*.xml
+report.xml
+CC/*
+jcov2/*
+.idea/*
+test/lib/testng.jar
+test/script/external/*
diff --git a/nashorn/.hgtags b/nashorn/.hgtags
new file mode 100644
index 0000000..4eb67ac
--- /dev/null
+++ b/nashorn/.hgtags
@@ -0,0 +1,193 @@
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b24
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b25
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b26
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b27
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b28
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b29
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b30
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b31
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b32
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b33
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b34
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b35
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b36
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b37
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b38
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b39
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b40
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b41
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b42
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b43
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b44
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b45
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b46
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b47
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b48
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b49
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b50
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b51
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b52
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b53
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b54
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b55
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b56
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b57
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b58
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b59
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b60
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b61
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b62
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b63
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b64
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b65
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b66
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b67
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b68
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b69
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b70
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b71
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b72
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b73
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b74
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b75
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b76
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b77
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b78
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b79
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b80
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b81
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b82
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b83
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b84
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b85
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b86
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b87
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b88
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b89
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b90
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b91
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b92
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b93
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b94
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b95
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b96
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b97
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b98
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b99
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b100
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b101
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b102
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b103
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b104
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b105
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b106
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b107
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b108
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b109
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b110
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b111
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b112
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b113
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b114
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b115
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b116
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b117
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b118
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b119
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b120
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b121
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b122
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b123
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b124
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b125
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b126
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b127
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b128
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b129
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b130
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b131
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b132
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b133
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b134
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b135
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b136
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b137
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b138
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b139
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b140
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b141
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b142
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b143
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b144
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b145
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b146
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk7-b147
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b01
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b02
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b03
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b04
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b05
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b06
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b07
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b08
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b09
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b10
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b11
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b12
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b13
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b14
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b15
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b17
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b16
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b18
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b19
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b20
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b21
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b22
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b23
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b24
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b25
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b26
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b27
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b28
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b29
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b30
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b31
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b32
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b33
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b34
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b35
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b36
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b37
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b38
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b39
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b40
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b41
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b42
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b43
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b44
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b45
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b46
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b47
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b48
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b49
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b50
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b51
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b52
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b53
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b54
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b55
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b56
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b57
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b58
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b59
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b60
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b61
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b62
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b63
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b64
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b65
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b66
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b67
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b68
+b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b69
diff --git a/nashorn/.jcheck/conf b/nashorn/.jcheck/conf
new file mode 100644
index 0000000..6d0dbe4
--- /dev/null
+++ b/nashorn/.jcheck/conf
@@ -0,0 +1 @@
+project=jdk8
diff --git a/nashorn/ASSEMBLY_EXCEPTION b/nashorn/ASSEMBLY_EXCEPTION
new file mode 100644
index 0000000..8b7ac1d
--- /dev/null
+++ b/nashorn/ASSEMBLY_EXCEPTION
@@ -0,0 +1,27 @@
+
+OPENJDK ASSEMBLY EXCEPTION
+
+The OpenJDK source code made available by Sun at openjdk.java.net and
+openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the
+GNU General Public License <http://www.gnu.org/copyleft/gpl.html> version 2
+only ("GPL2"), with the following clarification and special exception.
+
+    Linking this OpenJDK Code statically or dynamically with other code
+    is making a combined work based on this library.  Thus, the terms
+    and conditions of GPL2 cover the whole combination.
+
+    As a special exception, Sun gives you permission to link this
+    OpenJDK Code with certain code licensed by Sun as indicated at
+    http://openjdk.java.net/legal/exception-modules-2007-05-08.html
+    ("Designated Exception Modules") to produce an executable,
+    regardless of the license terms of the Designated Exception Modules,
+    and to copy and distribute the resulting executable under GPL2,
+    provided that the Designated Exception Modules continue to be
+    governed by the licenses under which they were offered by Sun.
+
+As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to
+build an executable that includes those portions of necessary code that Sun
+could not provide under GPL2 (or that Sun has provided under GPL2 with the
+Classpath exception).  If you modify or add to the OpenJDK code, that new
+GPL2 code may still be combined with Designated Exception Modules if the
+new code is made subject to this exception by its copyright holder.
diff --git a/nashorn/LICENSE b/nashorn/LICENSE
new file mode 100644
index 0000000..b40a0f4
--- /dev/null
+++ b/nashorn/LICENSE
@@ -0,0 +1,347 @@
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it.  By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.  This General Public License applies to
+most of the Free Software Foundation's software and to any other program whose
+authors commit to using it.  (Some other Free Software Foundation software is
+covered by the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not price.  Our
+General Public Licenses are designed to make sure that you have the freedom to
+distribute copies of free software (and charge for this service if you wish),
+that you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs; and that you know you
+can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny
+you these rights or to ask you to surrender the rights.  These restrictions
+translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for
+a fee, you must give the recipients all the rights that you have.  You must
+make sure that they, too, receive or can get the source code.  And you must
+show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software.  If the
+software is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents.  We
+wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program proprietary.
+To prevent this, we have made it clear that any patent must be licensed for
+everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms of
+this General Public License.  The "Program", below, refers to any such program
+or work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or
+translated into another language.  (Hereinafter, translation is included
+without limitation in the term "modification".) Each licensee is addressed as
+"you".
+
+Activities other than copying, distribution and modification are not covered by
+this License; they are outside its scope.  The act of running the Program is
+not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by
+running the Program).  Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as
+you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and give any other recipients of the
+Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may
+at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus
+forming a work based on the Program, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+    a) You must cause the modified files to carry prominent notices stating
+    that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in whole or
+    in part contains or is derived from the Program or any part thereof, to be
+    licensed as a whole at no charge to all third parties under the terms of
+    this License.
+
+    c) If the modified program normally reads commands interactively when run,
+    you must cause it, when started running for such interactive use in the
+    most ordinary way, to print or display an announcement including an
+    appropriate copyright notice and a notice that there is no warranty (or
+    else, saying that you provide a warranty) and that users may redistribute
+    the program under these conditions, and telling the user how to view a copy
+    of this License.  (Exception: if the Program itself is interactive but does
+    not normally print such an announcement, your work based on the Program is
+    not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License, and
+its terms, do not apply to those sections when you distribute them as separate
+works.  But when you distribute the same sections as part of a whole which is a
+work based on the Program, the distribution of the whole must be on the terms
+of this License, whose permissions for other licensees extend to the entire
+whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based on
+the Program.
+
+In addition, mere aggregation of another work not based on the Program with the
+Program (or with a work based on the Program) on a volume of a storage or
+distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1 and
+2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable source
+    code, which must be distributed under the terms of Sections 1 and 2 above
+    on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three years, to
+    give any third party, for a charge no more than your cost of physically
+    performing source distribution, a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of Sections 1
+    and 2 above on a medium customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer to
+    distribute corresponding source code.  (This alternative is allowed only
+    for noncommercial distribution and only if you received the program in
+    object code or executable form with such an offer, in accord with
+    Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it.  For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable.  However, as a special exception, the source code
+distributed need not include anything that is normally distributed (in either
+source or binary form) with the major components (compiler, kernel, and so on)
+of the operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the source
+code from the same place counts as distribution of the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License.  Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License.  However, parties who have received copies, or
+rights, from you under this License will not have their licenses terminated so
+long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the Program
+or its derivative works.  These actions are prohibited by law if you do not
+accept this License.  Therefore, by modifying or distributing the Program (or
+any work based on the Program), you indicate your acceptance of this License to
+do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program),
+the recipient automatically receives a license from the original licensor to
+copy, distribute or modify the Program subject to these terms and conditions.
+You may not impose any further restrictions on the recipients' exercise of the
+rights granted herein.  You are not responsible for enforcing compliance by
+third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License.  If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at all.
+For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through
+you, then the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices.  Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose that
+choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded.  In
+such case, this License incorporates the limitation as if written in the body
+of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the
+General Public License from time to time.  Such new versions will be similar in
+spirit to the present version, but may differ in detail to address new problems
+or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any later
+version", you have the option of following the terms and conditions either of
+that version or of any later version published by the Free Software Foundation.
+If the Program does not specify a version number of this License, you may
+choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission.  For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE,
+YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
+PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program.  It is safest to attach
+them to the start of each source file to most effectively convey the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+    One line to give the program's name and a brief idea of what it does.
+
+    Copyright (C) <year> <name of author>
+
+    This program is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the Free
+    Software Foundation; either version 2 of the License, or (at your option)
+    any later version.
+
+    This program 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 for
+    more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc., 59
+    Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when it
+starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
+    with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free
+    software, and you are welcome to redistribute it under certain conditions;
+    type 'show c' for details.
+
+The hypothetical commands 'show w' and 'show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may be
+called something other than 'show w' and 'show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.  Here
+is a sample; alter the names:
+
+    Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+    'Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+    signature of Ty Coon, 1 April 1989
+
+    Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General Public
+License instead of this License.
+
+
+"CLASSPATH" EXCEPTION TO THE GPL
+
+Certain source files distributed by Oracle America and/or its affiliates are
+subject to the following clarification and special exception to the GPL, but
+only where Oracle has expressly included in the particular source file's header
+the words "Oracle designates this particular file as subject to the "Classpath"
+exception as provided by Oracle in the LICENSE file that accompanied this code."
+
+    Linking this library statically or dynamically with other modules is making
+    a combined work based on this library.  Thus, the terms and conditions of
+    the GNU General Public License cover the whole combination.
+
+    As a special exception, the copyright holders of this library give you
+    permission to link this library with independent modules to produce an
+    executable, regardless of the license terms of these independent modules,
+    and to copy and distribute the resulting executable under terms of your
+    choice, provided that you also meet, for each linked independent module,
+    the terms and conditions of the license of that module.  An independent
+    module is a module which is not derived from or based on this library.  If
+    you modify this library, you may extend this exception to your version of
+    the library, but you are not obligated to do so.  If you do not wish to do
+    so, delete this exception statement from your version.
diff --git a/nashorn/README b/nashorn/README
new file mode 100644
index 0000000..52b3091
--- /dev/null
+++ b/nashorn/README
@@ -0,0 +1,147 @@
+- What is Nashorn?
+
+Nashorn is a runtime environment for programs written in ECMAScript 5.1
+that runs on top of JVM.
+
+- How to find out more about ECMAScript 5.1?
+
+The specification can be found at
+
+    http://www.ecma-international.org/publications/standards/Ecma-262.htm
+
+- How to checkout sources of Nashorn project?
+
+Nashorn project uses Mercurial source code control system. You can
+download Mercurial from http://mercurial.selenic.com/wiki/Download
+
+Information about the forest extension can be found at
+
+    http://mercurial.selenic.com/wiki/ForestExtension
+
+and downlaoded using
+
+    hg clone https://bitbucket.org/gxti/hgforest
+
+You can clone Nashorn Mercurial forest using this command:
+
+    hg fclone http://hg.openjdk.java.net/nashorn/jdk8 nashorn~jdk8
+    
+To update your copy of the forest (fwith the latest code:
+
+    (cd nashorn~jdk8 ; hg fpull)
+    
+Or just the nashorn subdirectory with
+
+    (cd nashorn~jdk8/nashorn ; hg pull -u)
+    
+To learn about Mercurial in detail, please visit http://hgbook.red-bean.com.
+
+- How to build?
+
+To build Nashorn, you need to install JDK 8. You may use the Nashorn
+forest build (recommended) or down load from java.net.  You will need to
+set JAVA_HOME environmental variable to point to your JDK installation
+directory.
+
+    cd nashorn~jdk8/nashorn/make
+    ant clean; ant
+
+- How to run?
+
+Use the jjs script (see RELESE_README):
+
+    cd nashorn~jdk8/nashorn
+    sh bin/jjs <your .js file>
+
+Nashorn supports javax.script API. It is possible to drop nashorn.jar in
+class path and request for "nashorn" script engine from
+javax.script.ScriptEngineManager. 
+
+Look for samples under the directory test/src/jdk/nashorn/api/scripting/.
+
+- Documentation
+
+Comprehensive development documentation is found in the Nashorn JavaDoc. You can
+build it using:
+
+    cd nashorn~jdk8/nashorn/make
+    ant javadoc
+    
+after which you can view the generated documentation at dist/javadoc/index.html.
+
+- Running tests
+
+Nashorn tests are TestNG based. Running tests requires downloading the
+TestNG library and placing its jar file into the lib subdirectory:
+
+    # download and install TestNG
+    wget http://testng.org/testng-x.y.z.zip
+    unzip testng-x.y.z.zip
+    cp testng-x.y.z/testng-x.y.z.jar test/lib/testng.jar
+    
+After that, you can run the tests using:
+    cd make
+    ant test
+    
+You can also run the ECMA-262 test suite with Nashorn. In order to do
+that, you will need to get a copy of it and put it in
+test/script/external/test262 directory. A convenient way to do it is:
+
+   hg clone http://hg.ecmascript.org/tests/test262/ test/script/external/test262
+    
+Alternatively, you can check it out elsewhere and make
+test/script/external/test262 a symbolic link to that directory. After
+you've done this, you can run the ECMA-262 tests using:
+
+    cd nashorn~jdk8/nashorn/make
+    ant test262
+    
+These tests take time, so we have a parallelized runner for them that
+takes advantage of all processor cores on the computer:
+
+    cd nashorn~jdk8/nashorn/make
+    ant test262parallel
+    
+- How to write your own test?
+
+Nashorn uses it's own simple test framework. Any .js file dropped under
+nashorn/test directory is considered as a test. A test file can
+optionally have .js.EXPECTED (foo.js.EXPECTED for foo.js) associated
+with it. The .EXPECTED file, if exists, should contain the output
+expected from compiling and/or running the test file.
+
+The test runner crawls these directories for .js files and looks for
+JTReg-style @foo comments to identify tests.
+
+    * @test - A test is tagged with @test.
+
+    * @test/fail - Tests that are supposed to fail (compiling, see @run/fail
+      for runtime) are tagged with @test/fail.
+
+    * @test/compile-error - Test expects compilation to fail, compares
+      output.
+
+    * @test/warning - Test expects compiler warnings, compares output.
+
+    * @test/nocompare - Test expects to compile [and/or run?]
+      successfully(may be warnings), does not compare output.
+
+    * @subtest - denotes necessary file for a main test file; itself is not
+      a test.
+
+    * @run - A test that should be run is also tagged with @run (otherwise
+      the test runner only compiles the test).
+
+    * @run/fail - A test that should compile but fail with a runtime error.
+
+    * @run/ignore-std-error - script may produce output on stderr, ignore
+      this output.
+
+    * @argument - pass an argument to script.
+
+    * @option \ - pass option to engine, sample.
+
+/**
+ * @option --dump-ir-graph
+ * @test
+ */
diff --git a/nashorn/RELEASE_README b/nashorn/RELEASE_README
new file mode 100644
index 0000000..9984be4
--- /dev/null
+++ b/nashorn/RELEASE_README
@@ -0,0 +1,20 @@
+The Nashorn repo is in the process of being migrated to OpenJDK and as such is
+incomplete in several areas.
+
+- The build system is not fully integrated.  When complete, Nashorn will be
+installed in its proper location in the JRE.
+
+- Once integrated, the correct version of the JDK will be wrapped around 
+Nashorn.  In the meantime, ensure you use JDK8 b68 or later.
+
+- The jjs tool has not been implemented in binary form yet.  Use "sh bin/jjs" 
+(or bin/jjs.bat on windows) in the interm.
+
+- The Dynalink component is not fully integrated into Nashorn as yet, but will
+be when details are finalized.
+
+- And, finally Nashorn is still in development.  To stay up to date, subscribe
+to nashorn-dev@openjdk.java.net at
+
+    http://mail.openjdk.java.net/mailman/listinfo/nashorn-dev.
+
diff --git a/nashorn/THIRD_PARTY_README b/nashorn/THIRD_PARTY_README
new file mode 100644
index 0000000..02202a1
--- /dev/null
+++ b/nashorn/THIRD_PARTY_README
@@ -0,0 +1,123 @@
+DO NOT TRANSLATE OR LOCALIZE.
+-----------------------------
+
+%% This notice is provided with respect to  ECMAScript Language
+Specification ECMA-262 Edition 5.1 which is included with the Nashorn
+technology.
+
+--- begin of LICENSE ---
+Copyright notice
+Copyright © 2011 Ecma International
+Ecma International
+Rue du Rhone 114
+CH-1204 Geneva
+Tel: +41 22 849 6000
+Fax: +41 22 849 6001
+Web: http://www.ecma-international.org
+
+This document and possible translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it or assist
+in its implementation may be prepared, copied, published, and distributed, in
+whole or in part, without restriction of any kind, provided that the above
+copyright notice and this section are included on all such copies and derivative
+works. However, this document itself may not be modified in any way, including
+by removing the copyright notice or references to Ecma International, except as
+needed for the purpose of developing any document or deliverable produced by
+Ecma International (in which case the rules applied to copyrights must be
+followed) or as required to translate it into languages other than English. The
+limited permissions granted above are perpetual and will not be revoked by Ecma
+International or its successors or assigns. This document and the information
+contained herein is provided on an "AS IS" basis and ECMA INTERNATIONAL
+DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
+WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP
+RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+PURPOSE." Software License
+
+All Software contained in this document ("Software)" is protected by copyright
+and is being made available under the "BSD License", included below. This
+Software may be subject to third party rights (rights from parties other than
+Ecma International), including patent rights, and no licenses under such third
+party rights are granted under this license even if the third party concerned is
+a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS
+AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR
+INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO
+IMPLEMENT ECMA INTERNATIONAL STANDARDS*. Redistribution and use in source and
+binary forms, with or without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name of the authors nor Ecma International may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "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 ECMA INTERNATIONAL 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.
+--- end of LICENSE ---
+
+%% This notice is provided with respect to Dynalink library which is included
+with the Nashorn technology.
+
+--- begin of LICENSE ---
+Copyright (c) 2009-2013, Attila Szegedi
+
+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.
+--- end of LICENSE ---
+
+%% This notice is provided with respect to Joni library which is included
+with the Nashorn technology.
+
+--- begin of LICENSE ---
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+--- end of LICENSE ---
diff --git a/nashorn/bin/checkintest.sh b/nashorn/bin/checkintest.sh
new file mode 100644
index 0000000..c4a9e96
--- /dev/null
+++ b/nashorn/bin/checkintest.sh
@@ -0,0 +1,266 @@
+#!/bin/bash
+#
+# 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.
+#
+
+#best pass rate at test 262 known
+TEST262_PASS_AT_LEAST=435
+
+RUN_TEST="true"
+RUN_TEST262="true"
+RUN_NODE="true"
+KEEP_OUTPUT="true"
+CLEAN_AND_BUILD_NASHORN="true"
+
+#the stable node version to sync against
+NODE_LAST_STABLE=v0.6.18
+
+#parse args
+for arg in $*
+do
+    if [ $arg = "--no-test" ]; then
+	RUN_TEST="false"
+	echo "**** WARNING - you have disabled 'ant test', which is a minimum checkin requirement..."
+    elif [ $arg = "--no-262" ]; then
+	RUN_TEST262="false"
+    elif [ $arg = "--no-node" ]; then
+	RUN_NODE="false"
+    elif [ $arg = "--no-build" ]; then
+	CLEAN_AND_BUILD_NASHORN="false"
+    elif [ $arg = "--no-logs" ]; then
+	KEEP_OUTPUT="false"
+    fi
+done
+
+function lastpart() {        
+    arr=$(echo $1 | tr "/" "\n")
+    for x in $arr
+    do
+	_last=$x
+    done
+    echo $_last
+}
+
+function check_installed() {
+    which $1 >/dev/null
+    if [ $? -ne 0 ]; then
+	echo "Error $1 not installed: $?"
+	exit 2
+    fi
+}
+
+check_installed hg
+check_installed git
+check_installed mv
+check_installed git
+
+PWD=$(pwd);
+
+while [ -z $NASHORN_ROOT ]
+do
+    if [ -e $PWD/.hg ]; then
+	NASHORN_ROOT=${PWD}
+	break
+    fi
+    PWD=$(dirname ${PWD})
+done
+
+echo "Nashorn root detected at ${NASHORN_ROOT}"
+
+COMMON_ROOT=$(dirname $NASHORN_ROOT)
+echo "Common root is ${COMMON_ROOT}"
+
+echo "Running checkintest..."
+
+ABSOLUTE_NASHORN_HOME=$COMMON_ROOT/$(lastpart $NASHORN_ROOT)
+
+if [ $CLEAN_AND_BUILD_NASHORN != "false" ]; then
+    echo "Cleaning and building nashorn at $ABSOLUTE_NASHORN_HOME/nashorn..."
+    $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant clean >/dev/null 2>/dev/null)
+    $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant jar >/dev/null 2>/dev/null)
+    echo "Done."
+fi
+
+function failure_check() {
+    while read line
+    do
+	LINE=$(echo $line | grep "Tests run")    
+	if [ "${LINE}" != "" ]; then
+	    RESULT=$(echo $line | grep "Failures: 0" | grep "Errors: 0")
+	    if [ "${RESULT}" == "" ]; then
+		TESTNAME=$2
+		echo "There were errors in ${TESTNAME} : ${LINE}"
+		exit 1
+	    fi
+	fi
+    done < $1
+}
+
+function test() {
+    TEST_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX)
+    echo "Running 'ant test' on nashorn from ${ABSOLUTE_NASHORN_HOME}/nashorn..."
+    $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant test >$TEST_OUTPUT)
+    echo "Done."
+
+    failure_check $TEST_OUTPUT
+
+    echo "**** SUCCESS: 'ant test' successful"
+
+    if [ $KEEP_OUTPUT == "true" ]; then
+	cp $TEST_OUTPUT ./checkintest.test.log
+	rm -fr $TEST_OUTPUT
+    fi
+}
+
+if [ $RUN_TEST != "false" ]; then
+    test;
+fi
+
+function test262() {
+
+    echo "Running 'ant test262parallel' on nashorn from ${ABSOLUTE_NASHORN_HOME}/nashorn..."
+    TEST262_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX)
+
+    echo "Looking for ${ABSOLUTE_NASHORN_HOME}/test/test262..."
+
+    if [ ! -e $ABSOLUTE_NASHORN_HOME/nashorn/test/test262 ]; then
+	echo "test262 is missing... looking in $COMMON_ROOT..."
+	if [ ! -e $COMMON_ROOT/test262 ]; then
+	    echo "... not there either... cloning from repo..."
+	    hg clone http://hg.ecmascript.org/tests/test262 $COMMON_ROOT/test262 >/dev/null 2>/dev/null
+	    echo "Done."
+	fi
+	echo "Adding soft link ${COMMON_ROOT}/test262 -> ${ABSOLUTE_NASHORN_HOME}/test/test262..."
+	ln -s $COMMON_ROOT/test262 $ABSOLUTE_NASHORN_HOME/nashorn/test/test262
+	echo "Done."
+    fi
+
+    echo "Ensuring test262 is up to date..."
+    $(cd $ABSOLUTE_NASHORN_HOME/nashorn/test/test262; hg pull -u >/dev/null 2>/dev/null)
+    echo "Done."
+
+    echo "Running test262..."
+    $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant test262parallel > $TEST262_OUTPUT)
+    
+    FAILED=$(cat $TEST262_OUTPUT|grep "Tests run:"| cut -d ' ' -f 15 |tr -cd '"[[:digit:]]')
+    if [ $FAILED -gt $TEST262_PASS_AT_LEAST ]; then 
+	echo "FAILURE: There are ${FAILED} failures in test262 and can be no more than ${TEST262_PASS_AT_LEAST}"
+	cp $TEST262_OUTPUT ./checkintest.test262.log
+	echo "See ./checkintest.test262.log"
+	echo "Terminating due to error"
+	exit 1
+    elif [ $FAILED -lt $TEST262_PASS_AT_LEAST ]; then
+	echo "There seem to have been fixes to 262. ${FAILED} < ${TEST262_PASS_AT_LEAST}. Please update limit in bin/checkintest.sh"
+    fi
+    
+    echo "**** SUCCESS: Test262 passed with no more than ${TEST262_PASS_AT_LEAST} failures."
+
+    if [ $KEEP_OUTPUT == "true" ]; then
+	cp $TEST262_OUTPUT ./checkintest.test262.log
+	rm -fr $TEST262_OUTPUT
+    fi    
+}
+
+if [ $RUN_TEST262 != "false" ]; then
+    test262;    
+fi;
+
+function testnode() {
+    TESTNODEJAR_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX)
+   
+    echo "Running node tests..."
+#replace node jar properties nashorn with this nashorn
+    
+    NODEJAR_PROPERTIES=~/nodejar.properties
+    
+    NODE_HOME=$(cat $NODEJAR_PROPERTIES | grep ^node.home | cut -f2 -d=)    
+    NASHORN_HOME=$(cat $NODEJAR_PROPERTIES | grep ^nashorn.home | cut -f2 -d=)
+    
+    ABSOLUTE_NODE_HOME=$COMMON_ROOT/$(lastpart $NODE_HOME)    
+    
+    echo "Writing nodejar.properties..."
+
+    cat > $NODEJAR_PROPERTIES << EOF
+node.home=../node
+nashorn.home=../$(lastpart $NASHORN_ROOT)
+EOF
+    echo "Done."
+    echo "Checking node home ${ABSOLUTE_NODE_HOME}..."
+
+    if [ ! -e $ABSOLUTE_NODE_HOME ]; then
+	echo "Node base dir not found. Cloning node..."    
+	$(cd $COMMON_ROOT; git clone https://github.com/joyent/node.git $(lastpart $NODE_HOME) >/dev/null 2>/dev/null)
+	echo "Done."
+	echo "Updating to last stable version ${NODE_LAST_STABLE}..."
+	$(cd $ABSOLUTE_NODE_HOME; git checkout $NODE_LAST_STABLE >/dev/null 2>/dev/null)
+	echo "Done."
+	echo "Running configure..."
+	$(cd $ABSOLUTE_NODE_HOME; ./configure >/dev/null 2>/dev/null)
+	echo "Done."
+    fi
+    
+    echo "Ensuring node is built..."
+#make sure node is built
+    $(cd $ABSOLUTE_NODE_HOME; make >/dev/null 2>/dev/null)
+    echo "Done."
+
+    NODEJAR_HOME=$COMMON_ROOT/nodejar
+
+    if [ ! -e $NODEJAR_HOME ]; then
+	echo "No node jar home found. cloning from depot..."
+	$(cd $COMMON_ROOT; hg clone https://hg.kenai.com/hg/nodejs~source nodejar >/dev/null 2>/dev/null) 
+	$(cd $COMMON_ROOT/nodejar; ant >/dev/null)
+	echo "Done."
+	echo "Copying node files..."
+	$(cd $COMMON_ROOT/nodejar; ant copy-node-files >/dev/null 2>/dev/null)
+	echo "Patching node files..."
+	$(cd $COMMON_ROOT/nodejar; ant patch-node-files >/dev/null 2>/dev/null)
+	echo "Done."
+    fi
+    
+    echo "Ensuring node.jar is up to date from source depot..."
+    $(cd $COMMON_ROOT/nodejar; hg pull -u >/dev/null 2>/dev/null)
+    echo "Done."
+
+    echo "Installing nashorn..."
+    $(cd $COMMON_ROOT/nodejar; ant >/dev/null)
+    echo "Done."
+
+    echo "Running node.jar test..."
+    $(cd $COMMON_ROOT/nodejar; mvn clean verify >$TESTNODEJAR_OUTPUT)
+    echo "Done."
+
+    failure_check $TESTNODEJAR_OUTPUT
+    
+    echo "**** SUCCESS: Node test successful."
+
+    if [ $KEEP_OUTPUT == "true" ]; then
+	rm -fr $TESTNODEJAR_OUTPUT
+	cp $TESTNODEJAR_OUTPUT ./checkintest.nodejar.log
+    fi
+}
+
+if [ $RUN_NODE != "false" ]; then
+    testnode;
+fi;
+
+echo "Finished"
diff --git a/nashorn/bin/dump_octane_code.sh b/nashorn/bin/dump_octane_code.sh
new file mode 100644
index 0000000..d24ab2c
--- /dev/null
+++ b/nashorn/bin/dump_octane_code.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# 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.
+#
+
+#
+# The purpose of this script is to provide a large amount of IR/bytecode from a known
+# application to be diffed against the same output with a different Nashorn version.
+# That way we can quickly detect if a seemingly minute change modifies a lot of code,
+# which it most likely shouldn't. One example of this was when AccessSpecializer was
+# moved into Lower the first time, it worked fine, but as a lot of Scope information
+# at the time was finalized further down the code pipeline it did a lot fewer callsite
+# specializations. This would have been immediately detected with a before and after 
+# diff using the output from this script.
+#
+
+ITERS=$1
+if [ -z $ITERS ]; then 
+    ITERS=7
+fi
+NASHORN_JAR=dist/nashorn.jar
+JVM_FLAGS="-ea -esa -server -jar ${NASHORN_JAR}"
+
+BENCHMARKS=( "box2d.js" "code-load.js" "crypto.js" "deltablue.js" "earley-boyer.js" "gbemu.js" "mandreel.js" "navier-stokes.js" "pdfjs.js" "raytrace.js" "regexp.js" "richards.js" "splay.js" )
+
+for BENCHMARK in "${BENCHMARKS[@]}"
+do     
+    echo "START: ${BENCHMARK}"
+    CMD="${JAVA_HOME}/bin/java ${JVM_FLAGS} -co --print-lower-parse test/script/external/octane/${BENCHMARK}"
+    $CMD
+    echo "END: ${BENCHMARK}"
+    echo ""
+done
+
+echo "Done"
diff --git a/nashorn/bin/fixorphantests.sh b/nashorn/bin/fixorphantests.sh
new file mode 100644
index 0000000..604e2da
--- /dev/null
+++ b/nashorn/bin/fixorphantests.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# 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.
+#
+
+#ensure that all tests tagged with @test are also tagged with @run
+
+for f in $(find test/script/basic/*.js); do 
+    grep @test $f >/dev/null
+    TEST=$?
+    grep @run $f >/dev/null
+    RUN=$?    
+
+    if [ $TEST -eq 0 ] && [ ! $RUN -eq 0 ]; then		
+	echo "repairing ${f}..."
+	TEMP=$(mktemp /tmp/scratch.XXXXXX)
+
+	#IFS='', -raw flag to preserve white space
+	while IFS='' read -r line; do 	    
+	    echo $line | grep @test >/dev/null
+	    TEST=$?
+	    printf "%s\n" "$line" 
+	    if [ $TEST -eq 0 ]; then
+		printf "%s\n" "$line" | sed s/@test/@run/g 
+	    fi	   
+	done < $f >$TEMP
+
+	cp $TEMP $f
+
+	rm -fr $TEMP
+    fi
+
+done
diff --git a/nashorn/bin/fixwhitespace.sh b/nashorn/bin/fixwhitespace.sh
new file mode 100644
index 0000000..cac757d
--- /dev/null
+++ b/nashorn/bin/fixwhitespace.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# 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.
+#
+
+#convert tabs to spaces
+find . -name "*.java" -exec sed -i "" 's/	/    /g' {} \;
+
+#remove trailing whitespace
+find . -name "*.java" -exec sed -i "" 's/[ 	]*$//' \{} \;
+
diff --git a/nashorn/bin/jjs b/nashorn/bin/jjs
new file mode 100644
index 0000000..ca531f4
--- /dev/null
+++ b/nashorn/bin/jjs
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# 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.
+#
+
+[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
+
+$JAVA_HOME/bin/java -server -XX:-TieredCompilation -Xms2G -Xmx2G -esa -ea -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -XX:+HeapDumpOnOutOfMemoryError -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.debug=true jdk.nashorn.tools.Shell $*
diff --git a/nashorn/bin/jjs.bat b/nashorn/bin/jjs.bat
new file mode 100644
index 0000000..3c1c159
--- /dev/null
+++ b/nashorn/bin/jjs.bat
@@ -0,0 +1,27 @@
+rem
+rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+rem
+rem This code is free software; you can redistribute it and/or modify it
+rem under the terms of the GNU General Public License version 2 only, as
+rem published by the Free Software Foundation.  Oracle designates this
+rem particular file as subject to the "Classpath" exception as provided
+rem by Oracle in the LICENSE file that accompanied this code.
+rem
+rem This code is distributed in the hope that it will be useful, but WITHOUT
+rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+rem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+rem version 2 for more details (a copy is included in the LICENSE file that
+rem accompanied this code).
+rem
+rem You should have received a copy of the GNU General Public License version
+rem 2 along with this work; if not, write to the Free Software Foundation,
+rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+rem
+rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+rem or visit www.oracle.com if you need additional information or have any
+rem questions.
+rem
+@echo off
+
+java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.ext.dirs=%~dp0\..\dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false jdk.nashorn.tools.Shell
diff --git a/nashorn/bin/jjssecure b/nashorn/bin/jjssecure
new file mode 100644
index 0000000..614ffd3
--- /dev/null
+++ b/nashorn/bin/jjssecure
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# 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.
+#
+
+[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
+
+$JAVA_HOME/bin/java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.security.properties=`dirname $0`/../make/java.security.override -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=true -Dnashorn.home=`dirname $0`/.. -Djava.security.manager jdk.nashorn.tools.Shell $*
diff --git a/nashorn/bin/jjssecure.bat b/nashorn/bin/jjssecure.bat
new file mode 100644
index 0000000..f8da10a
--- /dev/null
+++ b/nashorn/bin/jjssecure.bat
@@ -0,0 +1,27 @@
+rem
+rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+rem
+rem This code is free software; you can redistribute it and/or modify it
+rem under the terms of the GNU General Public License version 2 only, as
+rem published by the Free Software Foundation.  Oracle designates this
+rem particular file as subject to the "Classpath" exception as provided
+rem by Oracle in the LICENSE file that accompanied this code.
+rem
+rem This code is distributed in the hope that it will be useful, but WITHOUT
+rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+rem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+rem version 2 for more details (a copy is included in the LICENSE file that
+rem accompanied this code).
+rem
+rem You should have received a copy of the GNU General Public License version
+rem 2 along with this work; if not, write to the Free Software Foundation,
+rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+rem
+rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+rem or visit www.oracle.com if you need additional information or have any
+rem questions.
+rem
+@echo off
+
+java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.security.properties=%~dp0\..\make\java.security.override -Djava.ext.dirs=%~dp0\..\dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.home=%~dp0\.. -Djava.security.manager jdk.nashorn.tools.Shell
diff --git a/nashorn/bin/nashorn b/nashorn/bin/nashorn
new file mode 100644
index 0000000..3fccdd0
--- /dev/null
+++ b/nashorn/bin/nashorn
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# 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.
+#
+
+[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
+
+$JAVA_HOME/bin/jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $*
diff --git a/nashorn/bin/nashorn.bat b/nashorn/bin/nashorn.bat
new file mode 100644
index 0000000..2961ac6
--- /dev/null
+++ b/nashorn/bin/nashorn.bat
@@ -0,0 +1,27 @@
+rem
+rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+rem
+rem This code is free software; you can redistribute it and/or modify it
+rem under the terms of the GNU General Public License version 2 only, as
+rem published by the Free Software Foundation.  Oracle designates this
+rem particular file as subject to the "Classpath" exception as provided
+rem by Oracle in the LICENSE file that accompanied this code.
+rem
+rem This code is distributed in the hope that it will be useful, but WITHOUT
+rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+rem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+rem version 2 for more details (a copy is included in the LICENSE file that
+rem accompanied this code).
+rem
+rem You should have received a copy of the GNU General Public License version
+rem 2 along with this work; if not, write to the Free Software Foundation,
+rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+rem
+rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+rem or visit www.oracle.com if you need additional information or have any
+rem questions.
+rem
+@echo off
+
+jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=%~dp0\..\dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Dnashorn.debug=true -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -l nashorn
diff --git a/nashorn/bin/nashornsecure b/nashorn/bin/nashornsecure
new file mode 100644
index 0000000..3d02c52
--- /dev/null
+++ b/nashorn/bin/nashornsecure
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# 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.
+#
+
+[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
+
+$JAVA_HOME/bin/jrunscript -J-Djava.security.properties=`dirname $0`/../make/java.security.override -J-Djava.security.manager -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $*
diff --git a/nashorn/bin/nashornsecure.bat b/nashorn/bin/nashornsecure.bat
new file mode 100644
index 0000000..5a4eca6
--- /dev/null
+++ b/nashorn/bin/nashornsecure.bat
@@ -0,0 +1,27 @@
+rem
+rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+rem
+rem This code is free software; you can redistribute it and/or modify it
+rem under the terms of the GNU General Public License version 2 only, as
+rem published by the Free Software Foundation.  Oracle designates this
+rem particular file as subject to the "Classpath" exception as provided
+rem by Oracle in the LICENSE file that accompanied this code.
+rem
+rem This code is distributed in the hope that it will be useful, but WITHOUT
+rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+rem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+rem version 2 for more details (a copy is included in the LICENSE file that
+rem accompanied this code).
+rem
+rem You should have received a copy of the GNU General Public License version
+rem 2 along with this work; if not, write to the Free Software Foundation,
+rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+rem
+rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+rem or visit www.oracle.com if you need additional information or have any
+rem questions.
+rem
+@echo off
+
+jrunscript -J-Djava.security.properties=%~dp0\..\make\java.security.override -J-Djava.security.manager -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=%~dp0\..\dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Dnashorn.debug=true -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -l nashorn
diff --git a/nashorn/bin/rm-non-tracked.sh b/nashorn/bin/rm-non-tracked.sh
new file mode 100644
index 0000000..1eac199
--- /dev/null
+++ b/nashorn/bin/rm-non-tracked.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+#
+# 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.
+#
+hg status|grep ^\?|awk '{print $2}'|xargs rm
diff --git a/nashorn/bin/verbose_octane.bat b/nashorn/bin/verbose_octane.bat
new file mode 100644
index 0000000..ab9e484
--- /dev/null
+++ b/nashorn/bin/verbose_octane.bat
@@ -0,0 +1,59 @@
+rem
+rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+rem 
+rem This code is free software; you can redistribute it and/or modify it
+rem under the terms of the GNU General Public License version 2 only, as
+rem published by the Free Software Foundation.
+rem 
+rem This code is distributed in the hope that it will be useful, but WITHOUT
+rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+rem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+rem version 2 for more details (a copy is included in the LICENSE file that
+rem accompanied this code).
+rem 
+rem You should have received a copy of the GNU General Public License version
+rem 2 along with this work; if not, write to the Free Software Foundation,
+rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+rem 
+rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+rem or visit www.oracle.com if you need additional information or have any
+rem questions.
+rem
+@echo off
+
+if "%JAVA_HOME%" neq "" (
+  call :run "%JAVA_HOME%/bin/java"
+) else (
+  call :run java
+)
+goto :EOF
+
+:run
+setlocal
+set NASHORN_JAR=dist/nashorn.jar
+set JVM_FLAGS=-Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -jar %NASHORN_JAR%
+set JVM_FLAGS7=-Xbootclasspath/p:%NASHORN_JAR% %JVM_FLAGS%
+set OCTANE_ARGS=--verbose --iterations 7
+
+%1 -fullversion 2>&1 | findstr /L /C:"version ""1.7"
+if %errorlevel% equ 0 (
+  set CMD=%1 %JVM_FLAGS7%
+) else (
+  %1 -fullversion
+  set CMD=%1 %JVM_FLAGS%
+)
+
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/box2d.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/code-load.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/crypto.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/deltablue.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/gbemu.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/navier-stokes.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/pdfjs.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/raytrace.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/regexp.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/richards.js %OCTANE_ARGS%
+%CMD% test/script/basic/run-octane.js -- test/script/external/octane/splay.js %OCTANE_ARGS%
+endlocal
+goto :EOF
diff --git a/nashorn/bin/verbose_octane.sh b/nashorn/bin/verbose_octane.sh
new file mode 100644
index 0000000..e70e9d4
--- /dev/null
+++ b/nashorn/bin/verbose_octane.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+# 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.
+#
+
+ITERS=$1
+if [ -z $ITERS ]; then 
+    ITERS=7
+fi
+NASHORN_JAR=dist/nashorn.jar
+JVM_FLAGS="-XX:+UnlockDiagnosticVMOptions -Dnashorn.unstable.relink.threshold=8 -Xms2G -Xmx2G -XX:+TieredCompilation -server -jar ${NASHORN_JAR}"
+JVM_FLAGS7="-Xbootclasspath/p:${NASHORN_JAR} ${JVM_FLAGS}"
+OCTANE_ARGS="--verbose --iterations ${ITERS}"
+
+BENCHMARKS=( "box2d.js" "code-load.js" "crypto.js" "deltablue.js" "earley-boyer.js" "gbemu.js" "navier-stokes.js" "pdfjs.js" "raytrace.js" "regexp.js" "richards.js" "splay.js" )
+# TODO mandreel.js has metaspace issues
+
+if [ ! -z $JAVA7_HOME ]; then	
+    echo "running ${ITERS} iterations with java7 using JAVA_HOME=${JAVA7_HOME}..."
+    for BENCHMARK in "${BENCHMARKS[@]}"
+    do 
+	CMD="${JAVA7_HOME}/bin/java ${JVM_FLAGS} test/script/basic/run-octane.js -- test/script/external/octane/${BENCHMARK} ${OCTANE_ARGS}"
+	$CMD
+    done
+else
+    echo "no JAVA7_HOME set. skipping java7"
+fi
+
+if [ ! -z $JAVA8_HOME ]; then
+    echo "running ${ITERS} iterations with java8 using JAVA_HOME=${JAVA8_HOME}..."   
+    for BENCHMARK in "${BENCHMARKS[@]}"
+    do 
+	CMD="${JAVA8_HOME}/bin/java ${JVM_FLAGS} test/script/basic/run-octane.js -- test/script/external/octane/${BENCHMARK} ${OCTANE_ARGS}"
+	$CMD
+    done
+else 
+    echo "no JAVA8_HOME set."
+fi
+
+echo "Done"
diff --git a/nashorn/buildtools/nasgen/README b/nashorn/buildtools/nasgen/README
new file mode 100644
index 0000000..d450945
--- /dev/null
+++ b/nashorn/buildtools/nasgen/README
@@ -0,0 +1,34 @@
+Nasgen is a tool for processing Java classes that implement native
+JavaScript objects. It does so by looking for the
+com.oracle.nashorn.objects.annotations.ScriptClass annotation and other
+annotations in that package.
+
+For each  class "C", nasgen instruments the original class and generates
+two additional classes: a "C$Prototype" class for the JavaScript
+prototype object, and a "C$Constructor" class for the JavaScript
+constructor function.
+
+Each class instrumented or generated by nasgen contains a private static
+"$nasgenmap$" field of type com.oracle.nashorn.runtime.PropertyMap and
+static initializer block to initialize the field to the object's
+JavaScript properties.
+
+Members annotated with @Function, @Property, @Getter, and @Setter are
+mapped to the $Constructor, $Prototype, or main class, depending on the
+value of the annotation's 'where' field. By default, @Property, @Getter,
+and @Setter belong to the main class while @Function methods without
+explicit 'where' field belong to the $Prototype class. The @Constructor
+annotation marks a method to be invoked as JavaScript constructor.
+
+Nasgen enforces all @Function/@Getter/@Setter/@Constructor annotated
+methods to be declared as static. Static final @Property fields remain
+in the main class while other @Property fields are moved to respective
+classes depending on the annotation's 'where' value. For functions
+mapped to the $Prototype or $Constructor class, nasgen also generates
+getters and setters prefixed by G$ and S$, respectively.
+
+Nasgen-generated classes are hidden from normal ClassLoaders by giving
+them a ".clazz" file name extension instead of the standard ".class"
+extension. This allows script classes to be loaded independently by each
+Nashorn context through the com.oracle.nashorn.runtime.StructureLoader
+class loader.
diff --git a/nashorn/buildtools/nasgen/build.xml b/nashorn/buildtools/nasgen/build.xml
new file mode 100644
index 0000000..bf56c11
--- /dev/null
+++ b/nashorn/buildtools/nasgen/build.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project name="nasgen" default="all" basedir=".">
+  <target name="init">
+    <loadproperties srcFile="project.properties"/>
+  </target>
+
+  <target name="prepare" depends="init">
+    <mkdir dir="${build.classes.dir}"/>
+    <mkdir dir="${dist.dir}"/>
+    <mkdir dir="${dist.dir}/lib"/>
+  </target>
+
+  <target name="clean" depends="init">
+    <delete dir="${build.dir}"/>
+    <delete dir="${dist.dir}"/>
+  </target>
+
+  <target name="compile" depends="prepare" description="Compiles the nasgen sources">
+    <javac srcdir="${src.dir}"
+           destdir="${build.classes.dir}"
+           classpath="${javac.classpath}"
+           debug="${javac.debug}"
+           includeantruntime="false">
+      <compilerarg value="-Xlint:unchecked"/>
+      <compilerarg value="-Xlint:deprecation"/>
+      <compilerarg value="-XDignore.symbol.file"/>
+    </javac>
+  </target>
+
+  <target name="jar" depends="compile" description="Creates nasgen.jar">
+    <jar jarfile="${dist.jar}" basedir="${build.classes.dir}" manifest="${meta.inf.dir}/MANIFEST.MF"/>
+  </target>
+
+  <target name="dist" depends="jar"/>
+
+  <target name="all" depends="dist" 
+    description="Builds sources and generates nasgen.jar"/>
+</project>
diff --git a/nashorn/buildtools/nasgen/nasgen.iml b/nashorn/buildtools/nasgen/nasgen.iml
new file mode 100644
index 0000000..f6c890a
--- /dev/null
+++ b/nashorn/buildtools/nasgen/nasgen.iml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/classes" />
+    <output-test url="file://$MODULE_DIR$/build/test/classes" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/build" />
+      <excludeFolder url="file://$MODULE_DIR$/dist" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="asm" />
+  </component>
+</module>
+
diff --git a/nashorn/buildtools/nasgen/project.properties b/nashorn/buildtools/nasgen/project.properties
new file mode 100644
index 0000000..5963f68
--- /dev/null
+++ b/nashorn/buildtools/nasgen/project.properties
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+application.title=nasgen
+
+# source and target levels
+build.compiler=modern
+javac.source=1.7
+javac.target=1.7
+
+build.classes.dir=${build.dir}/classes
+
+# This directory is removed when the project is cleaned:
+build.dir=build
+
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/nasgen.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+
+nashorn.dir=../../
+
+javac.debug=true
+
+javac.classpath=\
+    ${nashorn.dir}/build/classes
+
+meta.inf.dir=${src.dir}/META-INF
+run.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+run.jvmargs=
+src.dir=src
diff --git a/nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF b/nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..b709863
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0

+Class-Path: lib/ant-1.7.1.jar

+Main-Class: jdk.nashorn.internal.tools.nasgen.Main

+

diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
new file mode 100644
index 0000000..808f265
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
@@ -0,0 +1,334 @@
+/*
+ * 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.tools.nasgen;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.GETTER_PREFIX;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SETTER_PREFIX;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_OBJECT;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+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.FieldVisitor;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Type;
+import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
+
+/**
+ * Base class for class generator classes.
+ *
+ */
+public class ClassGenerator {
+    /** ASM class writer used to output bytecode for this class */
+    protected final ClassWriter cw;
+
+    /**
+     * Constructor
+     */
+    protected ClassGenerator() {
+        this.cw = makeClassWriter();
+    }
+
+    MethodGenerator makeStaticInitializer() {
+        return makeStaticInitializer(cw);
+    }
+
+    MethodGenerator makeConstructor() {
+        return makeConstructor(cw);
+    }
+
+    MethodGenerator makeMethod(final int access, final String name, final String desc) {
+        return makeMethod(cw, access, name, desc);
+    }
+
+    void addMapField() {
+        addMapField(cw);
+    }
+
+    void addField(final String name, final String desc) {
+        addField(cw, name, desc);
+    }
+
+    void addFunctionField(final String name) {
+        addFunctionField(cw, name);
+    }
+
+    void addGetter(final String owner, final MemberInfo memInfo) {
+        addGetter(cw, owner, memInfo);
+    }
+
+    void addSetter(final String owner, final MemberInfo memInfo) {
+        addSetter(cw, owner, memInfo);
+    }
+
+    void emitGetClassName(final String name) {
+        final MethodGenerator mi = makeMethod(ACC_PUBLIC, GET_CLASS_NAME, GET_CLASS_NAME_DESC);
+        mi.loadLiteral(name);
+        mi.returnValue();
+        mi.computeMaxs();
+        mi.visitEnd();
+    }
+
+    static ClassWriter makeClassWriter() {
+        return new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
+            @Override
+            protected String getCommonSuperClass(final String type1, final String type2) {
+                try {
+                    return super.getCommonSuperClass(type1, type2);
+                } catch (final RuntimeException | LinkageError e) {
+                    return StringConstants.OBJECT_TYPE;
+                }
+            }
+        };
+    }
+
+    static MethodGenerator makeStaticInitializer(final ClassVisitor cv) {
+        return makeStaticInitializer(cv, CLINIT);
+    }
+
+    static MethodGenerator makeStaticInitializer(final ClassVisitor cv, final String name) {
+        final int access = ACC_PUBLIC | ACC_STATIC;
+        final String desc = DEFAULT_INIT_DESC;
+        final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null);
+        return new MethodGenerator(mv, access, name, desc);
+    }
+
+    static MethodGenerator makeConstructor(final ClassVisitor cv) {
+        final int access = ACC_PUBLIC;
+        final String name = INIT;
+        final String desc = DEFAULT_INIT_DESC;
+        final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null);
+        return new MethodGenerator(mv, access, name, desc);
+    }
+
+    static MethodGenerator makeMethod(final ClassVisitor cv, final int access, final String name, final String desc) {
+        final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null);
+        return new MethodGenerator(mv, access, name, desc);
+    }
+
+    static void emitStaticInitPrefix(final MethodGenerator mi, final String className) {
+        mi.visitCode();
+        mi.pushNull();
+        mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC);
+        mi.loadClass(className);
+        mi.invokeStatic(MAP_TYPE, MAP_NEWMAP, MAP_NEWMAP_DESC);
+        mi.storeLocal(0);
+    }
+
+    static void emitStaticInitSuffix(final MethodGenerator mi, final String className) {
+        mi.loadLocal(0);
+        mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC);
+        mi.returnVoid();
+        mi.computeMaxs();
+        mi.visitEnd();
+    }
+
+    @SuppressWarnings("fallthrough")
+    private static Type memInfoType(final MemberInfo memInfo) {
+        switch (memInfo.getJavaDesc().charAt(0)) {
+            case 'I': return Type.INT_TYPE;
+            case 'J': return Type.LONG_TYPE;
+            case 'D': return Type.DOUBLE_TYPE;
+            default:  assert false : memInfo.getJavaDesc();
+            case 'L': return TYPE_OBJECT;
+        }
+    }
+
+    private static String getterDesc(final MemberInfo memInfo) {
+        return Type.getMethodDescriptor(memInfoType(memInfo));
+    }
+
+    private static String setterDesc(final MemberInfo memInfo) {
+        return Type.getMethodDescriptor(Type.VOID_TYPE, memInfoType(memInfo));
+    }
+
+    static void addGetter(final ClassVisitor cv, final String owner, final MemberInfo memInfo) {
+        final int access = ACC_PUBLIC;
+        final String name = GETTER_PREFIX + memInfo.getJavaName();
+        final String desc = getterDesc(memInfo);
+        final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null);
+        final MethodGenerator mi = new MethodGenerator(mv, access, name, desc);
+        mi.visitCode();
+        if (memInfo.isStatic() && memInfo.getKind() == Kind.PROPERTY) {
+            mi.getStatic(owner, memInfo.getJavaName(), memInfo.getJavaDesc());
+        } else {
+            mi.loadLocal(0);
+            mi.getField(owner, memInfo.getJavaName(), memInfo.getJavaDesc());
+        }
+        mi.returnValue();
+        mi.computeMaxs();
+        mi.visitEnd();
+    }
+
+    static void addSetter(final ClassVisitor cv, final String owner, final MemberInfo memInfo) {
+        final int access = ACC_PUBLIC;
+        final String name = SETTER_PREFIX + memInfo.getJavaName();
+        final String desc = setterDesc(memInfo);
+        final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null);
+        final MethodGenerator mi = new MethodGenerator(mv, access, name, desc);
+        mi.visitCode();
+        if (memInfo.isStatic() && memInfo.getKind() == Kind.PROPERTY) {
+            mi.loadLocal(1);
+            mi.putStatic(owner, memInfo.getJavaName(), memInfo.getJavaDesc());
+        } else {
+            mi.loadLocal(0);
+            mi.loadLocal(1);
+            mi.putField(owner, memInfo.getJavaName(), memInfo.getJavaDesc());
+        }
+        mi.returnVoid();
+        mi.computeMaxs();
+        mi.visitEnd();
+    }
+
+    static void addMapField(final ClassVisitor cv) {
+        // add a MAP static field
+        final FieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC,
+            MAP_FIELD_NAME, MAP_DESC, null, null);
+        if (fv != null) {
+            fv.visitEnd();
+        }
+    }
+
+    static void addField(final ClassVisitor cv, final String name, final String desc) {
+        final FieldVisitor fv = cv.visitField(ACC_PRIVATE, name, desc, null, null);
+        if (fv != null) {
+            fv.visitEnd();
+        }
+    }
+
+    static void addFunctionField(final ClassVisitor cv, final String name) {
+        addField(cv, name, OBJECT_DESC);
+    }
+
+    static void newFunction(final MethodGenerator mi, final String className, final MemberInfo memInfo, final List<MemberInfo> specs) {
+        final boolean arityFound = (memInfo.getArity() != MemberInfo.DEFAULT_ARITY);
+
+        mi.loadLiteral(memInfo.getName());
+        mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, memInfo.getJavaName(), memInfo.getJavaDesc()));
+
+        assert specs != null;
+        if (!specs.isEmpty()) {
+            mi.memberInfoArray(className, specs);
+            mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC);
+        } else {
+            mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC);
+        }
+
+        if (arityFound) {
+            mi.dup();
+            mi.push(memInfo.getArity());
+            mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, SCRIPTFUNCTION_SETARITY_DESC);
+        }
+
+    }
+
+    static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
+        final String propertyName = memInfo.getName();
+        mi.loadLocal(0);
+        mi.loadLiteral(propertyName);
+        // setup flags
+        mi.push(memInfo.getAttributes());
+        // setup getter method handle
+        String javaName = GETTER_PREFIX + memInfo.getJavaName();
+        mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, getterDesc(memInfo)));
+        // setup setter method handle
+        if (memInfo.isFinal()) {
+            mi.pushNull();
+        } else {
+            javaName = SETTER_PREFIX + memInfo.getJavaName();
+            mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo)));
+        }
+        mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC);
+        mi.storeLocal(0);
+    }
+
+    static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo getter, final MemberInfo setter) {
+        final String propertyName = getter.getName();
+        mi.loadLocal(0);
+        mi.loadLiteral(propertyName);
+        // setup flags
+        mi.push(getter.getAttributes());
+        // setup getter method handle
+        mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className,
+                getter.getJavaName(), getter.getJavaDesc()));
+        // setup setter method handle
+        if (setter == null) {
+            mi.pushNull();
+        } else {
+            mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className,
+                    setter.getJavaName(), setter.getJavaDesc()));
+        }
+        mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC);
+        mi.storeLocal(0);
+    }
+
+    static ScriptClassInfo getScriptClassInfo(final String fileName) throws IOException {
+        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName))) {
+            return getScriptClassInfo(new ClassReader(bis));
+        }
+    }
+
+    static ScriptClassInfo getScriptClassInfo(final byte[] classBuf) {
+        return getScriptClassInfo(new ClassReader(classBuf));
+    }
+
+    private static ScriptClassInfo getScriptClassInfo(final ClassReader reader) {
+        final ScriptClassInfoCollector scic = new ScriptClassInfoCollector();
+        reader.accept(scic, 0);
+        return scic.getScriptClassInfo();
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java
new file mode 100644
index 0000000..836cb89
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java
@@ -0,0 +1,276 @@
+/*
+ * 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.tools.nasgen;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC3;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC4;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.List;
+import jdk.internal.org.objectweb.asm.Handle;
+
+/**
+ * This class generates constructor class for a @ClassInfo annotated class.
+ *
+ */
+public class ConstructorGenerator extends ClassGenerator {
+    private final ScriptClassInfo scriptClassInfo;
+    private final String className;
+    private final MemberInfo constructor;
+    private final int memberCount;
+    private final List<MemberInfo> specs;
+
+    ConstructorGenerator(final ScriptClassInfo sci) {
+        this.scriptClassInfo = sci;
+
+        this.className = scriptClassInfo.getConstructorClassName();
+        this.constructor = scriptClassInfo.getConstructor();
+        this.memberCount = scriptClassInfo.getConstructorMemberCount();
+        this.specs = scriptClassInfo.getSpecializedConstructors();
+    }
+
+    byte[] getClassBytes() {
+        // new class extensing from ScriptObject
+        final String superClass = (constructor != null)? SCRIPTFUNCTIONIMPL_TYPE : SCRIPTOBJECT_TYPE;
+        cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClass, null);
+        if (memberCount > 0) {
+            // add fields
+            emitFields();
+            // add <clinit>
+            emitStaticInitializer();
+        }
+        // add <init>
+        emitConstructor();
+
+        if (constructor == null) {
+            emitGetClassName(scriptClassInfo.getName());
+        }
+
+        cw.visitEnd();
+        return cw.toByteArray();
+    }
+
+    // --Internals only below this point
+    private void emitFields() {
+        // Introduce "Function" type instance fields for each
+        // constructor @Function in script class and introduce instance
+        // fields for each constructor @Property in the script class.
+        for (MemberInfo memInfo : scriptClassInfo.getMembers()) {
+            if (memInfo.isConstructorFunction()) {
+                addFunctionField(memInfo.getJavaName());
+                memInfo = (MemberInfo)memInfo.clone();
+                memInfo.setJavaDesc(OBJECT_DESC);
+                memInfo.setJavaAccess(ACC_PUBLIC);
+                addGetter(className, memInfo);
+                addSetter(className, memInfo);
+            } else if (memInfo.isConstructorProperty()) {
+                if (memInfo.isStaticFinal()) {
+                    addGetter(scriptClassInfo.getJavaName(), memInfo);
+                } else {
+                    addField(memInfo.getJavaName(), memInfo.getJavaDesc());
+                    memInfo = (MemberInfo)memInfo.clone();
+                    memInfo.setJavaAccess(ACC_PUBLIC);
+                    addGetter(className, memInfo);
+                    addSetter(className, memInfo);
+                }
+            }
+        }
+
+        addMapField();
+    }
+
+    private void emitStaticInitializer() {
+        final MethodGenerator mi = makeStaticInitializer();
+        emitStaticInitPrefix(mi, className);
+
+        for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
+            if (memInfo.isConstructorFunction() || memInfo.isConstructorProperty()) {
+                linkerAddGetterSetter(mi, className, memInfo);
+            } else if (memInfo.isConstructorGetter()) {
+                final MemberInfo setter = scriptClassInfo.findSetter(memInfo);
+                linkerAddGetterSetter(mi, scriptClassInfo.getJavaName(), memInfo, setter);
+            }
+        }
+        emitStaticInitSuffix(mi, className);
+    }
+
+    private void emitConstructor() {
+        final MethodGenerator mi = makeConstructor();
+        mi.visitCode();
+        callSuper(mi);
+
+        if (memberCount > 0) {
+            // initialize Function type fields
+            initFunctionFields(mi);
+            // initialize data fields
+            initDataFields(mi);
+        }
+
+        if (constructor != null) {
+            final int arity = constructor.getArity();
+            if (arity != MemberInfo.DEFAULT_ARITY) {
+                mi.loadThis();
+                mi.push(arity);
+                mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY,
+                        SCRIPTFUNCTION_SETARITY_DESC);
+            }
+        }
+        mi.returnVoid();
+        mi.computeMaxs();
+        mi.visitEnd();
+    }
+
+    private void loadMap(final MethodGenerator mi) {
+        if (memberCount > 0) {
+            mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC);
+            // make sure we use duplicated PropertyMap so that original map
+            // stays intact and so can be used for many globals in same context
+            mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC);
+        }
+    }
+
+    private void callSuper(final MethodGenerator mi) {
+        String superClass, superDesc;
+        mi.loadThis();
+        if (constructor == null) {
+            // call ScriptObject.<init>
+            superClass = SCRIPTOBJECT_TYPE;
+            superDesc = (memberCount > 0) ? SCRIPTOBJECT_INIT_DESC : DEFAULT_INIT_DESC;
+            loadMap(mi);
+        } else {
+            // call Function.<init>
+            superClass = SCRIPTFUNCTIONIMPL_TYPE;
+            superDesc = (memberCount > 0) ? SCRIPTFUNCTIONIMPL_INIT_DESC4 : SCRIPTFUNCTIONIMPL_INIT_DESC3;
+            mi.loadLiteral(constructor.getName());
+            mi.visitLdcInsn(new Handle(H_INVOKESTATIC, scriptClassInfo.getJavaName(), constructor.getJavaName(), constructor.getJavaDesc()));
+            loadMap(mi);
+            mi.memberInfoArray(scriptClassInfo.getJavaName(), specs); //pushes null if specs empty
+        }
+
+        mi.invokeSpecial(superClass, INIT, superDesc);
+    }
+
+    private void initFunctionFields(final MethodGenerator mi) {
+        for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
+            if (!memInfo.isConstructorFunction()) {
+                continue;
+            }
+            mi.loadThis();
+            newFunction(mi, scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName()));
+            mi.putField(className, memInfo.getJavaName(), OBJECT_DESC);
+        }
+    }
+
+    private void initDataFields(final MethodGenerator mi) {
+         for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
+            if (!memInfo.isConstructorProperty() || memInfo.isFinal()) {
+                continue;
+            }
+            final Object value = memInfo.getValue();
+            if (value != null) {
+                mi.loadThis();
+                mi.loadLiteral(value);
+                mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
+            } else if (!memInfo.getInitClass().isEmpty()) {
+                final String clazz = memInfo.getInitClass();
+                mi.loadThis();
+                mi.newObject(clazz);
+                mi.dup();
+                mi.invokeSpecial(clazz, INIT, DEFAULT_INIT_DESC);
+                mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
+            }
+        }
+
+        if (constructor != null) {
+            mi.loadThis();
+            final String protoName = scriptClassInfo.getPrototypeClassName();
+            mi.newObject(protoName);
+            mi.dup();
+            mi.invokeSpecial(protoName, INIT, DEFAULT_INIT_DESC);
+            mi.dup();
+            mi.loadThis();
+            mi.invokeStatic(PROTOTYPEOBJECT_TYPE, PROTOTYPEOBJECT_SETCONSTRUCTOR,
+                    PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC);
+            mi.putField(SCRIPTFUNCTION_TYPE, PROTOTYPE, OBJECT_DESC);
+        }
+    }
+
+    /**
+     * Entry point for ConstructorGenerator run separately as an application. Will display
+     * usage. Takes one argument, a class name.
+     * @param args args vector
+     * @throws IOException if class can't be read
+     */
+    public static void main(final String[] args) throws IOException {
+        if (args.length != 1) {
+            System.err.println("Usage: " + ConstructorGenerator.class.getName() + " <class>");
+            System.exit(1);
+        }
+
+        final String className = args[0].replace('.', '/');
+        final ScriptClassInfo sci = getScriptClassInfo(className + ".class");
+        if (sci == null) {
+            System.err.println("No @ScriptClass in " + className);
+            System.exit(2);
+            throw new IOException(); // get rid of warning for sci.verify() below - may be null
+        }
+
+        try {
+            sci.verify();
+        } catch (final Exception e) {
+            System.err.println(e.getMessage());
+            System.exit(3);
+        }
+        final ConstructorGenerator gen = new ConstructorGenerator(sci);
+        try (FileOutputStream fos = new FileOutputStream(className + CONSTRUCTOR_SUFFIX + ".class")) {
+            fos.write(gen.getClassBytes());
+        }
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java
new file mode 100644
index 0000000..7c8439b
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java
@@ -0,0 +1,181 @@
+/*
+ * 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.tools.nasgen;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
+
+/**
+ * Main class for the "nasgen" tool.
+ *
+ */
+public class Main {
+    private static final boolean DEBUG = Boolean.getBoolean("nasgen.debug");
+
+    private interface ErrorReporter {
+        public void error(String msg);
+    }
+
+    /**
+     * Public entry point for Nasgen if invoked from command line. Nasgen takes three arguments
+     * in order: input directory, package list, output directory
+     *
+     * @param args argument vector
+     */
+    public static void main(final String[] args) {
+        final ErrorReporter reporter = new ErrorReporter() {
+            @Override
+            public void error(final String msg) {
+                Main.error(msg, 1);
+            }
+        };
+        if (args.length == 3) {
+            processAll(args[0], args[1], args[2], reporter);
+        } else {
+            error("Usage: nasgen <input-dir> <package-list> <output-dir>", 1);
+        }
+    }
+
+    private static void processAll(final String in, final String pkgList, final String out, final ErrorReporter reporter) {
+        final File inDir = new File(in);
+        if (!inDir.exists() || !inDir.isDirectory()) {
+            reporter.error(in + " does not exist or not a directory");
+            return;
+        }
+
+        final File outDir = new File(out);
+        if (!outDir.exists() || !outDir.isDirectory()) {
+            reporter.error(out + " does not exist or not a directory");
+            return;
+        }
+
+        final String[] packages = pkgList.split(":");
+        for (String pkg : packages) {
+            pkg = pkg.replace('.', File.separatorChar);
+            final File dir = new File(inDir, pkg);
+            final File[] classes = dir.listFiles();
+            for (final File clazz : classes) {
+                if (clazz.isFile() && clazz.getName().endsWith(".class")) {
+                    if (! process(clazz, new File(outDir, pkg), reporter)) {
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    private static boolean process(final File inFile, final File outDir, final ErrorReporter reporter) {
+        try {
+            byte[] buf = new byte[(int)inFile.length()];
+
+            try (FileInputStream fin = new FileInputStream(inFile)) {
+                fin.read(buf);
+            }
+
+            final ScriptClassInfo sci = ClassGenerator.getScriptClassInfo(buf);
+
+            if (sci != null) {
+                try {
+                    sci.verify();
+                } catch (final Exception e) {
+                    reporter.error(e.getMessage());
+                    return false;
+                }
+
+                // create necessary output package dir
+                outDir.mkdirs();
+
+                // instrument @ScriptClass
+                final ClassWriter writer = ClassGenerator.makeClassWriter();
+                final ClassReader reader = new ClassReader(buf);
+                final ScriptClassInstrumentor inst = new ScriptClassInstrumentor(writer, sci);
+                reader.accept(inst, 0);
+                //noinspection UnusedAssignment
+
+                // write instrumented class
+                try (FileOutputStream fos = new FileOutputStream(new File(outDir, inFile.getName()))) {
+                    buf = writer.toByteArray();
+                    if (DEBUG) {
+                        verify(buf);
+                    }
+                    fos.write(buf);
+                }
+
+                // simple class name without package prefix
+                String simpleName = inFile.getName();
+                simpleName = simpleName.substring(0, simpleName.indexOf(".class"));
+
+                if (sci.getPrototypeMemberCount() > 0) {
+                    // generate prototype class
+                    final PrototypeGenerator protGen = new PrototypeGenerator(sci);
+                    buf = protGen.getClassBytes();
+                    if (DEBUG) {
+                        verify(buf);
+                    }
+                    try (FileOutputStream fos = new FileOutputStream(new File(outDir, simpleName + StringConstants.PROTOTYPE_SUFFIX + ".class"))) {
+                        fos.write(buf);
+                    }
+                }
+
+                if (sci.getConstructorMemberCount() > 0 || sci.getConstructor() != null) {
+                    // generate constructor class
+                    final ConstructorGenerator consGen = new ConstructorGenerator(sci);
+                    buf = consGen.getClassBytes();
+                    if (DEBUG) {
+                        verify(buf);
+                    }
+                    try (FileOutputStream fos = new FileOutputStream(new File(outDir, simpleName + StringConstants.CONSTRUCTOR_SUFFIX + ".class"))) {
+                        fos.write(buf);
+                    }
+                }
+            }
+            return true;
+        } catch (final IOException | RuntimeException e) {
+            if (DEBUG) {
+                e.printStackTrace(System.err);
+            }
+            reporter.error(e.getMessage());
+
+            return false;
+        }
+    }
+
+    private static void verify(final byte[] buf) {
+        final ClassReader cr = new ClassReader(buf);
+        CheckClassAdapter.verify(cr, false, new PrintWriter(System.err));
+    }
+
+    private static void error(final String msg, final int exitCode) {
+        System.err.println(msg);
+        System.exit(exitCode);
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java
new file mode 100644
index 0000000..3fdd7c6
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java
@@ -0,0 +1,377 @@
+/*
+ * 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.tools.nasgen;
+
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_ARRAY_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.Type;
+import jdk.nashorn.internal.objects.annotations.Where;
+
+/**
+ * Details about a Java method or field annotated with any of the field/method
+ * annotations from the jdk.nashorn.internal.objects.annotations package.
+ */
+public final class MemberInfo implements Cloneable {
+    /**
+     * The different kinds of available class annotations
+     */
+    public static enum Kind {
+        /** This is a script class */
+        SCRIPT_CLASS,
+        /** This is a constructor */
+        CONSTRUCTOR,
+        /** This is a function */
+        FUNCTION,
+        /** This is a getter */
+        GETTER,
+        /** This is a setter */
+        SETTER,
+        /** This is a property */
+        PROPERTY,
+        /** This is a specialized version of a function */
+        SPECIALIZED_FUNCTION,
+        /** This is a specialized version of a constructor */
+        SPECIALIZED_CONSTRUCTOR
+    }
+
+    // keep in sync with jdk.nashorn.internal.objects.annotations.Attribute
+    static final int DEFAULT_ATTRIBUTES = 0x0;
+
+    static final int DEFAULT_ARITY = -2;
+
+    // the kind of the script annotation - one of the above constants
+    private MemberInfo.Kind kind;
+    // script property name
+    private String name;
+    // script property attributes
+    private int attributes;
+    // name of the java member
+    private String javaName;
+    // type descriptor of the java member
+    private String javaDesc;
+    // access bits of the Java field or method
+    private int javaAccess;
+    // initial value for static @Property fields
+    private Object value;
+    // class whose object is created to fill property value
+    private String initClass;
+    // arity of the Function or Constructor
+    private int arity;
+
+    private Where where;
+
+    /**
+     * @return the kind
+     */
+    public Kind getKind() {
+        return kind;
+    }
+
+    /**
+     * @param kind the kind to set
+     */
+    public void setKind(final Kind kind) {
+        this.kind = kind;
+    }
+
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the attributes
+     */
+    public int getAttributes() {
+        return attributes;
+    }
+
+    /**
+     * @param attributes the attributes to set
+     */
+    public void setAttributes(final int attributes) {
+        this.attributes = attributes;
+    }
+
+    /**
+     * @return the javaName
+     */
+    public String getJavaName() {
+        return javaName;
+    }
+
+    /**
+     * @param javaName the javaName to set
+     */
+    public void setJavaName(final String javaName) {
+        this.javaName = javaName;
+    }
+
+    /**
+     * @return the javaDesc
+     */
+    public String getJavaDesc() {
+        return javaDesc;
+    }
+
+    void setJavaDesc(final String javaDesc) {
+        this.javaDesc = javaDesc;
+    }
+
+    int getJavaAccess() {
+        return javaAccess;
+    }
+
+    void setJavaAccess(final int access) {
+        this.javaAccess = access;
+    }
+
+    Object getValue() {
+        return value;
+    }
+
+    void setValue(final Object value) {
+        this.value = value;
+    }
+
+    Where getWhere() {
+        return where;
+    }
+
+    void setWhere(final Where where) {
+        this.where = where;
+    }
+
+    boolean isFinal() {
+        return (javaAccess & Opcodes.ACC_FINAL) != 0;
+    }
+
+    boolean isStatic() {
+        return (javaAccess & Opcodes.ACC_STATIC) != 0;
+    }
+
+    boolean isStaticFinal() {
+        return isStatic() && isFinal();
+    }
+
+    boolean isInstanceGetter() {
+        return kind == Kind.GETTER && where == Where.INSTANCE;
+    }
+
+    /**
+     * Check whether this MemberInfo is a getter that resides in the instance
+     * @return true if instance setter
+     */
+    boolean isInstanceSetter() {
+        return kind == Kind.SETTER && where == Where.INSTANCE;
+    }
+
+    boolean isInstanceProperty() {
+        return kind == Kind.PROPERTY && where == Where.INSTANCE;
+    }
+
+    boolean isInstanceFunction() {
+        return kind == Kind.FUNCTION && where == Where.INSTANCE;
+    }
+
+    boolean isPrototypeGetter() {
+        return kind == Kind.GETTER && where == Where.PROTOTYPE;
+    }
+
+    boolean isPrototypeSetter() {
+        return kind == Kind.SETTER && where == Where.PROTOTYPE;
+    }
+
+    boolean isPrototypeProperty() {
+        return kind == Kind.PROPERTY && where == Where.PROTOTYPE;
+    }
+
+    boolean isPrototypeFunction() {
+        return kind == Kind.FUNCTION && where == Where.PROTOTYPE;
+    }
+
+    boolean isConstructorGetter() {
+        return kind == Kind.GETTER && where == Where.CONSTRUCTOR;
+    }
+
+    boolean isConstructorSetter() {
+        return kind == Kind.SETTER && where == Where.CONSTRUCTOR;
+    }
+
+    boolean isConstructorProperty() {
+        return kind == Kind.PROPERTY && where == Where.CONSTRUCTOR;
+    }
+
+    boolean isConstructorFunction() {
+        return kind == Kind.FUNCTION && where == Where.CONSTRUCTOR;
+    }
+
+    boolean isConstructor() {
+        return kind == Kind.CONSTRUCTOR;
+    }
+
+    void verify() {
+        if (kind == Kind.CONSTRUCTOR) {
+            final Type returnType = Type.getReturnType(javaDesc);
+            if (! returnType.toString().equals(OBJECT_DESC)) {
+                error("return value should be of Object type, found" + returnType);
+            }
+            final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+            if (argTypes.length < 2) {
+                error("constructor methods should have at least 2 args");
+            }
+            if (! argTypes[0].equals(Type.BOOLEAN_TYPE)) {
+                error("first argument should be of boolean type, found" + argTypes[0]);
+            }
+            if (! argTypes[1].toString().equals(OBJECT_DESC)) {
+                error("second argument should be of Object type, found" + argTypes[0]);
+            }
+
+            if (argTypes.length > 2) {
+                for (int i = 2; i < argTypes.length - 1; i++) {
+                    if (! argTypes[i].toString().equals(OBJECT_DESC)) {
+                        error(i + "'th argument should be of Object type, found " + argTypes[i]);
+                    }
+                }
+
+                final String lastArgType = argTypes[argTypes.length - 1].toString();
+                final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC);
+                if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) {
+                    error("last argument is neither Object nor Object[] type: " + lastArgType);
+                }
+
+                if (isVarArg && argTypes.length > 3) {
+                    error("vararg constructor has more than 3 arguments");
+                }
+            }
+        } else if (kind == Kind.FUNCTION) {
+            final Type returnType = Type.getReturnType(javaDesc);
+            if (! returnType.toString().equals(OBJECT_DESC)) {
+                error("return value should be of Object type, found" + returnType);
+            }
+            final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+            if (argTypes.length < 1) {
+                error("function methods should have at least 1 arg");
+            }
+            if (! argTypes[0].toString().equals(OBJECT_DESC)) {
+                error("first argument should be of Object type, found" + argTypes[0]);
+            }
+
+            if (argTypes.length > 1) {
+                for (int i = 1; i < argTypes.length - 1; i++) {
+                    if (! argTypes[i].toString().equals(OBJECT_DESC)) {
+                        error(i + "'th argument should be of Object type, found " + argTypes[i]);
+                    }
+                }
+
+                final String lastArgType = argTypes[argTypes.length - 1].toString();
+                final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC);
+                if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) {
+                    error("last argument is neither Object nor Object[] type: " + lastArgType);
+                }
+
+                if (isVarArg && argTypes.length > 2) {
+                    error("vararg function has more than 2 arguments");
+                }
+            }
+        } else if (kind == Kind.GETTER) {
+            final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+            if (argTypes.length != 1) {
+                error("getter methods should have one argument");
+            }
+            if (! argTypes[0].toString().equals(OBJECT_DESC)) {
+                error("first argument of getter should be of Object type, found: " + argTypes[0]);
+            }
+            if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) {
+                error("return type of getter should not be void");
+            }
+        } else if (kind == Kind.SETTER) {
+            final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+            if (argTypes.length != 2) {
+                error("setter methods should have two arguments");
+            }
+            if (! argTypes[0].toString().equals(OBJECT_DESC)) {
+                error("first argument of setter should be of Object type, found: " + argTypes[0]);
+            }
+            if (!Type.getReturnType(javaDesc).toString().equals("V")) {
+                error("return type of setter should be void, found: " + Type.getReturnType(javaDesc));
+            }
+        }
+    }
+
+    private void error(final String msg) {
+        throw new RuntimeException(javaName + javaDesc + " : " + msg);
+    }
+
+    /**
+     * @return the initClass
+     */
+    String getInitClass() {
+        return initClass;
+    }
+
+    /**
+     * @param initClass the initClass to set
+     */
+    void setInitClass(final String initClass) {
+        this.initClass = initClass;
+    }
+
+    @Override
+    protected Object clone() {
+        try {
+            return super.clone();
+        } catch (final CloneNotSupportedException e) {
+            assert false : "clone not supported " + e;
+            return null;
+        }
+    }
+
+    /**
+     * @return the arity
+     */
+    int getArity() {
+        return arity;
+    }
+
+    /**
+     * @param arity the arity to set
+     */
+    void setArity(final int arity) {
+        this.arity = arity;
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java
new file mode 100644
index 0000000..c3dfd87
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java
@@ -0,0 +1,426 @@
+/*
+ * 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.tools.nasgen;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.AALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.AASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACONST_NULL;
+import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.ANEWARRAY;
+import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.ASM4;
+import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.BALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.BASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.BIPUSH;
+import static jdk.internal.org.objectweb.asm.Opcodes.CALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.CASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.CHECKCAST;
+import static jdk.internal.org.objectweb.asm.Opcodes.DALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.DASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.DCONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.DRETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP2;
+import static jdk.internal.org.objectweb.asm.Opcodes.FALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.FASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.FCONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.FRETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.GETFIELD;
+import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.IALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.ISTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.LALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.LASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.NEW;
+import static jdk.internal.org.objectweb.asm.Opcodes.POP;
+import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD;
+import static jdk.internal.org.objectweb.asm.Opcodes.PUTSTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.SALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.SASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH;
+import static jdk.internal.org.objectweb.asm.Opcodes.SWAP;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.METHODHANDLE_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_METHODHANDLE;
+
+import java.util.List;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Type;
+
+/**
+ * Base class for all method generating classes.
+ *
+ */
+public class MethodGenerator extends MethodVisitor {
+    private final int access;
+    private final String name;
+    private final String descriptor;
+    private final Type returnType;
+    private final Type[] argumentTypes;
+
+    MethodGenerator(final MethodVisitor mv, final int access, final String name, final String descriptor) {
+        super(ASM4, mv);
+        this.access        = access;
+        this.name          = name;
+        this.descriptor    = descriptor;
+        this.returnType    = Type.getReturnType(descriptor);
+        this.argumentTypes = Type.getArgumentTypes(descriptor);
+    }
+
+    int getAccess() {
+        return access;
+    }
+
+    final String getName() {
+        return name;
+    }
+
+    final String getDescriptor() {
+        return descriptor;
+    }
+
+    final Type getReturnType() {
+        return returnType;
+    }
+
+    final Type[] getArgumentTypes() {
+        return argumentTypes;
+    }
+
+    /**
+     * Check whether access for this method is static
+     * @return true if static
+     */
+    protected final boolean isStatic() {
+        return (getAccess() & ACC_STATIC) != 0;
+    }
+
+    /**
+     * Check whether this method is a constructor
+     * @return true if constructor
+     */
+    protected final boolean isConstructor() {
+        return "<init>".equals(name);
+    }
+
+    void newObject(final String type) {
+        super.visitTypeInsn(NEW, type);
+    }
+
+    void newObjectArray(final String type) {
+        super.visitTypeInsn(ANEWARRAY, type);
+    }
+
+    void loadThis() {
+        if ((access & ACC_STATIC) != 0) {
+            throw new IllegalStateException("no 'this' inside static method");
+        }
+        super.visitVarInsn(ALOAD, 0);
+    }
+
+    void returnValue() {
+        super.visitInsn(returnType.getOpcode(IRETURN));
+    }
+
+    void returnVoid() {
+        super.visitInsn(RETURN);
+    }
+
+    // load, store
+    void arrayLoad(final Type type) {
+        super.visitInsn(type.getOpcode(IALOAD));
+    }
+
+    void arrayLoad() {
+        super.visitInsn(AALOAD);
+    }
+
+    void arrayStore(final Type type) {
+        super.visitInsn(type.getOpcode(IASTORE));
+    }
+
+    void arrayStore() {
+        super.visitInsn(AASTORE);
+    }
+
+    void loadLiteral(final Object value) {
+        super.visitLdcInsn(value);
+    }
+
+    void classLiteral(final String className) {
+        super.visitLdcInsn(className);
+    }
+
+    void loadLocal(final Type type, final int index) {
+        super.visitVarInsn(type.getOpcode(ILOAD), index);
+    }
+
+    void loadLocal(final int index) {
+        super.visitVarInsn(ALOAD, index);
+    }
+
+    void storeLocal(final Type type, final int index) {
+        super.visitVarInsn(type.getOpcode(ISTORE), index);
+    }
+
+    void storeLocal(final int index) {
+        super.visitVarInsn(ASTORE, index);
+    }
+
+    void checkcast(final String type) {
+        super.visitTypeInsn(CHECKCAST, type);
+    }
+
+    // push constants/literals
+    void pushNull() {
+        super.visitInsn(ACONST_NULL);
+    }
+
+    void push(final int value) {
+        if (value >= -1 && value <= 5) {
+            super.visitInsn(ICONST_0 + value);
+        } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
+            super.visitIntInsn(BIPUSH, value);
+        } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
+            super.visitIntInsn(SIPUSH, value);
+        } else {
+            super.visitLdcInsn(value);
+        }
+    }
+
+    void loadClass(final String className) {
+        super.visitLdcInsn(Type.getObjectType(className));
+    }
+
+    void pop() {
+        super.visitInsn(POP);
+    }
+
+    // various "dups"
+    void dup() {
+        super.visitInsn(DUP);
+    }
+
+    void dup2() {
+        super.visitInsn(DUP2);
+    }
+
+    void swap() {
+        super.visitInsn(SWAP);
+    }
+
+    void dupArrayValue(final int arrayOpcode) {
+        switch (arrayOpcode) {
+            case IALOAD: case FALOAD:
+            case AALOAD: case BALOAD:
+            case CALOAD: case SALOAD:
+            case IASTORE: case FASTORE:
+            case AASTORE: case BASTORE:
+            case CASTORE: case SASTORE:
+                dup();
+            break;
+
+            case LALOAD: case DALOAD:
+            case LASTORE: case DASTORE:
+                dup2();
+            break;
+            default:
+                throw new AssertionError("invalid dup");
+        }
+    }
+
+    void dupReturnValue(final int returnOpcode) {
+        switch (returnOpcode) {
+            case IRETURN:
+            case FRETURN:
+            case ARETURN:
+                super.visitInsn(DUP);
+                return;
+            case LRETURN:
+            case DRETURN:
+                super.visitInsn(DUP2);
+                return;
+            case RETURN:
+                return;
+            default:
+                throw new IllegalArgumentException("not return");
+        }
+    }
+
+    void dupValue(final Type type) {
+        switch (type.getSize()) {
+            case 1:
+                dup();
+            break;
+            case 2:
+                dup2();
+            break;
+            default:
+                throw new AssertionError("invalid dup");
+        }
+    }
+
+    void dupValue(final String desc) {
+        final int typeCode = desc.charAt(0);
+        switch (typeCode) {
+            case '[':
+            case 'L':
+            case 'Z':
+            case 'C':
+            case 'B':
+            case 'S':
+            case 'I':
+                super.visitInsn(DUP);
+                break;
+            case 'J':
+            case 'D':
+                super.visitInsn(DUP2);
+                break;
+            default:
+                throw new RuntimeException("invalid signature");
+        }
+    }
+
+    // push default value of given type desc
+    void defaultValue(final String desc) {
+        final int typeCode = desc.charAt(0);
+        switch (typeCode) {
+            case '[':
+            case 'L':
+                super.visitInsn(ACONST_NULL);
+                break;
+            case 'Z':
+            case 'C':
+            case 'B':
+            case 'S':
+            case 'I':
+                super.visitInsn(ICONST_0);
+                break;
+            case 'J':
+                super.visitInsn(LCONST_0);
+                break;
+            case 'F':
+                super.visitInsn(FCONST_0);
+                break;
+            case 'D':
+                super.visitInsn(DCONST_0);
+                break;
+            default:
+                throw new AssertionError("invalid desc " + desc);
+        }
+    }
+
+    // invokes, field get/sets
+    void invokeVirtual(final String owner, final String method, final String desc) {
+        super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc);
+    }
+
+    void invokeSpecial(final String owner, final String method, final String desc) {
+        super.visitMethodInsn(INVOKESPECIAL, owner, method, desc);
+    }
+
+    void invokeStatic(final String owner, final String method, final String desc) {
+        super.visitMethodInsn(INVOKESTATIC, owner, method, desc);
+    }
+
+    void putStatic(final String owner, final String field, final String desc) {
+        super.visitFieldInsn(PUTSTATIC, owner, field, desc);
+    }
+
+    void getStatic(final String owner, final String field, final String desc) {
+        super.visitFieldInsn(GETSTATIC, owner, field, desc);
+    }
+
+    void putField(final String owner, final String field, final String desc) {
+        super.visitFieldInsn(PUTFIELD, owner, field, desc);
+    }
+
+    void getField(final String owner, final String field, final String desc) {
+        super.visitFieldInsn(GETFIELD, owner, field, desc);
+    }
+
+    void memberInfoArray(final String className, final List<MemberInfo> mis) {
+        if (mis.isEmpty()) {
+            pushNull();
+            return;
+        }
+
+        int pos = 0;
+        push(mis.size());
+        newObjectArray(METHODHANDLE_TYPE);
+        for (final MemberInfo mi : mis) {
+            dup();
+            push(pos++);
+            visitLdcInsn(new Handle(H_INVOKESTATIC, className, mi.getJavaName(), mi.getJavaDesc()));
+            arrayStore(TYPE_METHODHANDLE);
+        }
+    }
+
+    void computeMaxs() {
+        // These values are ignored as we create class writer
+        // with ClassWriter.COMPUTE_MAXS flag.
+        super.visitMaxs(Short.MAX_VALUE, Short.MAX_VALUE);
+    }
+
+    // debugging support - print calls
+    void println(final String msg) {
+        super.visitFieldInsn(GETSTATIC,
+                    "java/lang/System",
+                    "out",
+                    "Ljava/io/PrintStream;");
+        super.visitLdcInsn(msg);
+        super.visitMethodInsn(INVOKEVIRTUAL,
+                    "java/io/PrintStream",
+                    "println",
+                    "(Ljava/lang/String;)V");
+    }
+
+    // print the object on the top of the stack
+    void printObject() {
+        super.visitFieldInsn(GETSTATIC,
+                    "java/lang/System",
+                    "out",
+                    "Ljava/io/PrintStream;");
+        super.visitInsn(SWAP);
+        super.visitMethodInsn(INVOKEVIRTUAL,
+                    "java/io/PrintStream",
+                    "println",
+                    "(Ljava/lang/Object;)V");
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java
new file mode 100644
index 0000000..de2f392
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java
@@ -0,0 +1,88 @@
+/*
+ * 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.tools.nasgen;
+
+import jdk.internal.org.objectweb.asm.AnnotationVisitor;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A visitor that does nothing on visitXXX calls.
+ *
+ */
+public class NullVisitor extends ClassVisitor {
+    NullVisitor() {
+        super(Opcodes.ASM4);
+    }
+
+    @Override
+    public MethodVisitor visitMethod(
+        final int access,
+        final String name,
+        final String desc,
+        final String signature,
+        final String[] exceptions) {
+        return new MethodVisitor(Opcodes.ASM4) {
+            @Override
+            public AnnotationVisitor visitAnnotationDefault() {
+                return new NullAnnotationVisitor();
+            }
+
+            @Override
+            public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+                return new NullAnnotationVisitor();
+            }
+        };
+    }
+
+    @Override
+    public FieldVisitor visitField(
+        final int access,
+        final String name,
+        final String desc,
+        final String signature,
+        final Object value) {
+        return new FieldVisitor(Opcodes.ASM4) {
+            @Override
+            public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+                return new NullAnnotationVisitor();
+            }
+        };
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
+        return new NullAnnotationVisitor();
+    }
+
+    private static class NullAnnotationVisitor extends AnnotationVisitor {
+        NullAnnotationVisitor() {
+            super(Opcodes.ASM4);
+        }
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java
new file mode 100644
index 0000000..17750cd
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java
@@ -0,0 +1,184 @@
+/*
+ * 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.tools.nasgen;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
+import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * This class generates prototype class for a @ClassInfo annotated class.
+ *
+ */
+public class PrototypeGenerator extends ClassGenerator {
+    private final ScriptClassInfo scriptClassInfo;
+    private final String className;
+    private final int memberCount;
+
+    PrototypeGenerator(final ScriptClassInfo sci) {
+        this.scriptClassInfo = sci;
+        this.className = scriptClassInfo.getPrototypeClassName();
+        this.memberCount = scriptClassInfo.getPrototypeMemberCount();
+    }
+
+    byte[] getClassBytes() {
+        // new class extensing from ScriptObject
+        cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, PROTOTYPEOBJECT_TYPE, null);
+        if (memberCount > 0) {
+            // add fields
+            emitFields();
+            // add <clinit>
+            emitStaticInitializer();
+        }
+        // add <init>
+        emitConstructor();
+
+        // add getClassName()
+        emitGetClassName(scriptClassInfo.getName());
+
+        cw.visitEnd();
+        return cw.toByteArray();
+    }
+
+    // --Internals only below this point
+    private void emitFields() {
+        // introduce "Function" type instance fields for each
+        // prototype @Function in script class info
+        for (MemberInfo memInfo : scriptClassInfo.getMembers()) {
+            if (memInfo.isPrototypeFunction()) {
+                addFunctionField(memInfo.getJavaName());
+                memInfo = (MemberInfo)memInfo.clone();
+                memInfo.setJavaDesc(OBJECT_DESC);
+                addGetter(className, memInfo);
+                addSetter(className, memInfo);
+            } else if (memInfo.isPrototypeProperty()) {
+                if (memInfo.isStaticFinal()) {
+                    addGetter(scriptClassInfo.getJavaName(), memInfo);
+                } else {
+                    addField(memInfo.getJavaName(), memInfo.getJavaDesc());
+                    memInfo = (MemberInfo)memInfo.clone();
+                    memInfo.setJavaAccess(ACC_PUBLIC);
+                    addGetter(className, memInfo);
+                    addSetter(className, memInfo);
+                }
+            }
+        }
+
+        addMapField();
+    }
+
+    private void emitStaticInitializer() {
+        final MethodGenerator mi = makeStaticInitializer();
+        emitStaticInitPrefix(mi, className);
+        for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
+            if (memInfo.isPrototypeFunction() || memInfo.isPrototypeProperty()) {
+                linkerAddGetterSetter(mi, className, memInfo);
+            } else if (memInfo.isPrototypeGetter()) {
+                final MemberInfo setter = scriptClassInfo.findSetter(memInfo);
+                linkerAddGetterSetter(mi, scriptClassInfo.getJavaName(), memInfo, setter);
+            }
+        }
+        emitStaticInitSuffix(mi, className);
+    }
+
+    private void emitConstructor() {
+        final MethodGenerator mi = makeConstructor();
+        mi.visitCode();
+        mi.loadThis();
+        if (memberCount > 0) {
+            // call "super(map$)"
+            mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC);
+            // make sure we use duplicated PropertyMap so that original map
+            // stays intact and so can be used for many globals in same context
+            mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC);
+            mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC);
+            // initialize Function type fields
+            initFunctionFields(mi);
+        } else {
+            // call "super()"
+            mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, DEFAULT_INIT_DESC);
+        }
+        mi.returnVoid();
+        mi.computeMaxs();
+        mi.visitEnd();
+    }
+
+    private void initFunctionFields(final MethodGenerator mi) {
+        for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
+            if (! memInfo.isPrototypeFunction()) {
+                continue;
+            }
+            mi.loadThis();
+            newFunction(mi, scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName()));
+            mi.putField(className, memInfo.getJavaName(), OBJECT_DESC);
+        }
+    }
+
+    /**
+     * External entry point for PrototypeGenerator if called from the command line
+     *
+     * @param args arguments, takes 1 argument which is the class to process
+     * @throws IOException if class cannot be read
+     */
+    public static void main(final String[] args) throws IOException {
+        if (args.length != 1) {
+            System.err.println("Usage: " + ConstructorGenerator.class.getName() + " <class>");
+            System.exit(1);
+        }
+
+        final String className = args[0].replace('.', '/');
+        final ScriptClassInfo sci = getScriptClassInfo(className + ".class");
+        if (sci == null) {
+            System.err.println("No @ScriptClass in " + className);
+            System.exit(2);
+            throw new AssertionError(); //guard against warning that sci is null below
+        }
+        try {
+            sci.verify();
+        } catch (final Exception e) {
+            System.err.println(e.getMessage());
+            System.exit(3);
+        }
+        final PrototypeGenerator gen = new PrototypeGenerator(sci);
+        try (FileOutputStream fos = new FileOutputStream(className + PROTOTYPE_SUFFIX + ".class")) {
+            fos.write(gen.getClassBytes());
+        }
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java
new file mode 100644
index 0000000..0a1579f
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java
@@ -0,0 +1,237 @@
+/*
+ * 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.tools.nasgen;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import jdk.internal.org.objectweb.asm.Type;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Getter;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Setter;
+import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
+
+/**
+ * All annotation information from a class that is annotated with
+ * the annotation com.sun.oracle.objects.annotations.ScriptClass.
+ *
+ */
+public final class ScriptClassInfo {
+    // descriptots for various annotations
+    static final String SCRIPT_CLASS_ANNO_DESC  = Type.getDescriptor(ScriptClass.class);
+    static final String CONSTRUCTOR_ANNO_DESC   = Type.getDescriptor(Constructor.class);
+    static final String FUNCTION_ANNO_DESC      = Type.getDescriptor(Function.class);
+    static final String GETTER_ANNO_DESC        = Type.getDescriptor(Getter.class);
+    static final String SETTER_ANNO_DESC        = Type.getDescriptor(Setter.class);
+    static final String PROPERTY_ANNO_DESC      = Type.getDescriptor(Property.class);
+    static final String WHERE_ENUM_DESC         = Type.getDescriptor(Where.class);
+    static final String SPECIALIZED_FUNCTION    = Type.getDescriptor(SpecializedFunction.class);
+    static final String SPECIALIZED_CONSTRUCTOR = Type.getDescriptor(SpecializedConstructor.class);
+
+    static final Map<String, Kind> annotations = new HashMap<>();
+
+    static {
+        annotations.put(SCRIPT_CLASS_ANNO_DESC, Kind.SCRIPT_CLASS);
+        annotations.put(FUNCTION_ANNO_DESC, Kind.FUNCTION);
+        annotations.put(CONSTRUCTOR_ANNO_DESC, Kind.CONSTRUCTOR);
+        annotations.put(GETTER_ANNO_DESC, Kind.GETTER);
+        annotations.put(SETTER_ANNO_DESC, Kind.SETTER);
+        annotations.put(PROPERTY_ANNO_DESC, Kind.PROPERTY);
+        annotations.put(SPECIALIZED_FUNCTION, Kind.SPECIALIZED_FUNCTION);
+        annotations.put(SPECIALIZED_CONSTRUCTOR, Kind.SPECIALIZED_CONSTRUCTOR);
+    }
+
+    // name of the script class
+    private String name;
+    // member info for script properties
+    private List<MemberInfo> members = Collections.emptyList();
+    // java class name that is annotated with @ScriptClass
+    private String javaName;
+
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the members
+     */
+    public List<MemberInfo> getMembers() {
+        return Collections.unmodifiableList(members);
+    }
+
+    /**
+     * @param members the members to set
+     */
+    public void setMembers(final List<MemberInfo> members) {
+        this.members = members;
+    }
+
+    MemberInfo getConstructor() {
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getKind() == Kind.CONSTRUCTOR) {
+                return memInfo;
+            }
+        }
+        return null;
+    }
+
+    List<MemberInfo> getSpecializedConstructors() {
+        final List<MemberInfo> res = new LinkedList<>();
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getKind() == Kind.SPECIALIZED_CONSTRUCTOR) {
+                res.add(memInfo);
+            }
+        }
+        return res;
+    }
+
+    int getPrototypeMemberCount() {
+        int count = 0;
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getWhere() == Where.PROTOTYPE || memInfo.isConstructor()) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    int getConstructorMemberCount() {
+        int count = 0;
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getWhere() == Where.CONSTRUCTOR) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    int getInstancePropertyCount() {
+        int count = 0;
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getWhere() == Where.INSTANCE) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    MemberInfo find(final String findJavaName, final String findJavaDesc, final int findAccess) {
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getJavaName().equals(findJavaName) &&
+                memInfo.getJavaDesc().equals(findJavaDesc) &&
+                memInfo.getJavaAccess() == findAccess) {
+                return memInfo;
+            }
+        }
+        return null;
+    }
+
+    List<MemberInfo> findSpecializations(final String methodName) {
+        final List<MemberInfo> res = new LinkedList<>();
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getName().equals(methodName) &&
+                memInfo.getKind() == Kind.SPECIALIZED_FUNCTION) {
+                res.add(memInfo);
+            }
+        }
+        return res;
+    }
+
+    MemberInfo findSetter(final MemberInfo getter) {
+        assert getter.getKind() == Kind.GETTER : "getter expected";
+        final String getterName = getter.getName();
+        final Where getterWhere = getter.getWhere();
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getKind() == Kind.SETTER &&
+                getterName.equals(memInfo.getName()) &&
+                getterWhere == memInfo.getWhere()) {
+                return memInfo;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @return the javaName
+     */
+    public String getJavaName() {
+        return javaName;
+    }
+
+    /**
+     * @param javaName the javaName to set
+     */
+    void setJavaName(final String javaName) {
+        this.javaName = javaName;
+    }
+
+    String getConstructorClassName() {
+        return getJavaName() + StringConstants.CONSTRUCTOR_SUFFIX;
+    }
+
+    String getPrototypeClassName() {
+        return getJavaName() + StringConstants.PROTOTYPE_SUFFIX;
+    }
+
+    void verify() {
+        boolean constructorSeen = false;
+        for (final MemberInfo memInfo : getMembers()) {
+            if (memInfo.isConstructor()) {
+                if (constructorSeen) {
+                    error("more than @Constructor method");
+                }
+                constructorSeen = true;
+            }
+            try {
+                memInfo.verify();
+            } catch (final Exception e) {
+                error(e.getMessage());
+            }
+        }
+    }
+
+    private void error(final String msg) throws RuntimeException {
+        throw new RuntimeException(javaName + " : " + msg);
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java
new file mode 100644
index 0000000..5561cfb
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java
@@ -0,0 +1,331 @@
+/*
+ * 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.tools.nasgen;
+
+import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.SCRIPT_CLASS_ANNO_DESC;
+import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.WHERE_ENUM_DESC;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import jdk.internal.org.objectweb.asm.AnnotationVisitor;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
+
+/**
+ * This class collects all @ScriptClass and other annotation information from a
+ * compiled .class file. Enforces that @Function/@Getter/@Setter/@Constructor
+ * methods are declared to be 'static'.
+ */
+public class ScriptClassInfoCollector extends ClassVisitor {
+    private String scriptClassName;
+    private List<MemberInfo> scriptMembers;
+    private String javaClassName;
+
+    ScriptClassInfoCollector(final ClassVisitor visitor) {
+        super(Opcodes.ASM4, visitor);
+    }
+
+    ScriptClassInfoCollector() {
+        this(new NullVisitor());
+    }
+
+    private void addScriptMember(final MemberInfo memInfo) {
+        if (scriptMembers == null) {
+            scriptMembers = new ArrayList<>();
+        }
+        scriptMembers.add(memInfo);
+    }
+
+    @Override
+    public void visit(final int version, final int access, final String name, final String signature,
+           final String superName, final String[] interfaces) {
+        super.visit(version, access, name, signature, superName, interfaces);
+        javaClassName = name;
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
+        final AnnotationVisitor delegateAV = super.visitAnnotation(desc, visible);
+        if (SCRIPT_CLASS_ANNO_DESC.equals(desc)) {
+            return new AnnotationVisitor(Opcodes.ASM4, delegateAV) {
+                @Override
+                public void visit(final String name, final Object value) {
+                    if ("value".equals(name)) {
+                        scriptClassName = (String) value;
+                    }
+                    super.visit(name, value);
+                }
+            };
+        }
+
+        return delegateAV;
+    }
+
+    @Override
+    public FieldVisitor visitField(final int fieldAccess, final String fieldName, final String fieldDesc, final String signature, final Object value) {
+        final FieldVisitor delegateFV = super.visitField(fieldAccess, fieldName, fieldDesc, signature, value);
+
+        return new FieldVisitor(Opcodes.ASM4, delegateFV) {
+            @Override
+            public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+                final AnnotationVisitor delegateAV = super.visitAnnotation(descriptor, visible);
+
+                if (ScriptClassInfo.PROPERTY_ANNO_DESC.equals(descriptor)) {
+                    final MemberInfo memInfo = new MemberInfo();
+
+                    memInfo.setKind(Kind.PROPERTY);
+                    memInfo.setJavaName(fieldName);
+                    memInfo.setJavaDesc(fieldDesc);
+                    memInfo.setJavaAccess(fieldAccess);
+
+                    if ((fieldAccess & Opcodes.ACC_STATIC) != 0) {
+                        memInfo.setValue(value);
+                    }
+
+                    addScriptMember(memInfo);
+
+                    return new AnnotationVisitor(Opcodes.ASM4, delegateAV) {
+                        // These could be "null" if values are not suppiled,
+                        // in which case we have to use the default values.
+                        private String  name;
+                        private Integer attributes;
+                        private String  clazz = "";
+                        private Where   where;
+
+                        @Override
+                        public void visit(final String annotationName, final Object annotationValue) {
+                            switch (annotationName) {
+                            case "name":
+                                this.name = (String) annotationValue;
+                                break;
+                            case "attributes":
+                                this.attributes = (Integer) annotationValue;
+                                break;
+                            case "clazz":
+                                this.clazz = (annotationValue == null) ? "" : annotationValue.toString();
+                                break;
+                            default:
+                                break;
+                            }
+                            super.visit(annotationName, annotationValue);
+                        }
+
+                        @Override
+                        public void visitEnum(final String enumName, final String desc, final String enumValue) {
+                            if ("where".equals(enumName) && WHERE_ENUM_DESC.equals(desc)) {
+                                this.where = Where.valueOf(enumValue);
+                            }
+                            super.visitEnum(enumName, desc, enumValue);
+                        }
+
+                        @Override
+                        public void visitEnd() {
+                            super.visitEnd();
+                            memInfo.setName(name == null ? fieldName : name);
+                            memInfo.setAttributes(attributes == null
+                                    ? MemberInfo.DEFAULT_ATTRIBUTES : attributes);
+                            clazz = clazz.replace('.', '/');
+                            memInfo.setInitClass(clazz);
+                            memInfo.setWhere(where == null? Where.INSTANCE : where);
+                        }
+                    };
+                }
+
+                return delegateAV;
+            }
+        };
+    }
+
+    private void error(final String javaName, final String javaDesc, final String msg) {
+        throw new RuntimeException(scriptClassName + "." + javaName + javaDesc + " : " + msg);
+    }
+
+    @Override
+    public MethodVisitor visitMethod(final int methodAccess, final String methodName,
+            final String methodDesc, final String signature, final String[] exceptions) {
+
+        final MethodVisitor delegateMV = super.visitMethod(methodAccess, methodName, methodDesc,
+                signature, exceptions);
+
+        return new MethodVisitor(Opcodes.ASM4, delegateMV) {
+
+            @Override
+            public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+                final AnnotationVisitor delegateAV = super.visitAnnotation(descriptor, visible);
+                final Kind annoKind = ScriptClassInfo.annotations.get(descriptor);
+
+                if (annoKind != null) {
+                    if ((methodAccess & Opcodes.ACC_STATIC) == 0) {
+                        error(methodName, methodDesc, "nasgen method annotations cannot be on instance methods");
+                    }
+
+                    final MemberInfo memInfo = new MemberInfo();
+
+                    memInfo.setKind(annoKind);
+                    memInfo.setJavaName(methodName);
+                    memInfo.setJavaDesc(methodDesc);
+                    memInfo.setJavaAccess(methodAccess);
+
+                    addScriptMember(memInfo);
+
+                    return new AnnotationVisitor(Opcodes.ASM4, delegateAV) {
+                        // These could be "null" if values are not suppiled,
+                        // in which case we have to use the default values.
+                        private String  name;
+                        private Integer attributes;
+                        private Integer arity;
+                        private Where   where;
+
+                        @Override
+                        public void visit(final String annotationName, final Object annotationValue) {
+                            switch (annotationName) {
+                            case "name":
+                                this.name = (String)annotationValue;
+                                break;
+                            case "attributes":
+                                this.attributes = (Integer)annotationValue;
+                                break;
+                            case "arity":
+                                this.arity = (Integer)annotationValue;
+                                break;
+                            default:
+                                break;
+                            }
+
+                            super.visit(annotationName, annotationValue);
+                        }
+
+                        @Override
+                        public void visitEnum(final String enumName, final String desc, final String enumValue) {
+                            if ("where".equals(enumName) && WHERE_ENUM_DESC.equals(desc)) {
+                                this.where = Where.valueOf(enumValue);
+                            }
+                            super.visitEnum(enumName, desc, enumValue);
+                        }
+
+                        @Override
+                        public void visitEnd() {
+                            super.visitEnd();
+
+                            if (memInfo.getKind() == Kind.CONSTRUCTOR) {
+                                memInfo.setName(name == null ? scriptClassName : name);
+                            } else {
+                                memInfo.setName(name == null ? methodName : name);
+                            }
+                            memInfo.setAttributes(attributes == null ? MemberInfo.DEFAULT_ATTRIBUTES : attributes);
+
+                            memInfo.setArity((arity == null)? MemberInfo.DEFAULT_ARITY : arity);
+                            if (where == null) {
+                                // by default @Getter/@Setter belongs to INSTANCE
+                                // @Function belong to PROTOTYPE.
+                                switch (memInfo.getKind()) {
+                                    case GETTER:
+                                    case SETTER:
+                                        where = Where.INSTANCE;
+                                        break;
+                                    case SPECIALIZED_CONSTRUCTOR:
+                                    case CONSTRUCTOR:
+                                        where = Where.CONSTRUCTOR;
+                                        break;
+                                    case FUNCTION:
+                                        where = Where.PROTOTYPE;
+                                        break;
+                                    case SPECIALIZED_FUNCTION:
+                                        //TODO is this correct
+                                    default:
+                                        break;
+                                }
+                            }
+                            memInfo.setWhere(where);
+                        }
+                    };
+                }
+
+                return delegateAV;
+            }
+        };
+    }
+
+    ScriptClassInfo getScriptClassInfo() {
+        ScriptClassInfo sci = null;
+        if (scriptClassName != null) {
+            sci = new ScriptClassInfo();
+            sci.setName(scriptClassName);
+            if (scriptMembers == null) {
+                scriptMembers = Collections.emptyList();
+            }
+            sci.setMembers(scriptMembers);
+            sci.setJavaName(javaClassName);
+        }
+        return sci;
+    }
+
+    /**
+     * External entry point for ScriptClassInfoCollector if invoked from the command line
+     * @param args argument vector, args contains a class for which to collect info
+     * @throws IOException if there were problems parsing args or class
+     */
+    public static void main(final String[] args) throws IOException {
+        if (args.length != 1) {
+            System.err.println("Usage: " + ScriptClassInfoCollector.class.getName() + " <class>");
+            System.exit(1);
+        }
+
+        args[0] = args[0].replace('.', '/');
+        final ScriptClassInfoCollector scic = new ScriptClassInfoCollector();
+        try (final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(args[0] + ".class"))) {
+            final ClassReader reader = new ClassReader(bis);
+            reader.accept(scic, 0);
+        }
+        final ScriptClassInfo sci = scic.getScriptClassInfo();
+        final PrintStream out = System.out;
+        if (sci != null) {
+            out.println("script class: " + sci.getName());
+            out.println("===================================");
+            for (final MemberInfo memInfo : sci.getMembers()) {
+                out.println("kind : " + memInfo.getKind());
+                out.println("name : " + memInfo.getName());
+                out.println("attributes: " + memInfo.getAttributes());
+                out.println("javaName: " + memInfo.getJavaName());
+                out.println("javaDesc: " + memInfo.getJavaDesc());
+                out.println("where: " + memInfo.getWhere());
+                out.println("=====================================");
+            }
+        } else {
+            out.println(args[0] + " is not a @ScriptClass");
+        }
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java
new file mode 100644
index 0000000..d140585
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java
@@ -0,0 +1,309 @@
+/*
+ * 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.tools.nasgen;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP;
+import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.NEW;
+import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD;
+import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.$CLINIT$;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import jdk.internal.org.objectweb.asm.AnnotationVisitor;
+import jdk.internal.org.objectweb.asm.Attribute;
+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.FieldVisitor;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
+
+/**
+ * This class instruments the java class annotated with @ScriptClass.
+ *
+ * Changes done are:
+ *
+ * 1) remove all jdk.nashorn.internal.objects.annotations.* annotations.
+ * 2) static final @Property fields stay here. Other @Property fields moved to
+ *    respective classes depending on 'where' value of annotation.
+ * 2) add "Map" type static field named "$map".
+ * 3) add static initializer block to initialize map.
+ */
+
+public class ScriptClassInstrumentor extends ClassVisitor {
+    private final ScriptClassInfo scriptClassInfo;
+    private final int memberCount;
+    private boolean staticInitFound;
+
+    ScriptClassInstrumentor(final ClassVisitor visitor, final ScriptClassInfo sci) {
+        super(Opcodes.ASM4, visitor);
+        if (sci == null) {
+            throw new IllegalArgumentException("Null ScriptClassInfo, is the class annotated?");
+        }
+        this.scriptClassInfo = sci;
+        this.memberCount = scriptClassInfo.getInstancePropertyCount();
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
+        if (ScriptClassInfo.annotations.containsKey(desc)) {
+            // ignore @ScriptClass
+            return null;
+        }
+
+        return super.visitAnnotation(desc, visible);
+    }
+
+    @Override
+    public FieldVisitor visitField(final int fieldAccess, final String fieldName,
+            final String fieldDesc, final String signature, final Object value) {
+        final MemberInfo memInfo = scriptClassInfo.find(fieldName, fieldDesc, fieldAccess);
+        if (memInfo != null && memInfo.getKind() == Kind.PROPERTY &&
+                memInfo.getWhere() != Where.INSTANCE && !memInfo.isStaticFinal()) {
+            // non-instance @Property fields - these have to go elsewhere unless 'static final'
+            return null;
+        }
+
+        final FieldVisitor delegateFV = super.visitField(fieldAccess, fieldName, fieldDesc,
+                signature, value);
+        return new FieldVisitor(Opcodes.ASM4, delegateFV) {
+            @Override
+            public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
+                if (ScriptClassInfo.annotations.containsKey(desc)) {
+                    // ignore script field annotations
+                    return null;
+                }
+
+                return fv.visitAnnotation(desc, visible);
+            }
+
+            @Override
+            public void visitAttribute(final Attribute attr) {
+                fv.visitAttribute(attr);
+            }
+
+            @Override
+            public void visitEnd() {
+                fv.visitEnd();
+            }
+        };
+    }
+
+    @Override
+    public MethodVisitor visitMethod(final int methodAccess, final String methodName,
+            final String methodDesc, final String signature, final String[] exceptions) {
+
+        final boolean isConstructor = INIT.equals(methodName);
+        final boolean isStaticInit  = CLINIT.equals(methodName);
+
+        if (isStaticInit) {
+            staticInitFound = true;
+        }
+
+        final MethodGenerator delegateMV = new MethodGenerator(super.visitMethod(methodAccess, methodName, methodDesc,
+                signature, exceptions), methodAccess, methodName, methodDesc);
+
+        return new MethodVisitor(Opcodes.ASM4, delegateMV) {
+            @Override
+            public void visitInsn(final int opcode) {
+                // call $clinit$ just before return from <clinit>
+                if (isStaticInit && opcode == RETURN) {
+                    super.visitMethodInsn(INVOKESTATIC, scriptClassInfo.getJavaName(),
+                            $CLINIT$, DEFAULT_INIT_DESC);
+                }
+                super.visitInsn(opcode);
+            }
+
+            @Override
+            public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
+                if (isConstructor && opcode == INVOKESPECIAL &&
+                        INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) {
+                    super.visitFieldInsn(GETSTATIC, scriptClassInfo.getJavaName(),
+                            MAP_FIELD_NAME, MAP_DESC);
+                    super.visitMethodInsn(INVOKESPECIAL, SCRIPTOBJECT_TYPE, INIT,
+                            SCRIPTOBJECT_INIT_DESC);
+
+                    if (memberCount > 0) {
+                        // initialize @Property fields if needed
+                        for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
+                            if (memInfo.isInstanceProperty() && !memInfo.getInitClass().isEmpty()) {
+                                final String clazz = memInfo.getInitClass();
+                                super.visitVarInsn(ALOAD, 0);
+                                super.visitTypeInsn(NEW, clazz);
+                                super.visitInsn(DUP);
+                                super.visitMethodInsn(INVOKESPECIAL, clazz,
+                                    INIT, DEFAULT_INIT_DESC);
+                                super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(),
+                                    memInfo.getJavaName(), memInfo.getJavaDesc());
+                            }
+
+                            if (memInfo.isInstanceFunction()) {
+                                super.visitVarInsn(ALOAD, 0);
+                                ClassGenerator.newFunction(delegateMV, scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName()));
+                                super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(),
+                                    memInfo.getJavaName(), OBJECT_DESC);
+                            }
+                        }
+                    }
+                } else {
+                    super.visitMethodInsn(opcode, owner, name, desc);
+                }
+            }
+
+            @Override
+            public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
+                if (ScriptClassInfo.annotations.containsKey(desc)) {
+                    // ignore script method annotations
+                    return null;
+                }
+                return super.visitAnnotation(desc, visible);
+            }
+        };
+    }
+
+    @Override
+    public void visitEnd() {
+        emitFields();
+        emitStaticInitializer();
+        emitGettersSetters();
+        super.visitEnd();
+    }
+
+    private void emitFields() {
+        // introduce "Function" type instance fields for each
+        // instance @Function in script class info
+        final String className = scriptClassInfo.getJavaName();
+        for (MemberInfo memInfo : scriptClassInfo.getMembers()) {
+            if (memInfo.isInstanceFunction()) {
+                ClassGenerator.addFunctionField(cv, memInfo.getJavaName());
+                memInfo = (MemberInfo)memInfo.clone();
+                memInfo.setJavaDesc(OBJECT_DESC);
+                ClassGenerator.addGetter(cv, className, memInfo);
+                ClassGenerator.addSetter(cv, className, memInfo);
+            }
+        }
+        ClassGenerator.addMapField(this);
+    }
+
+    void emitGettersSetters() {
+        if (memberCount > 0) {
+            for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
+                final String className = scriptClassInfo.getJavaName();
+                if (memInfo.isInstanceProperty()) {
+                    ClassGenerator.addGetter(cv, className, memInfo);
+                    if (! memInfo.isFinal()) {
+                        ClassGenerator.addSetter(cv, className, memInfo);
+                    }
+                }
+            }
+        }
+    }
+
+    private void emitStaticInitializer() {
+        final String className = scriptClassInfo.getJavaName();
+        if (! staticInitFound) {
+            // no user written <clinit> and so create one
+            final MethodVisitor mv = ClassGenerator.makeStaticInitializer(this);
+            mv.visitCode();
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(Short.MAX_VALUE, 0);
+            mv.visitEnd();
+        }
+        // Now generate $clinit$
+        final MethodGenerator mi = ClassGenerator.makeStaticInitializer(this, $CLINIT$);
+        ClassGenerator.emitStaticInitPrefix(mi, className);
+        if (memberCount > 0) {
+            for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
+                if (memInfo.isInstanceProperty() || memInfo.isInstanceFunction()) {
+                    ClassGenerator.linkerAddGetterSetter(mi, className, memInfo);
+                } else if (memInfo.isInstanceGetter()) {
+                    final MemberInfo setter = scriptClassInfo.findSetter(memInfo);
+                    ClassGenerator.linkerAddGetterSetter(mi, className, memInfo, setter);
+                }
+            }
+        }
+        ClassGenerator.emitStaticInitSuffix(mi, className);
+    }
+
+    /**
+     * External entry point for ScriptClassInfoCollector if run from the command line
+     *
+     * @param args arguments - one argument is needed, the name of the class to collect info from
+     *
+     * @throws IOException if there are problems reading class
+     */
+    public static void main(final String[] args) throws IOException {
+        if (args.length != 1) {
+            System.err.println("Usage: " + ScriptClassInfoCollector.class.getName() + " <class>");
+            System.exit(1);
+        }
+
+        final String fileName = args[0].replace('.', '/') + ".class";
+        final ScriptClassInfo sci = ClassGenerator.getScriptClassInfo(fileName);
+        if (sci == null) {
+            System.err.println("No @ScriptClass in " + fileName);
+            System.exit(2);
+            throw new AssertionError(); //guard against warning that sci is null below
+        }
+
+        try {
+            sci.verify();
+        } catch (final Exception e) {
+            System.err.println(e.getMessage());
+            System.exit(3);
+        }
+
+        final ClassWriter writer = ClassGenerator.makeClassWriter();
+        try (final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName))) {
+            final ClassReader reader = new ClassReader(bis);
+            final CheckClassAdapter checker = new CheckClassAdapter(writer);
+            final ScriptClassInstrumentor instr = new ScriptClassInstrumentor(checker, sci);
+            reader.accept(instr, 0);
+        }
+
+        try (FileOutputStream fos = new FileOutputStream(fileName)) {
+            fos.write(writer.toByteArray());
+        }
+    }
+}
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java
new file mode 100644
index 0000000..8c2dcef
--- /dev/null
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java
@@ -0,0 +1,113 @@
+/*
+ * 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.tools.nasgen;
+
+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;
+
+/**
+ * String constants used for code generation/instrumentation.
+ */
+@SuppressWarnings("javadoc")
+public interface StringConstants {
+    static final Type TYPE_METHOD             = Type.getType(Method.class);
+    static final Type TYPE_METHODHANDLE       = Type.getType(MethodHandle.class);
+    static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class);
+    static final Type TYPE_OBJECT             = Type.getType(Object.class);
+    static final Type TYPE_CLASS              = Type.getType(Class.class);
+    static final Type TYPE_STRING             = Type.getType(String.class);
+
+    // Nashorn types
+    static final Type TYPE_LOOKUP             = Type.getType(Lookup.class);
+    static final Type TYPE_PROPERTYMAP        = Type.getType(PropertyMap.class);
+    static final Type TYPE_PROTOTYPEOBJECT    = Type.getType(PrototypeObject.class);
+    static final Type TYPE_SCRIPTFUNCTION     = Type.getType(ScriptFunction.class);
+    static final Type TYPE_SCRIPTFUNCTIONIMPL = Type.getType(ScriptFunctionImpl.class);
+    static final Type TYPE_SCRIPTOBJECT       = Type.getType(ScriptObject.class);
+
+    static final String PROTOTYPE = "prototype";
+    static final String PROTOTYPE_SUFFIX = "$Prototype";
+    static final String CONSTRUCTOR_SUFFIX = "$Constructor";
+    // This field name is known to Nashorn runtime (Context).
+    // Synchronize the name change, if needed at all.
+    static final String MAP_FIELD_NAME = "$nasgenmap$";
+    static final String $CLINIT$ = "$clinit$";
+    static final String CLINIT = "<clinit>";
+    static final String INIT = "<init>";
+    static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE);
+
+    static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP);
+
+    static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
+
+    static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
+    static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor();
+    static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class);
+
+    static final String SCRIPTFUNCTION_TYPE = TYPE_SCRIPTFUNCTION.getInternalName();
+    static final String SCRIPTFUNCTIONIMPL_TYPE = TYPE_SCRIPTFUNCTIONIMPL.getInternalName();
+    static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION = "makeFunction";
+    static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC =
+        Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE);
+    static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC =
+        Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
+
+    static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 =
+        Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
+    static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 =
+        Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_METHODHANDLE_ARRAY);
+    static final String SCRIPTFUNCTION_SETARITY = "setArity";
+    static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
+    static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName();
+    static final String PROTOTYPEOBJECT_SETCONSTRUCTOR = "setConstructor";
+    static final String PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT, TYPE_OBJECT);
+    static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName();
+    static final String MAP_TYPE = TYPE_PROPERTYMAP.getInternalName();
+    static final String MAP_DESC = TYPE_PROPERTYMAP.getDescriptor();
+    static final String MAP_NEWMAP = "newMap";
+    static final String MAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_CLASS);
+    static final String MAP_DUPLICATE = "duplicate";
+    static final String MAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
+    static final String MAP_SETFLAGS = "setFlags";
+    static final String LOOKUP_TYPE = TYPE_LOOKUP.getInternalName();
+    static final String LOOKUP_GETMETHOD = "getMethod";
+    static final String LOOKUP_NEWPROPERTY = "newProperty";
+    static final String LOOKUP_NEWPROPERTY_DESC =
+        Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_PROPERTYMAP, TYPE_STRING, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE);
+    static final String GETTER_PREFIX = "G$";
+    static final String SETTER_PREFIX = "S$";
+
+    // ScriptObject.getClassName() method.
+    static final String GET_CLASS_NAME = "getClassName";
+    static final String GET_CLASS_NAME_DESC = Type.getMethodDescriptor(TYPE_STRING);
+}
diff --git a/nashorn/docs/DEVELOPER_README b/nashorn/docs/DEVELOPER_README
new file mode 100644
index 0000000..3bd220b
--- /dev/null
+++ b/nashorn/docs/DEVELOPER_README
@@ -0,0 +1,475 @@
+This document describes system properties that are used for internal
+debugging and instrumentation purposes, along with the system loggers,
+which are used for the same thing.
+
+This document is intended as a developer resource, and it is not
+needed as Nashorn documentation for normal usage. Flags and system
+properties described herein are subject to change without notice.
+
+=====================================
+1. System properties used internally
+=====================================
+
+This documentation of the system property flags assume that the
+default value of the flag is false, unless otherwise specified.
+
+SYSTEM PROPERTY: -Dnashorn.unstable.relink.threshold=x
+
+This property controls how many call site misses are allowed before a 
+callsite is relinked with "apply" semantics to never change again. 
+In the case of megamorphic callsites, this is necessary, or the 
+program would spend all its time swapping out callsite targets. Dynalink 
+has a default value (currently 8 relinks) for this property if it 
+is not explicitly set.
+
+
+SYSTEM PROPERTY: -Dnashorn.compiler.splitter.threshold=x
+
+This will change the node weight that requires a subgraph of the IR to
+be split into several classes in order not to run out of bytecode space.
+The default value is 0x8000 (32768).
+
+
+SYSTEM PROPERTY: -Dnashorn.compiler.intarithmetic
+
+Arithmetic operations in Nashorn (except bitwise ones) typically
+coerce the operands to doubles (as per the JavaScript spec). To switch
+this off and remain in integer mode, for example for "var x = a&b; var
+y = c&d; var z = x*y;", use this flag. This will force the
+multiplication of variables that are ints to be done with the IMUL
+bytecode and the result "z" to become an int.
+
+WARNING: Note that is is experimental only to ensure that type support
+exists for all primitive types. The generated code is unsound. This
+will be the case until we do optimizations based on it. There is a CR
+in Nashorn to do better range analysis, and ensure that this is only
+done where the operation can't overflow into a wider type. Currently
+no overflow checking is done, so at the moment, until range analysis
+has been completed, this option is turned off.
+
+We've experimented by using int arithmetic for everything and putting
+overflow checks afterwards, which would recompute the operation with
+the correct precision, but have yet to find a configuration where this
+is faster than just using doubles directly, even if the int operation
+does not overflow. Getting access to a JVM intrinsic that does branch
+on overflow would probably alleviate this.
+
+There is also a problem with this optimistic approach if the symbol
+happens to reside in a local variable slot in the bytecode, as those
+are strongly typed. Then we would need to split large sections of
+control flow, so this is probably not the right way to go, while range
+analysis is. There is a large difference between integer bytecode
+without overflow checks and double bytecode. The former is
+significantly faster.
+
+
+SYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace=<x>
+
+See the description of the codegen logger below.
+
+
+SYSTEM_PROPERTY: -Dnashorn.fields.debug
+
+See the description on the fields logger below.
+
+
+SYSTEM PROPERTY: -Dnashorn.fields.dual
+
+When this property is true, Nashorn will attempt to use primitive
+fields for AccessorProperties (currently just AccessorProperties, not
+spill properties). Memory footprint for script objects will increase,
+as we need to maintain both a primitive field (a long) as well as an
+Object field for the property value. Ints are represented as the 32
+low bits of the long fields. Doubles are represented as the
+doubleToLongBits of their value. This way a single field can be used
+for all primitive types. Packing and unpacking doubles to their bit
+representation is intrinsified by the JVM and extremely fast.
+
+While dual fields in theory runs significantly faster than Object
+fields due to reduction of boxing and memory allocation overhead,
+there is still work to be done to make this a general purpose
+solution. Research is ongoing.
+
+In the future, this might complement or be replaced by experimental
+feature sun.misc.TaggedArray, which has been discussed on the mlvm
+mailing list. TaggedArrays are basically a way to share data space
+between primitives and references, and have the GC understand this.
+
+As long as only primitive values are written to the fields and enough
+type information exists to make sure that any reads don't have to be
+uselessly boxed and unboxed, this is significantly faster than the
+standard "Objects only" approach that currently is the default. See
+test/examples/dual-fields-micro.js for an example that runs twice as
+fast with dual fields as without them. Here, the compiler, can
+determine that we are dealing with numbers only throughout the entire
+property life span of the properties involved.
+
+If a "real" object (not a boxed primitive) is written to a field that
+has a primitive representation, its callsite is relinked and an Object
+field is used forevermore for that particular field in that
+PropertyMap and its children, even if primitives are later assigned to
+it.
+
+As the amount of compile time type information is very small in a
+dynamic language like JavaScript, it is frequently the case that
+something has to be treated as an object, because we don't know any
+better. In reality though, it is often a boxed primitive is stored to
+an AccessorProperty. The fastest way to handle this soundly is to use
+a callsite typecheck and avoid blowing the field up to an Object. We
+never revert object fields to primitives. Ping-pong:ing back and forth
+between primitive representation and Object representation would cause
+fatal performance overhead, so this is not an option.
+
+For a general application the dual fields approach is still slower
+than objects only fields in some places, about the same in most cases,
+and significantly faster in very few. This is due the program using
+primitives, but we still can't prove it. For example "local_var a =
+call(); field = a;" may very well write a double to the field, but the
+compiler dare not guess a double type if field is a local variable,
+due to bytecode variables being strongly typed and later non
+interchangeable. To get around this, the entire method would have to
+be replaced and a continuation retained to restart from. We believe
+that the next steps we should go through are instead:
+
+1) Implement method specialization based on callsite, as it's quite
+frequently the case that numbers are passed around, but currently our
+function nodes just have object types visible to the compiler. For
+example "var b = 17; func(a,b,17)" is an example where two parameters
+can be specialized, but the main version of func might also be called
+from another callsite with func(x,y,"string").
+
+2) This requires lazy jitting as the functions have to be specialized
+per callsite.
+
+Even though "function square(x) { return x*x }" might look like a
+trivial function that can always only take doubles, this is not
+true. Someone might have overridden the valueOf for x so that the
+toNumber coercion has side effects. To fulfil JavaScript semantics,
+the coercion has to run twice for both terms of the multiplication
+even if they are the same object. This means that call site
+specialization is necessary, not parameter specialization on the form
+"function square(x) { var xd = (double)x; return xd*xd; }", as one
+might first think.
+
+Generating a method specialization for any variant of a function that
+we can determine by types at compile time is a combinatorial explosion
+of byte code (try it e.g. on all the variants of am3 in the Octane
+benchmark crypto.js). Thus, this needs to be lazy
+
+3) Possibly optimistic callsite writes, something on the form
+
+x = y; //x is a field known to be a primitive. y is only an object as
+far as we can tell
+
+turns into
+
+try {
+  x = (int)y;
+} catch (X is not an integer field right now | ClassCastException e) {
+  x = y;
+}
+
+Mini POC shows that this is the key to a lot of dual field performance
+in seemingly trivial micros where one unknown object, in reality
+actually a primitive, foils it for us. Very common pattern. Once we
+are "all primitives", dual fields runs a lot faster than Object fields
+only.
+
+We still have to deal with objects vs primitives for local bytecode
+slots, possibly through code copying and versioning.
+
+
+SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[<x>[,*]], 
+  -Dnashorn.compiler.symbol.stacktrace=[<x>[,*]]
+
+When this property is set, creation and manipulation of any symbol
+named "x" will show information about when the compiler changes its
+type assumption, bytecode local variable slot assignment and other
+data. This is useful if, for example, a symbol shows up as an Object,
+when you believe it should be a primitive. Usually there is an
+explanation for this, for example that it exists in the global scope
+and type analysis has to be more conservative. 
+
+Several symbols names to watch can be specified by comma separation.
+
+If no variable name is specified (and no equals sign), all symbols
+will be watched
+
+By using "stacktrace" instead of or together with "trace", stack
+traces will be displayed upon symbol changes according to the same
+semantics.
+
+
+SYSTEM PROPERTY: nashorn.lexer.xmlliterals
+
+If this property it set, it means that the Lexer should attempt to
+parse XML literals, which would otherwise generate syntax
+errors. Warning: there are currently no unit tests for this
+functionality.
+
+XML literals, when this is enabled, end up as standard LiteralNodes in
+the IR.
+
+
+SYSTEM_PROPERTY: nashorn.debug
+
+If this property is set to true, Nashorn runs in Debug mode. Debug
+mode is slightly slower, as for example statistics counters are enabled
+during the run. Debug mode makes available a NativeDebug instance
+called "Debug" in the global space that can be used to print property
+maps and layout for script objects, as well as a "dumpCounters" method
+that will print the current values of the previously mentioned stats
+counters.
+
+These functions currently exists for Debug:
+
+"map" - print(Debug.map(x)) will dump the PropertyMap for object x to
+stdout (currently there also exist functions called "embedX", where X
+is a value from 0 to 3, that will dump the contents of the embed pool
+for the first spill properties in any script object and "spill", that
+will dump the contents of the growing spill pool of spill properties
+in any script object. This is of course subject to change without
+notice, should we change the script object layout.
+
+"methodHandle" - this method returns the method handle that is used
+for invoking a particular script function.
+
+"identical" - this method compares two script objects for reference
+equality. It is a == Java comparison
+
+"dumpCounters" - will dump the debug counters' current values to
+stdout.
+
+Currently we count number of ScriptObjects in the system, number of
+Scope objects in the system, number of ScriptObject listeners added,
+removed and dead (without references).
+
+We also count number of ScriptFunctions, ScriptFunction invocations
+and ScriptFunction allocations.
+
+Furthermore we count PropertyMap statistics: how many property maps
+exist, how many times were property maps cloned, how many times did
+the property map history cache hit, prevent new allocations, how many
+prototype invalidations were done, how many time the property map
+proto cache hit.
+
+Finally we count callsite misses on a per callsite bases, which occur
+when a callsite has to be relinked, due to a previous assumption of
+object layout being invalidated.
+
+
+SYSTEM PROPERTY: nashorn.methodhandles.debug,
+nashorn.methodhandles.debug=create
+
+If this property is enabled, each MethodHandle related call that uses
+the java.lang.invoke package gets its MethodHandle intercepted and an
+instrumentation printout of arguments and return value appended to
+it. This shows exactly which method handles are executed and from
+where. (Also MethodTypes and SwitchPoints). This can be augmented with
+more information, for example, instance count, by subclassing or
+further extending the TraceMethodHandleFactory implementation in
+MethodHandleFactory.java.
+
+If the property is specialized with "=create" as its option,
+instrumentation will be shown for method handles upon creation time
+rather than at runtime usage.
+
+
+SYSTEM PROPERTY: nashorn.methodhandles.debug.stacktrace
+
+This does the same as nashorn.methodhandles.debug, but when enabled
+also dumps the stack trace for every instrumented method handle
+operation. Warning: This is enormously verbose, but provides a pretty
+decent "grep:able" picture of where the calls are coming from.
+
+See the description of the codegen logger below for a more verbose
+description of this option
+
+
+SYSTEM PROPERTY: nashorn.scriptfunction.specialization.disable
+
+There are several "fast path" implementations of constructors and
+functions in the NativeObject classes that, in their original form,
+take a variable amount of arguments. Said functions are also declared
+to take Object parameters in their original form, as this is what the
+JavaScript specification mandates.
+
+However, we often know quite a lot more at a callsite of one of these
+functions. For example, Math.min is called with a fixed number (2) of
+integer arguments. The overhead of boxing these ints to Objects and
+folding them into an Object array for the generic varargs Math.min
+function is an order of magnitude slower than calling a specialized
+implementation of Math.min that takes two integers. Specialized
+functions and constructors are identified by the tag
+@SpecializedFunction and @SpecializedConstructor in the Nashorn
+code. The linker will link in the most appropriate (narrowest types,
+right number of types and least number of arguments) specialization if
+specializations are available.
+
+Every ScriptFunction may carry specializations that the linker can
+choose from. This framework will likely be extended for user defined
+functions. The compiler can often infer enough parameter type info
+from callsites for in order to generate simpler versions with less
+generic Object types. This feature depends on future lazy jitting, as
+there tend to be many calls to user defined functions, some where the
+callsite can be specialized, some where we mostly see object
+parameters even at the callsite.
+
+If this system property is set to true, the linker will not attempt to
+use any specialized function or constructor for native objects, but
+just call the generic one.
+
+
+SYSTEM PROPERTY: nashorn.tcs.miss.samplePercent=<x>
+
+When running with the trace callsite option (-tcs), Nashorn will count
+and instrument any callsite misses that require relinking. As the
+number of relinks is large and usually produces a lot of output, this
+system property can be used to constrain the percentage of misses that
+should be logged. Typically this is set to 1 or 5 (percent). 1% is the
+default value.
+
+
+SYSTEM_PROPERTY: nashorn.profilefile=<filename>
+
+When running with the profile callsite options (-pcs), Nashorn will
+dump profiling data for all callsites to stderr as a shutdown hook. To
+instead redirect this to a file, specify the path to the file using
+this system property.
+
+
+SYSTEM_PROPERTY: nashorn.regexp.impl=[jdk|joni]
+
+This property defines the regular expression engine to be used by
+Nashorn. The default implementation is "jdk" which is based on the
+JDK's java.util.regex package. Set this property to "joni" to install
+an implementation based on Joni, the regular expression engine used by
+the JRuby project.
+
+
+===============
+2. The loggers.
+===============
+
+It is very simple to create your own logger. Use the DebugLogger class
+and give the subsystem name as a constructor argument.
+
+The Nashorn loggers can be used to print per-module or per-subsystem
+debug information with different levels of verbosity. The loggers for
+a given subsystem are available are enabled by using
+
+--log=<systemname>[:<level>]
+
+on the command line.
+
+Here <systemname> identifies the name of the subsystem to be logged
+and the optional colon and level argument is a standard
+java.util.logging.Level name (severe, warning, info, config, fine,
+finer, finest). If the level is left out for a particular subsystem,
+it defaults to "info". Any log message logged as the level or a level
+that is more important will be output to stderr by the logger.
+
+Several loggers can be enabled by a single command line option, by
+putting a comma after each subsystem/level tuple (or each subsystem if
+level is unspecified). The --log option can also be given multiple
+times on the same command line, with the same effect.
+
+For example: --log=codegen,fields:finest is equivalent to
+--log=codegen:info --log=fields:finest
+
+The subsystems that currently support logging are:
+
+
+* compiler
+
+The compiler is in charge of turning source code and function nodes
+into byte code, and installs the classes into a class loader
+controlled from the Context. Log messages are, for example, about
+things like new compile units being allocated. The compiler has global
+settings that all the tiers of codegen (e.g. Lower and CodeGenerator)
+use.s
+
+
+* codegen
+
+The code generator is the emitter stage of the code pipeline, and
+turns the lowest tier of a FunctionNode into bytecode. Codegen logging
+shows byte codes as they are being emitted, line number information
+and jumps. It also shows the contents of the bytecode stack prior to
+each instruction being emitted. This is a good debugging aid. For
+example:
+
+[codegen] #41                       line:2 (f)_afc824e 
+[codegen] #42                           load symbol x slot=2 
+[codegen] #43  {1:O}                    load int 0 
+[codegen] #44  {2:I O}                  dynamic_runtime_call GT:ZOI_I args=2 returnType=boolean 
+[codegen] #45                              signature (Ljava/lang/Object;I)Z 
+[codegen] #46  {1:Z}                    ifeq  ternary_false_5402fe28 
+[codegen] #47                           load symbol x slot=2 
+[codegen] #48  {1:O}                    goto ternary_exit_107c1f2f 
+[codegen] #49                       ternary_false_5402fe28 
+[codegen] #50                           load symbol x slot=2 
+[codegen] #51  {1:O}                    convert object -> double 
+[codegen] #52  {1:D}                    neg 
+[codegen] #53  {1:D}                    convert double -> object 
+[codegen] #54  {1:O}                ternary_exit_107c1f2f 
+[codegen] #55  {1:O}                    return object 
+
+shows a ternary node being generated for the sequence "return x > 0 ?
+x : -x"
+
+The first number on the log line is a unique monotonically increasing
+emission id per bytecode. There is no guarantee this is the same id
+between runs.  depending on non deterministic code
+execution/compilation, but for small applications it usually is. If
+the system variable -Dnashorn.codegen.debug.trace=<x> is set, where x
+is a bytecode emission id, a stack trace will be shown as the
+particular bytecode is about to be emitted. This can be a quick way to
+determine where it comes from without attaching the debugger. "Who
+generated that neg?"
+
+The --log=codegen option is equivalent to setting the system variable
+"nashorn.codegen.debug" to true.
+
+
+* lower
+
+This is the first lowering pass.
+
+Lower is a code generation pass that turns high level IR nodes into
+lower level one, for example substituting comparisons to RuntimeNodes
+and inlining finally blocks.
+
+Lower is also responsible for determining control flow information
+like end points.
+
+
+* attr
+
+The lowering annotates a FunctionNode with symbols for each identifier
+and transforms high level constructs into lower level ones, that the
+CodeGenerator consumes.
+
+Lower logging typically outputs things like post pass actions,
+insertions of casts because symbol types have been changed and type
+specialization information. Currently very little info is generated by
+this logger. This will probably change.
+
+
+* finalize
+
+This --log=finalize log option outputs information for type finalization,
+the third tier of the compiler. This means things like placement of 
+specialized scope nodes or explicit conversions. 
+
+
+* fields
+
+The --log=fields option (at info level) is equivalent to setting the
+system variable "nashorn.fields.debug" to true. At the info level it
+will only show info about type assumptions that were invalidated. If
+the level is set to finest, it will also trace every AccessorProperty
+getter and setter in the program, show arguments, return values
+etc. It will also show the internal representation of respective field
+(Object in the normal case, unless running with the dual field
+representation)
diff --git a/nashorn/docs/JavaScriptingProgrammersGuide.html b/nashorn/docs/JavaScriptingProgrammersGuide.html
new file mode 100644
index 0000000..cf24814
--- /dev/null
+++ b/nashorn/docs/JavaScriptingProgrammersGuide.html
@@ -0,0 +1,751 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html class=" regenabled  gecko radius jsenabled regloaded" xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+<title>Java Scripting Programmer's Guide</title>
+
+<!-- ============ -->
+<!-- MAIN CONTENT -->
+<!-- ============ -->
+<table summary="layout" border="0" width="100%">
+<tbody><tr>
+<td>
+
+<div id="sharepage" class="smallpagetitle"><h1>Java Scripting Programmer's Guide</h1><div class="sharepage">		<div class="sharepagew1 share-mailto">		<table summary="" cellpadding="0" cellspacing="0"><tbody><tr>		<td id="share-mailto"><a href="mailto:?subject=Java%20Documentation%20Page:%20Java%20Scripting%20Programmer%27s%20Guide&amp;body=Check%20out%20this%20page:%20%0A%0Ahttp%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html" class="sharelink mailto" title="Email this page to a friend"></a></td>		<td id="share-technorati"><a href="http://technorati.com/search/http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html" class="sharelink technorati" title="See who links to this page on Technorati"></a></td>		<td id="share-delicious"><a href="http://del.icio.us/post?v=4;url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html;title=Java%20Scripting%20Programmer%27s%20Guide" class="sharelink delicious" title="Bookmark this page in del.icio.us"></a></td>		<td id="share-digg"><a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html&amp;title=Java%20Scripting%20Programmer%27s%20Guide" class="sharelink digg" title="Submit this page to Digg"></a></td>		<td id="share-slashdot"><a href="http://slashdot.org/bookmark.pl?title=Java%20Scripting%20Programmer%27s%20Guide&amp;url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html" class="sharelink slashdot" title="Submit this page to Slashdot"></a></td>		<td id="share-blank"> </td></tr></tbody></table></div></div></div>
+
+</td>
+</tr>
+</tbody></table>
+<!-- Body text begins here -->
+<ul>
+<li><span><a href="#who">Who is the Java Scripting API
+For?</a></span></li>
+<li><span><a href="#package">Scripting Package</a></span></li>
+<li><span><a href="#examples">Examples</a></span>
+<ul>
+<li><span><a href="#helloworld">"Hello, World"</a></span></li>
+<li><span><a href="#evalfile">Evaluating a Script
+File</a></span></li>
+<li><span><a href="#scriptvars">Script Variables</a></span></li>
+<li><span><a href="#invoke">Invoking Script Functions and
+Methods</a></span></li>
+<li><span><a href="#interfaces">Implementing Java Interfaces by
+Scripts</a></span></li>
+<li><span><a href="#scopes">Multiple Scopes for
+Scripts</a></span></li>
+</ul>
+</li>
+<li><span><a href="#jsengine">JavaScript Script
+Engine</a></span></li>
+<li><span><a href="#jstojava">JavaScript to Java
+Communication</a></span>
+<ul>
+<li><span><a href="#jsjavaclass">Accessing Java
+Classes</a></span></li>
+<li><span><a href="#jsimport">Importing Java Packages,
+Classes</a></span></li>
+<li><span><a href="#jsarrays">Creating, Converting and Using Java
+Arrays</a></span></li>
+<li><span><a href="#jsimplement">Implementing Java
+Interfaces</a></span></li>
+<li><span><a href="#jsextend">Extending Java classes
+</a></span></li>
+<li><span><a href="#jsoverload">Overload Resolution</a></span></li>
+</ul>
+</li>
+<li><span><a href="#engineimpl">Implementing Your Own Script
+Engine</a></span></li>
+<li><span><a href="#refs">References</a></span></li>
+</ul>
+<span><a name="who" id="who"></a></span>
+<h2><span>Who is the Java Scripting API For?</span></h2>
+<span>Some useful characteristics of scripting languages
+are:</span>
+<ul>
+<li><span><b>Convenience</b>: Most scripting languages are
+dynamically typed. You can usually create new variables without
+declaring the variable type, and you can reuse variables to store
+objects of different types. Also, scripting languages tend to
+perform many type conversions automatically, for example,
+converting the number 10 to the text "10" as necessary.</span></li>
+<li><span><b>Developing rapid prototypes</b>: You can avoid the
+edit-compile-run cycle and just use edit-run!</span></li>
+<li><span><b>Application extension/customization</b>: You can
+"externalize" parts of your application - like configuration
+scripts, business logic/rules and math expressions for financial
+applications.</span></li>
+<li><span><b>"Command line" shells for applications</b> -for
+debugging, runtime/deploy time configuration etc. Most applications
+have a web-based GUI configuaration tool these days. But
+sysadmins/deployers frequently prefer command line tools. Instead
+of inventing ad-hoc scripting language for that purpose, a
+"standard" scripting language can be used.</span></li>
+</ul>
+<p><span>The Java<font size="-1"><sup>TM</sup></font> Scripting API
+is a scripting language indepedent framework for using script
+engines from Java code. With the Java Scripting API, it is possible
+to write customizable/extendable applications in the Java language
+and leave the customization scripting language choice to the end
+user. The Java application developer need not choose the extension
+language during development. If you write your application with
+JSR-223 API, then your users can use any JSR-223 compliant
+scripting language.</span></p>
+<hr>
+<span><a name="package" id="package"></a></span>
+<h2><span>Scripting Package</span></h2>
+<p><span>The Java Scripting functionality is in the <code><a href="http://docs.oracle.com/javase/6/docs/api/javax/script/package-summary.html">javax.script</a></code>
+package. This is a relatively small, simple API. The starting point
+of the scripting API is the <code>ScriptEngineManager</code> class.
+A ScriptEngineManager object can discover script engines through
+the jar file service discovery mechanism. It can also instantiate
+ScriptEngine objects that interpret scripts written in a specific
+scripting language. The simplest way to use the scripting API is as
+follows:</span></p>
+<ol>
+<li><span>Create a <code>ScriptEngineManager</code>
+object.</span></li>
+<li><span>Get a <code>ScriptEngine</code> object from the
+manager.</span></li>
+<li><span>Evaluate script using the <code>ScriptEngine</code>'s
+<code>eval</code> methods.</span></li>
+</ol>
+<p><span>Now, it is time to look at some sample code. While it is
+not mandatory, it may be useful to know a bit of JavaScript to read
+these examples.</span></p>
+<hr>
+<span><a name="examples" id="examples"></a></span>
+<h2><span>Examples</span></h2>
+<span><a name="helloworld" id="helloworld"></a></span>
+<h3><span>"Hello, World"</span></h3>
+<p><span>From the <code>ScriptEngineManager</code> instance, we
+request a JavaScript engine instance using
+<code>getEngineByName</code> method. On the script engine, the
+<code>eval</code> method is called to execute a given String as
+JavaScript code! For brevity, in this as well as in subsequent
+examples, we have not shown exception handling. There are checked
+and runtime exceptions thrown from <code>javax.script</code> API.
+Needless to say, you have to handle the exceptions
+appropriately.</span></p>
+<pre>
+<span><code>
+// <a href="source/EvalScript.java">EvalScript.java</a>
+
+import javax.script.*;
+public class EvalScript {
+    public static void main(String[] args) throws Exception {
+        // create a script engine manager
+        <span class="classref">ScriptEngineManager</span> factory = new ScriptEngineManager();
+        // create a JavaScript engine
+        <span class="classref">ScriptEngine</span> engine = factory.<span class="methodref">getEngineByName</span>("nashorn");
+        // evaluate JavaScript code from String
+        engine.<span class="methodref">eval</span>("print('Hello, World')");
+    }
+}
+</code></span>
+</pre>
+<hr>
+<a name="evalfile" id="evalfile"></a>
+<h3>Evaluating a Script File</h3>
+<p>In this example, we call the <code>eval</code> method that
+accepts <code>java.io.Reader</code> for the input source. The
+script read by the given reader is executed. This way it is
+possible to execute scripts from files, URLs and resources by
+wrapping the relevant input stream objects as readers.</p>
+<pre>
+<code>
+// <a href="source/EvalFile.java">EvalFile.java</a>
+
+import javax.script.*;
+
+public class EvalFile {
+    public static void main(String[] args) throws Exception {
+        // create a script engine manager
+        <span class="classref">ScriptEngineManager</span> factory = new ScriptEngineManager();
+        // create JavaScript engine
+        <span class="classref">ScriptEngine</span> engine = factory.<span class="methodref">getEngineByName</span>("nashorn");
+        // evaluate JavaScript code from given file - specified by first argument
+        engine.<span class="methodref">eval</span>(new java.io.FileReader(args[0]));
+    }
+}
+</code>
+</pre>
+Let us assume that we have the file named <a href="source/test.js">test.js</a> with the
+following text:
+<pre><code>
+print("This is hello from test.js");
+</code>
+</pre>
+We can run the above Java as
+<pre><code>
+java EvalFile test.js
+</code>
+</pre>
+<hr>
+<a name="scriptvars" id="scriptvars"></a>
+<h3>Script Variables</h3>
+<p>When you embed script engines and scripts with your Java
+application, you may want to expose your application objects as
+global variables to scripts. This example demonstrates how you can
+expose your application objects as global variables to a script. We
+create a <code>java.io.File</code> in the application and expose
+the same as a global variable with the name "file". The script can
+access the variable - for example, it can call public methods on
+it. Note that the syntax to access Java objects, methods and fields
+is dependent on the scripting language. JavaScript supports the
+most "natural" Java-like syntax.</p>
+<pre><code>
+// <a href="source/ScriptVars.java">ScriptVars.java</a>
+
+import javax.script.*;
+import java.io.*;
+
+public class ScriptVars { 
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        File f = new File("test.txt");
+        // expose File object as variable to script
+        engine.<span class="methodref">put</span>("file", f);
+
+        // evaluate a script string. The script accesses "file" 
+        // variable and calls method on it
+        engine.eval("print(file.getAbsolutePath())");
+    }
+}
+
+</code>
+</pre>
+<hr>
+<a name="invoke" id="invoke"></a>
+<h3>Invoking Script Functions and Methods</h3>
+<p>Sometimes you may want to call a specific scripting function
+repeatedly - for example, your application menu functionality might
+be implemented by a script. In your menu's action event handler you
+may want to call a specific script function. The following example
+demonstrates invoking a specific script function from Java
+code.</p>
+<pre><code>
+// <a href="source/InvokeScriptFunction.java">InvokeScriptFunction.java</a>
+
+import javax.script.*;
+
+public class InvokeScriptFunction {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        // JavaScript code in a String
+        String script = "function hello(name) { print('Hello, ' + name); }";
+        // evaluate script
+        engine.eval(script);
+
+        // <code>javax.script.Invocable</code> is an optional interface.
+        // Check whether your script engine implements it or not!
+        // Note that the JavaScript engine implements Invocable interface.
+        <span class="classref">Invocable</span> inv = (Invocable) engine;
+
+        // invoke the global function named "hello"
+        inv.<span class="methodref">invokeFunction</span>("hello", "Scripting!!" );
+    }
+}
+
+</code>
+</pre>
+<p>If your scripting language is object based (like JavaScript) or
+object-oriented, then you can invoke a script method on a script
+object.</p>
+<pre><code>
+// <a href="source/InvokeScriptMethod.java">InvokeScriptMethod.java</a>
+
+import javax.script.*;
+
+public class InvokeScriptMethod {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        // JavaScript code in a String. This code defines a script object 'obj'
+        // with one method called 'hello'.        
+        String script = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }";
+        // evaluate script
+        engine.eval(script);
+
+        // <code>javax.script.Invocable</code> is an optional interface.
+        // Check whether your script engine implements or not!
+        // Note that the JavaScript engine implements Invocable interface.
+        <span class="classref">Invocable</span> inv = (Invocable) engine;
+
+        // get script object on which we want to call the method
+        Object obj = engine.<span class="methodref">get</span>("obj");
+
+        // invoke the method named "hello" on the script object "obj"
+        inv.<span class="methodref">invokeMethod</span>(obj, "hello", "Script Method !!" );
+    }
+}
+
+</code>
+</pre>
+<hr>
+<a name="interfaces" id="interfaces"></a>
+<h3>Implementing Java Interfaces by Scripts</h3>
+<p>Instead of calling specific script functions from Java,
+sometimes it is convenient to implement a Java interface by script
+functions or methods. Also, by using interfaces we can avoid having
+to use the <code>javax.script</code> API in many places. We can get
+an interface implementor object and pass it to various Java APIs.
+The following example demonstrates implementing the
+<code>java.lang.Runnable</code> interface with a script.</p>
+<pre><code>
+// <a href="source/RunnableImpl.java">RunnableImpl.java</a>
+
+import javax.script.*;
+
+public class RunnableImpl {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        // JavaScript code in a String
+        String script = "function run() { print('run called'); }";
+
+        // evaluate script
+        engine.eval(script);
+
+        <span class="classref">Invocable</span> inv = (Invocable) engine;
+
+        // get Runnable interface object from engine. This interface methods
+        // are implemented by script functions with the matching name.
+        Runnable r = inv.<span class="methodref">getInterface</span>(Runnable.class);
+
+        // start a new thread that runs the script implemented
+        // runnable interface
+        Thread th = new Thread(r);
+        th.start();
+        th.join();
+    }
+}
+</code>
+</pre>
+<p>If your scripting language is object-based or object-oriented,
+it is possible to implement a Java interface by script methods on
+script objects. This avoids having to call script global functions
+for interface methods. The script object can store the "state"
+associated with the interface implementor.</p>
+<pre><code>
+// <a href="source/RunnableImplObject.java">RunnableImplObject.java</a>
+
+import javax.script.*;
+
+public class RunnableImplObject {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        // JavaScript code in a String
+        String script = "var obj = new Object(); obj.run = function() { print('run method called'); }";
+
+        // evaluate script
+        engine.eval(script);
+
+        // get script object on which we want to implement the interface with
+        Object obj = engine.<span class="methodref">get</span>("obj");
+
+        <span class="classref">Invocable</span> inv = (Invocable) engine;
+
+        // get Runnable interface object from engine. This interface methods
+        // are implemented by script methods of object 'obj'
+        Runnable r = inv.<span class="methodref">getInterface</span>(obj, Runnable.class);
+
+        // start a new thread that runs the script implemented
+        // runnable interface
+        Thread th = new Thread(r);
+        th.start();
+        th.join();
+    }
+}
+</code>
+</pre>
+<hr>
+<a name="scopes" id="scopes"></a>
+<h3>Multiple Scopes for Scripts</h3>
+<p>In the <a href="#scriptvars">script variables</a> example, we
+saw how to expose application objects as script global variables.
+It is possible to expose multiple global "scopes" for scripts. A
+single scope is an instance of <code>javax.script.Bindings</code>.
+This interface is derived from <code>java.util.Map&lt;String,
+Object&gt;</code>. A scope a set of name-value pairs where name is
+any non-empty, non-null String.
+<code>javax.script.ScriptContext</code> interface supports multiple
+scopes with associated Bindings for each
+scope. By default, every script engine has a default script
+context. The default script context has atleast one scope called
+"ENGINE_SCOPE". Various scopes supported by a script context are
+available through <code>getScopes</code> method.</p>
+<pre><code>
+// <a href="source/MultiScopes.java">MultiScopes.java</a>
+
+import javax.script.*;
+
+public class MultiScopes {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        engine.put("x", "hello");
+        // print global variable "x"
+        engine.eval("print(x);");
+        // the above line prints "hello"
+
+        // Now, pass a different script context
+        <span class="classref">ScriptContext</span> newContext = new <span class="classref">SimpleScriptContext</span>();
+        newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
+        <span class="classref">Bindings</span> engineScope = newContext.<span class="methodref">getBindings</span>(ScriptContext.ENGINE_SCOPE);
+
+        // add new variable "x" to the new engineScope        
+        engineScope.<span class="methodref">put</span>("x", "world");
+
+        // execute the same script - but this time pass a different script context
+        engine.eval("print(x);", newContext);
+        // the above line prints "world"
+    }
+}
+
+</code>
+</pre>
+<hr>
+<a name="jsengine" id="jsengine"></a>
+<h2>JavaScript Script Engine</h2>
+<p>Oracle's implementation of JDK 8 is co-bundled with the Nashorn ECMAScript
+script engine.
+<hr>
+<a name="jstojava" id="jstojava"></a>
+<h2>JavaScript to Java Communication</h2>
+<p>For the most part, accessing Java classes, objects and methods
+is straightforward. In particular field and method access from
+JavaScript is the same as it is from Java. We highlight important
+aspects of JavaScript Java access here. 
+The following examples are JavaScript snippets accessing Java. This
+section requires knowledge of JavaScript. This section can be
+skipped if you are planning to use some other JSR-223 scripting
+language rather than JavaScript.</p>
+<hr>
+<a name="jsjavaclass" id=jsjavalass"></a>
+<h3>Accessing Java Classes</h3>
+<pre>
+<code>
+// <a href="source/javatypes.js">javatypes.js</a>
+
+ var arrayListType = Java.type("java.util.ArrayList")
+ var intType = Java.type("int")
+ var stringArrayType = Java.type("java.lang.String[]")
+ var int2DArrayType = Java.type("int[][]")
+</code>
+</pre> 
+
+Note that the name of the type is always a string for a fully qualified name. You can use any of these types to create new instances, e.g.:
+
+<pre><code>
+ var anArrayList = new Java.type("java.util.ArrayList")
+</code></pre> 
+
+or
+
+<pre><code>
+ var ArrayList = Java.type("java.util.ArrayList")
+ var anArrayList = new ArrayList
+ var anArrayListWithSize = new ArrayList(16)
+</code></pre> 
+
+In the special case of inner classes, you need to use the JVM fully qualified name, meaning using $ sign in the class name:
+
+<pre><code>
+ var ftype = Java.type("java.awt.geom.Arc2D$Float")
+</code></pre> 
+ 
+
+However, once you retrieved the outer class, you can access the inner class as a property on it:
+
+<pre><code>
+ var arctype = Java.type("java.awt.geom.Arc2D")
+ var ftype = arctype.Float
+</code></pre> 
+<p>
+You can access both static and non-static inner classes. If you want to create an instance of a non-static inner class, remember to pass an instance of its outer class as the first argument to the constructor.
+</p>
+<hr>
+<a name="jsimport" id="jsimport"></a>
+<h3>Importing Java Packages, Classes</h3>
+<p>The built-in functions <code>importPackage</code> (in compatibility script) and
+<code>importClass</code> can be used to import Java packages and
+classes.</p>
+<pre><code>
+
+// <a href="source/importpackageclass.js">importpackageclass.js</a>
+
+// load compatibility script
+load("nashorn:mozilla_compat.js");
+// Import Java packages and classes 
+// like import package.*; in Java
+<span class="functionref">importPackage</span>(java.awt);
+// like import java.awt.Frame in Java
+<span class="functionref">importClass</span>(java.awt.Frame);
+// Create Java Objects by "new ClassName"
+var frame = new java.awt.Frame("hello");
+// Call Java public methods from script
+frame.setVisible(true);
+// Access "JavaBean" properties like "fields"
+print(frame.title);
+</code>
+</pre>
+<p>The <span class="objectref">Packages</span> global variable can
+be used to access Java packages. Examples:
+<code>Packages.java.util.Vector</code>,
+<code>Packages.javax.swing.JFrame</code>. Please note that "java"
+is a shortcut for "Packages.java". There are equivalent shortcuts
+for javax, org, edu, com, net prefixes, so pratically all JDK
+platform classes can be accessed without the "Packages" prefix.</p>
+<p>Note that java.lang is not imported by default (unlike Java)
+because that would result in conflicts with JavaScript's built-in
+Object, Boolean, Math and so on.</p>
+<p><code>importPackage</code> and <code>importClass</code>
+functions "pollute" the global variable scope of JavaScript. To
+avoid that, you may use <span class="functionref">JavaImporter</span>.</p>
+<pre><code>
+
+// <a href="source/javaimporter.js">javaimporter.js</a>
+
+// create JavaImporter with specific packages and classes to import
+
+var SwingGui = new <span class="functionref">JavaImporter</span>(javax.swing,
+                            javax.swing.event,
+                            javax.swing.border,
+                            java.awt.event);
+with (SwingGui) {
+    // within this 'with' statement, we can access Swing and AWT
+    // classes by unqualified (simple) names.
+
+    var mybutton = new JButton("test");
+    var myframe = new JFrame("test");
+}
+
+</code>
+</pre>
+<hr>
+<a name="jsarrays" id="jsarrays"></a>
+<h3>Creating, Converting and Using Java Arrays</h3>
+<p>While creating a Java object is the same as in Java, to create
+Java arrays in JavaScript we can use Java reflection
+explicitly. But once created the element access or length access is
+the same as in Java. Also, a script array can be used when a Java
+method expects a Java array (auto conversion). So in most cases we
+don't have to create Java arrays explicitly.</p>
+<pre><code>
+// <a href="source/javaarray.js">javaarray.js</a>
+
+// create Java String array of 5 elements
+var a = java.lang.reflect.Array.newInstance(java.lang.String.class, 5);
+
+// Accessing elements and length access is by usual Java syntax
+a[0] = "scripting is great!";
+print(a.length);
+print(a[0]);
+</code>
+</pre>
+<p>
+It is also possible to convert between JavaScript and Java arrays.
+Given a JavaScript array and a Java type, <code>Java.toJavaArray</code> returns a Java array with the same initial contents, and with the specified component type. 
+</p>
+<pre><code>
+ var anArray = [1, "13", false]
+ var javaIntArray = Java.toJavaArray(anArray, "int")
+ print(javaIntArray[0]) // prints 1
+ print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
+ print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
+</code></pre>
+<p>
+Given a Java array or Collection, <code>Java.toJavaScriptArray</code> returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.i
+</p>
+<pre><code>
+var File = Java.type("java.io.File");
+var listCurDir = new File(".").listFiles();
+var jsList = Java.toJavaScriptArray(listCurDir);
+print(jsList);
+</code></pre>
+<hr>
+<a name="jsimplement" id="jsimplement"></a>
+<h3>Implementing Java Interfaces</h3>
+<p>A Java interface can be implemented in JavaScript by using a
+Java anonymous class-like syntax:</p>
+<pre><code>
+// <a href="source/runnable.js">runnable.js</a>
+
+var r  = new java.lang.Runnable() {
+    run: function() {
+        print("running...\n");
+    }
+};
+
+// "r" can be passed to Java methods that expect java.lang.Runnable
+var th = new java.lang.Thread(r);
+th.start();
+th.join();
+</code>
+</pre>
+<p>When an interface with a single method is expected, you can pass
+a script function directly.(auto conversion)</p>
+<pre><code>
+// <a href="source/samfunc.js">samfunc.js</a>
+
+function func() {
+     print("I am func!");
+}
+
+// pass script function for java.lang.Runnable argument
+var th = new java.lang.Thread(func);
+th.start();
+th.join();
+</code>
+</pre>
+<hr>
+<a name="jsextend" id="jsextend"></a>
+<h3>Extending Java classes</h3>
+<p>
+If a Java class is abstract, you can instantiate an anonymous subclass of it using an argument list that is applicable to any of its public or protected constructors, but inserting a JavaScript object with functions properties that provide JavaScript implementations of the abstract methods. If method names are overloaded, the JavaScript function will provide implementation for all overloads. E.g.:
+</p>
+
+<pre><code>
+ var TimerTask =  Java.type("java.util.TimerTask")
+ var task = new TimerTask({ run: function() { print("Hello World!") } })
+</code></pre>
+
+Nashorn supports a syntactic extension where a "new" expression followed by an argument is identical to invoking the constructor and passing the argument to it, so you can write the above example also as:
+
+<pre><code>
+ var task = new TimerTask {
+     run: function() {
+       print("Hello World!")
+     }
+ }
+</code></pre>
+
+which is very similar to Java anonymous inner class definition. On the other hand, if the type is an abstract type with a single abstract method (commonly referred to as a "SAM type") or all abstract methods it has share the same overloaded name), then instead of an object, you can just pass a function, so the above example can become even more simplified to:
+
+<pre><code>
+ var task = new TimerTask(function() { print("Hello World!") })
+</code></pre>
+
+<p>
+Note that in every one of these cases if you are trying to instantiate an abstract class that has constructors that take some arguments, you can invoke those simply by specifying the arguments after the initial implementation object or function.
+</p>
+<p>
+The use of functions can be taken even further; if you are invoking a Java method that takes a SAM type, you can just pass in a function object, and Nashorn will know what you meant:
+</p>
+<code><pre>
+ Java.type("java.util.Timer")
+ timer.schedule(function() { print("Hello World!") })
+</code></pre>
+
+Here, <code>Timer.schedule()</code> expects a <code>TimerTask</code> as its argument, so Nashorn creates an instance of a TimerTask subclass and uses the passed function to implement its only abstract method, run(). In this usage though, you can't use non-default constructors; the type must be either an interface, or must have a protected or public no-arg constructor.
+
+<p>
+To extend a concrete Java class, you have to use <code>Java.extend</code> function.
+<code>Java.extend</code> returns a type object for a subclass of the specified Java class (or implementation of the specified interface) that acts as a script-to-Java adapter for it.  
+</p>
+<pre><code>
+// <a href="source/javaextend.js">javaextend.js</a>
+
+var ArrayList = Java.type("java.util.ArrayList")
+var ArrayListExtender = Java.extend(ArrayList)
+var printSizeInvokedArrayList = new ArrayListExtender() {
+    size: function() { print("size invoked!"); }
+}
+var printAddInvokedArrayList = new ArrayListExtender() {
+    add: function(x, y) {
+        if(typeof(y) === "undefined") {
+            print("add(e) invoked!");
+        } else {
+            print("add(i, e) invoked!");
+        }
+    }
+};
+printSizeInvokedArrayList.size();
+printAddInvokedArrayList.add(33, 33);
+</code></pre>
+<hr>
+<a name="jsoverload" id="jsoverload"></a>
+<h3>Overload Resolution</h3>
+<p>Java methods can be overloaded by argument types. In Java,
+overload resolution occurs at compile time (performed by javac).
+When calling Java methods from a script, the script
+interpreter/compiler needs to select the appropriate method. With
+the JavaScript engine, you do not need to do anything special - the
+correct Java method overload variant is selected based on the
+argument types. But, sometimes you may want (or have) to explicitly
+select a particular overload variant.</p>
+<pre><code>
+// <a href="source/overload.js">overload.js</a>
+
+var out = java.lang.System.out;
+
+// select a particular print function 
+out["println(java.lang.Object)"]("hello");
+</code>
+</pre>
+<hr>
+<a name="engineimpl" id="engineimpl"></a>
+<h2>Implementing Your Own Script Engine</h2>
+<p>We will not cover implementation of JSR-223 compliant script
+engines in detail. Minimally, you need to implement the
+<code>javax.script.ScriptEngine</code> and
+<code>javax.script.ScriptEngineFactory</code> interfaces. The
+abstract class <code>javax.script.AbstractScriptEngine</code>
+provides useful defaults for a few methods of the
+<code>ScriptEngine</code> interface.</p>
+<p>Before starting to implement a JSR-223 engine, you may want to
+check <a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting</a>
+project. This project maintains JSR-223 implementations for many
+popular open source scripting languages.</p>
+<hr>
+<a name="refs" id="refs"></a>
+<h2>References</h2>
+<ul>
+<li><a href="http://jcp.org/en/jsr/detail?id=223">JSR-223 Scripting
+for the Java Platform</a></li>
+<li><a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting
+</a></li>
+</ul>
+
+
+
+<div class="hr"><hr></div>
+<table summary="layout" border="0" width="100%">
+<tbody><tr valign="TOP">
+<td width="30%"> <img src="Java%20Scripting%20Programmer%27s%20Guide_files/logo_oracle_footer.gif" alt="Oracle and/or its affiliates" border="0" height="29" width="100"><br>
+<font size="+1"> <i>Java Technology</i></font> </td>
+
+<td width="30%">
+<p><font size="-2">
+<a href="http://docs.oracle.com/javase/6/docs/legal/cpyr.html">Copyright ©</a> 2013, Oracle and/or its affiliates. All rights reserved.
+</font></p> 
+</td>
+<td width="30%">
+<p align="right"><font size="-2"><a href="http://download.oracle.com/javase/feedback.html">Contact Us</a></font></p><font size="-2">
+</font></td>
+</tr>
+</tbody></table> 
+<div class="hr"><hr></div>
+</div>
+
+<!-- Start SiteCatalyst code   -->
+<script language="JavaScript" src="Java%20Scripting%20Programmer%27s%20Guide_files/s_code_download.js"></script>
+<script language="JavaScript" src="Java%20Scripting%20Programmer%27s%20Guide_files/s_code.js"></script>
+ 
+<!-- ********** DO NOT ALTER ANYTHING BELOW THIS LINE ! *********** -->
+<!--  Below code will send the info to Omniture server -->
+<script language="javascript">var s_code=s.t();if(s_code)document.write(s_code)</script>
+ 
+<!-- End SiteCatalyst code -->
+
+
+
+</body></html>
diff --git a/nashorn/docs/genshelldoc.js b/nashorn/docs/genshelldoc.js
new file mode 100644
index 0000000..3d11a47
--- /dev/null
+++ b/nashorn/docs/genshelldoc.js
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+/**
+ * Generate HTML documentation for shell tool. Re-run this tool to regenerate
+ * html doc when you change options.
+ *
+ * Usage:
+ *
+ *     jjs -scripting genshelldoc.js > shell.html
+ */
+
+var Options = Packages.jdk.nashorn.internal.runtime.options.Options;
+var title = "Nashorn command line shell tool";
+
+print(<<PREFIX
+<html>
+<head>
+<title>
+${title}
+</title>
+</head>
+<body>
+<h1>Usage</h1>
+<p>
+<code>
+<b>jjs &lt;options&gt; &lt;script-files&gt; [ -- &lt;script-arguments&gt; ]</b>
+</code>
+</p>
+
+<h1>${title} options</h1>
+
+<table border="0">
+<tr>
+<th>name</th>
+<th>type</th>
+<th>default</th>
+<th>description</th>
+</tr>
+PREFIX);
+
+for each (opt in Options.validOptions) {
+
+var isTimezone = (opt.type == "timezone");   
+var defValue = opt.defaultValue;
+if (defValue == null) {
+    defValue = "&lt;none&gt;";
+}
+
+if (isTimezone) {
+    // don't output current user's timezone
+    defValue = "&lt;default-timezone&gt;"
+}
+
+print(<<ROW
+  <tr>
+  <td><b>${opt.name} ${opt.shortName == null? "" : opt.shortName}</b></td>
+  <td>${opt.type}</td>
+  <td>${defValue}</td>
+  <td>${opt.description}</td>
+  </tr>
+ROW);
+
+}
+
+print(<<SUFFIX
+</table>
+</body>
+</html>
+SUFFIX);
diff --git a/nashorn/docs/source/EvalFile.java b/nashorn/docs/source/EvalFile.java
new file mode 100644
index 0000000..6bb4e38
--- /dev/null
+++ b/nashorn/docs/source/EvalFile.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.script.*;
+
+public class EvalFile {
+    public static void main(String[] args) throws Exception {
+        // create a script engine manager
+        ScriptEngineManager factory = new ScriptEngineManager();
+        // create JavaScript engine
+        ScriptEngine engine = factory.getEngineByName("nashorn");
+        // evaluate JavaScript code from given file - specified by first argument
+        engine.eval(new java.io.FileReader(args[0]));
+    }
+}
+
diff --git a/nashorn/docs/source/EvalScript.java b/nashorn/docs/source/EvalScript.java
new file mode 100644
index 0000000..7fcbe1c
--- /dev/null
+++ b/nashorn/docs/source/EvalScript.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.script.*;
+
+public class EvalScript {
+    public static void main(String[] args) throws Exception {
+        // create a script engine manager
+        ScriptEngineManager factory = new ScriptEngineManager();
+        // create a JavaScript engine
+        ScriptEngine engine = factory.getEngineByName("nashorn");
+        // evaluate JavaScript code from String
+        engine.eval("print('Hello, World')");
+    }
+}
+
diff --git a/nashorn/docs/source/InvokeScriptFunction.java b/nashorn/docs/source/InvokeScriptFunction.java
new file mode 100644
index 0000000..26de36c
--- /dev/null
+++ b/nashorn/docs/source/InvokeScriptFunction.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.script.*;
+
+public class InvokeScriptFunction {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        // JavaScript code in a String
+        String script = "function hello(name) { print('Hello, ' + name); }";
+        // evaluate script
+        engine.eval(script);
+
+        // javax.script.Invocable is an optional interface.
+        // Check whether your script engine implements or not!
+        // Note that the JavaScript engine implements Invocable interface.
+        Invocable inv = (Invocable) engine;
+
+        // invoke the global function named "hello"
+        inv.invokeFunction("hello", "Scripting!!" );
+    }
+}
+
+
+
diff --git a/nashorn/docs/source/InvokeScriptMethod.java b/nashorn/docs/source/InvokeScriptMethod.java
new file mode 100644
index 0000000..a3f5ece
--- /dev/null
+++ b/nashorn/docs/source/InvokeScriptMethod.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.script.*;
+
+public class InvokeScriptMethod {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        // JavaScript code in a String. This code defines a script object 'obj'
+        // with one method called 'hello'.
+        String script = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }";
+        // evaluate script
+        engine.eval(script);
+
+        // javax.script.Invocable is an optional interface.
+        // Check whether your script engine implements or not!
+        // Note that the JavaScript engine implements Invocable interface.
+        Invocable inv = (Invocable) engine;
+
+        // get script object on which we want to call the method
+        Object obj = engine.get("obj");
+
+        // invoke the method named "hello" on the script object "obj"
+        inv.invokeMethod(obj, "hello", "Script Method !!" );
+    }
+}
diff --git a/nashorn/docs/source/MultiScopes.java b/nashorn/docs/source/MultiScopes.java
new file mode 100644
index 0000000..6c4fa2a
--- /dev/null
+++ b/nashorn/docs/source/MultiScopes.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.script.*;
+
+public class MultiScopes {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        engine.put("x", "hello");
+        // print global variable "x"
+        engine.eval("print(x);");
+        // the above line prints "hello"
+
+        // Now, pass a different script context
+        ScriptContext newContext = new SimpleScriptContext();
+        newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
+        Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
+
+        // add new variable "x" to the new engineScope
+        engineScope.put("x", "world");
+
+        // execute the same script - but this time pass a different script context
+        engine.eval("print(x);", newContext);
+        // the above line prints "world"
+    }
+}
+
+
diff --git a/nashorn/docs/source/RunnableImpl.java b/nashorn/docs/source/RunnableImpl.java
new file mode 100644
index 0000000..1d858d4
--- /dev/null
+++ b/nashorn/docs/source/RunnableImpl.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.script.*;
+
+public class RunnableImpl {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        // JavaScript code in a String
+        String script = "function run() { print('run called'); }";
+
+        // evaluate script
+        engine.eval(script);
+
+        Invocable inv = (Invocable) engine;
+
+        // get Runnable interface object from engine. This interface methods
+        // are implemented by script functions with the matching name.
+        Runnable r = inv.getInterface(Runnable.class);
+
+        // start a new thread that runs the script implemented
+        // runnable interface
+        Thread th = new Thread(r);
+        th.start();
+        th.join();
+    }
+}
diff --git a/nashorn/docs/source/RunnableImplObject.java b/nashorn/docs/source/RunnableImplObject.java
new file mode 100644
index 0000000..877f8c1
--- /dev/null
+++ b/nashorn/docs/source/RunnableImplObject.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.script.*;
+
+public class RunnableImplObject {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        // JavaScript code in a String
+        String script = "var obj = new Object(); obj.run = function() { print('run method called'); }";
+
+        // evaluate script
+        engine.eval(script);
+
+        // get script object on which we want to implement the interface with
+        Object obj = engine.get("obj");
+
+        Invocable inv = (Invocable) engine;
+
+        // get Runnable interface object from engine. This interface methods
+        // are implemented by script methods of object 'obj'
+        Runnable r = inv.getInterface(obj, Runnable.class);
+
+        // start a new thread that runs the script implemented
+        // runnable interface
+        Thread th = new Thread(r);
+        th.start();
+        th.join();
+    }
+}
diff --git a/nashorn/docs/source/ScriptVars.java b/nashorn/docs/source/ScriptVars.java
new file mode 100644
index 0000000..7e16cfc
--- /dev/null
+++ b/nashorn/docs/source/ScriptVars.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.script.*;
+import java.io.*;
+
+public class ScriptVars {
+    public static void main(String[] args) throws Exception {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("nashorn");
+
+        File f = new File("test.txt");
+        // expose File object as variable to script
+        engine.put("file", f);
+
+        // evaluate a script string. The script accesses "file"
+        // variable and calls method on it
+        engine.eval("print(file.getAbsolutePath())");
+    }
+}
+
+
+
diff --git a/nashorn/docs/source/importpackageclass.js b/nashorn/docs/source/importpackageclass.js
new file mode 100644
index 0000000..afc02a9
--- /dev/null
+++ b/nashorn/docs/source/importpackageclass.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// load compatibility script
+load("nashorn:mozilla_compat.js");
+
+// Import Java packages and classes 
+// like import package.*; in Java
+importPackage(java.awt);
+// like import java.awt.Frame in Java
+importClass(java.awt.Frame);
+// Create Java Objects by "new ClassName"
+var frame = new java.awt.Frame("hello");
+// Call Java public methods from script
+frame.setVisible(true);
+// Access "JavaBean" properties like "fields"
+print(frame.title);
diff --git a/nashorn/docs/source/javaarray.js b/nashorn/docs/source/javaarray.js
new file mode 100644
index 0000000..b9d93f0
--- /dev/null
+++ b/nashorn/docs/source/javaarray.js
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// create Java String array of 5 elements
+var a = java.lang.reflect.Array.newInstance(java.lang.String.class, 5);
+
+// Accessing elements and length access is by usual Java syntax
+a[0] = "scripting is great!";
+print(a.length);
+print(a[0]);
+
+// convert a script array to Java array
+var anArray = [1, "13", false];
+var javaIntArray = Java.toJavaArray(anArray, "int");
+print(javaIntArray[0]);// prints 1
+print(javaIntArray[1]); // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
+print(javaIntArray[2]);// prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
+
+// convert a Java array to a JavaScript array
+var File = Java.type("java.io.File");
+var listCurDir = new File(".").listFiles();
+var jsList = Java.toJavaScriptArray(listCurDir);
+print(jsList);
diff --git a/nashorn/docs/source/javaextend.js b/nashorn/docs/source/javaextend.js
new file mode 100644
index 0000000..408da32
--- /dev/null
+++ b/nashorn/docs/source/javaextend.js
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+var ArrayList = Java.type("java.util.ArrayList")
+var ArrayListExtender = Java.extend(ArrayList)
+var printSizeInvokedArrayList = new ArrayListExtender() {
+    size: function() { print("size invoked!"); }
+}
+var printAddInvokedArrayList = new ArrayListExtender() {
+    add: function(x, y) {
+        if(typeof(y) === "undefined") {
+            print("add(e) invoked!");
+        } else {
+            print("add(i, e) invoked!");
+        }
+    }
+};
+printSizeInvokedArrayList.size();
+printAddInvokedArrayList.add(33, 33);
diff --git a/nashorn/docs/source/javaimporter.js b/nashorn/docs/source/javaimporter.js
new file mode 100644
index 0000000..3bd0798
--- /dev/null
+++ b/nashorn/docs/source/javaimporter.js
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// create JavaImporter with specific packages and classes to import
+
+var SwingGui = new JavaImporter(javax.swing,
+                            javax.swing.event,
+                            javax.swing.border,
+                            java.awt.event);
+with (SwingGui) {
+    // within this 'with' statement, we can access Swing and AWT
+    // classes by unqualified (simple) names.
+
+    var mybutton = new JButton("test");
+    print(mybutton);
+    var myframe = new JFrame("test");
+    print(myframe);
+}
+
+
diff --git a/nashorn/docs/source/javatypes.js b/nashorn/docs/source/javatypes.js
new file mode 100644
index 0000000..e0b6f07
--- /dev/null
+++ b/nashorn/docs/source/javatypes.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+// accessing java types
+var arrayListType = Java.type("java.util.ArrayList")
+var intType = Java.type("int")
+var stringArrayType = Java.type("java.lang.String[]")
+var int2DArrayType = Java.type("int[][]")
+
+// Using java types
+var ArrayList = Java.type("java.util.ArrayList")
+var anArrayList = new ArrayList
+var anArrayListWithSize = new ArrayList(16)
+
+// fully qualified name
+var ftype = Java.type("java.awt.geom.Arc2D$Float")
+
+// inner class property
+var arctype = Java.type("java.awt.geom.Arc2D")
+var ftype = arctype.Float
+
diff --git a/nashorn/docs/source/overload.js b/nashorn/docs/source/overload.js
new file mode 100644
index 0000000..2407d0c
--- /dev/null
+++ b/nashorn/docs/source/overload.js
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+var out = java.lang.System.out;
+
+// select a particular print function 
+out["println(java.lang.Object)"]("hello");
+
diff --git a/nashorn/docs/source/runnable.js b/nashorn/docs/source/runnable.js
new file mode 100644
index 0000000..67cd31c
--- /dev/null
+++ b/nashorn/docs/source/runnable.js
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+var r  = new java.lang.Runnable() {
+    run: function() {
+        print("running...\n");
+    }
+};
+
+// "r" can be passed to Java methods that expect java.lang.Runnable
+var th = new java.lang.Thread(r);
+th.start();
+th.join();
diff --git a/nashorn/docs/source/samfunc.js b/nashorn/docs/source/samfunc.js
new file mode 100644
index 0000000..c870076
--- /dev/null
+++ b/nashorn/docs/source/samfunc.js
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function func() {
+     print("I am func!");
+}
+
+// pass script function for java.lang.Runnable argument
+var th = new java.lang.Thread(func);
+th.start();
+th.join();
diff --git a/nashorn/docs/source/test.js b/nashorn/docs/source/test.js
new file mode 100644
index 0000000..6323c38
--- /dev/null
+++ b/nashorn/docs/source/test.js
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+print("This is hello from test.js");
diff --git a/nashorn/make/Makefile b/nashorn/make/Makefile
new file mode 100644
index 0000000..443f8db
--- /dev/null
+++ b/nashorn/make/Makefile
@@ -0,0 +1,59 @@
+#
+# 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.
+#
+
+#
+# On Solaris, the standard 'make' utility will not work with these makefiles.
+#    This little rule is only understood by Solaris make, and is harmless
+#    when seen by the GNU make tool. If using Solaris make, this causes the
+#    make command to fail.
+#
+SUN_MAKE_TEST:sh = @echo "ERROR: PLEASE USE GNU VERSION OF MAKE"; exit 33
+
+
+# Default target and expected 'do everything' target
+all:
+	echo Nashorn can only be built with NEWBUILD=true
+
+# Standard make clobber target
+clobber:
+
+#-------------------------------------------------------------------
+#
+# Targets for Oracle's internal JPRT build system
+
+CD = cd
+ZIP = zip
+
+JPRT_ARCHIVE_BUNDLE=$(ABS_OUTPUTDIR)/$(JPRT_BUILD_FLAVOR)-bundle.zip
+
+jprt_build_product jprt_build_debug jprt_build_fastdebug: all
+	( $(CD) $(OUTPUTDIR) && \
+	  $(ZIP) -q -r $(JPRT_ARCHIVE_BUNDLE) build dist )
+
+#-------------------------------------------------------------------
+
+# Declare these phony (not filenames)
+.PHONY: $(ANT_TARGETS) all clobber \
+	jprt_build_product jprt_build_debug jprt_build_fastdebug
diff --git a/nashorn/make/build-benchmark.xml b/nashorn/make/build-benchmark.xml
new file mode 100644
index 0000000..d28de93
--- /dev/null
+++ b/nashorn/make/build-benchmark.xml
@@ -0,0 +1,412 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project name="nashorn-benchmarks" default="all" basedir="..">
+
+  <target name="octane-init" depends="jar">
+    <fileset id="octane-set"
+	     dir="${octane-test-sys-prop.test.js.roots}"
+	     excludes="${octane-test-sys-prop.test.js.exclude.list}">
+      <include name="*.js"/>
+    </fileset>
+    <pathconvert pathsep=" " property="octane-tests" refid="octane-set"/>
+  </target>
+
+  <!-- box2d -->
+  <target name="octane-box2d" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/box2d.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-box2d-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/box2d.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-box2d-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/box2d.js"/>
+    </antcall>
+  </target>
+
+  <!-- code-load -->  
+  <target name="octane-code-load" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/code-load.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-code-load-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/code-load.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-code-load-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/code-load.js"/>
+    </antcall>
+  </target>
+
+  <!-- crypto -->
+  <target name="octane-crypto" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/crypto.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-crypto-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/crypto.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-crypto-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/crypto.js"/>
+    </antcall>
+  </target>
+
+  <!-- deltablue -->
+  <target name="octane-deltablue" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/deltablue.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-deltablue-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/deltablue.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-deltablue-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/deltablue.js"/>
+    </antcall>
+  </target>
+
+  <!-- earley-boyer -->
+  <target name="octane-earley-boyer" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/earley-boyer.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-earley-boyer-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/earley-boyer.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-earley-boyer-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/earley-boyer.js"/>
+    </antcall>
+  </target>
+
+  <!-- gbemu -->  
+  <target name="octane-gbemu" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/gbemu.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-gbemu-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/gbemu.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-gbemu-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/gbemu.js"/>
+    </antcall>
+  </target>
+
+  <!-- mandreel -->  
+  <target name="octane-mandreel" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/mandreel.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-mandreel-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/mandreel.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-mandreel-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/mandreel.js"/>
+    </antcall>
+  </target>
+
+  <!-- navier-stokes -->
+  <target name="octane-navier-stokes" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/navier-stokes.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-navier-stokes-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/navier-stokes.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-navier-stokes-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/navier-stokes.js"/>
+    </antcall>
+  </target>
+
+  <!-- pdfjs -->  
+  <target name="octane-pdfjs" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/pdfjs.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-pdfjs-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/pdfjs.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-pdfjs-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/pdfjs.js"/>
+    </antcall>
+  </target>
+
+  <!-- raytrace -->
+  <target name="octane-raytrace" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/raytrace.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-raytrace-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/raytrace.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-raytrace-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/raytrace.js"/>
+    </antcall>
+  </target>
+
+  <!-- regexp -->
+  <target name="octane-regexp" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/regexp.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-regexp-octane-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/regexp.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-regexp-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/regexp.js"/>
+    </antcall>
+  </target>
+
+  <!-- richards -->
+  <target name="octane-richards" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/richards.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-richards-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/richards.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-richards-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/richards.js"/>
+    </antcall>
+  </target>
+
+  <!-- splay -->
+  <target name="octane-splay" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/splay.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-splay-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/splay.js"/>
+    </antcall>
+  </target>
+
+  <target name="octane-splay-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="${octane-test-sys-prop.test.js.roots}/splay.js"/>
+    </antcall>
+  </target>
+
+  <!-- run octane benchmarks in a single process  -->
+  <target name="octane-single-process" depends="octane-init">
+    <antcall target="run-octane"/>
+  </target>
+
+  <!-- mandreel excluded due to OOM -->
+  <target name="octane-separate-process" depends=
+     "octane-box2d, octane-code-load, octane-crypto, 
+      octane-deltablue, octane-earley-boyer, octane-gbemu,
+      octane-navier-stokes, octane-pdfjs, octane-raytrace, 
+      octane-regexp, octane-richards, octane-splay"/>
+
+  <target name="--single-process" unless="${octane-test-sys-prop.separate.process}">
+    <antcall target="octane-single-process"/>
+  </target>
+  <target name="--separate-process" if="${octane-test-sys-prop.separate.process}">
+    <antcall target="octane-separate-process"/>
+  </target>
+
+  <!-- run 'octane' in single or separate processes based on config -->
+  <target name="octane" depends="init, --single-process, --separate-process"/>
+
+  <!-- run octane benchmarks using octane as runtime -->
+  <target name="octane-v8" depends="octane-init">
+    <antcall target="run-octane-v8"/>
+  </target>
+
+  <!-- run octane benchmarks using Rhino as runtime -->
+  <target name="octane-rhino" depends="octane-init">
+    <antcall target="run-octane-rhino"/>
+  </target>
+  
+  <target name="run-octane">
+    <java classname="${nashorn.shell.tool}"
+          classpath="${run.test.classpath}"
+          fork="true"
+          dir=".">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${run.test.jvmargs.octane}"/>
+      <arg value="${octane-test-sys-prop.test.js.framework}"/>
+      <arg value="--"/>
+      <arg value="${octane-tests}"/>
+      <arg value="--runtime"/>
+      <arg value="Nashorn"/>
+      <arg value="--verbose"/>
+      <arg value="--iterations 8"/>
+    </java>
+  </target>
+
+  <target name="run-octane-v8">
+    <exec executable="${v8.shell}">
+      <arg value="${octane-test-sys-prop.test.js.framework}"/>
+      <arg value="--"/>
+      <arg value="${octane-tests}"/>      
+      <arg value="--runtime"/>
+      <arg value="v8"/>
+      <arg value="--verbose"/>
+      <arg value="--iterations 8"/>
+    </exec>
+  </target>
+
+  <target name="run-octane-rhino">
+    <java jar="${rhino.jar}"
+          classpath="${run.test.classpath}"
+          fork="true"
+          dir=".">
+      <jvmarg line="${run.test.jvmargs.octane}"/>
+      <arg value="${octane-test-sys-prop.test.js.framework}"/>
+      <arg value="${octane-tests}"/>
+      <arg value="--runtime"/>
+      <arg value="Rhino"/>
+      <arg value="--verbose"/>
+      <arg value="--iterations 8"/>
+    </java>
+  </target>
+
+  <!-- run octane with all known runtimes for comparison -->
+  <target name="octane-all" depends="octane, octane-v8, octane-rhino">
+    <exec executable="${v8.shell}">
+      <arg value="${octane-test-sys-prop.test.js.framework}"/>
+      <arg value="${octane-tests}/"/>
+    </exec>
+  </target>
+   
+  <target name="sunspider-init" depends="jar">
+    <fileset id="sunspider-set"
+	     dir="${sunspider-test-sys-prop.test.js.roots}"
+	     excludes="${sunspider-test-sys-prop.test.js.exclude.list}">
+      <include name="**/*.js"/>
+    </fileset>
+    <pathconvert pathsep=" " property="sunspider-tests" refid="sunspider-set"/>
+  </target>
+
+  <!-- run sunspider with Nashorn -->
+  <target name="sunspider" depends="sunspider-init">
+    <java classname="${nashorn.shell.tool}"
+          classpath="${run.test.classpath}"
+          fork="true"
+          dir=".">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${run.test.jvmargs}"/>
+      <arg value="-timezone=PST"/>
+      <arg value="--class-cache-size=50"/>
+      <arg value="${sunspider-test-sys-prop.test.js.framework}"/>
+      <arg value="--"/>
+      <arg value="${sunspider-tests}/"/>
+    </java>
+  </target>
+
+  <!-- run sunspider with v8 -->
+  <target name="sunspider-v8" depends="sunspider-init">
+    <exec executable="${v8.shell}">
+      <arg value="${sunspider-test-sys-prop.test.js.framework}"/>
+      <arg value="--"/>
+      <arg value="${sunspider-tests}/"/>
+    </exec>
+  </target>
+
+  <!-- run sunspider with Rhino -->
+  <target name="sunspider-rhino" depends="sunspider-init">
+    <java jar="${rhino.jar}"
+          classpath="${run.test.classpath}"
+          fork="true"
+          dir=".">
+      <jvmarg line="${run.test.jvmargs}"/>
+      <arg value="${sunspider-test-sys-prop.test.js.framework}"/>
+      <arg value="${sunspider-tests}/"/>
+    </java>
+  </target>
+
+</project>
diff --git a/nashorn/make/build-nasgen.xml b/nashorn/make/build-nasgen.xml
new file mode 100644
index 0000000..5797bef
--- /dev/null
+++ b/nashorn/make/build-nasgen.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project name="build-nasgen" default="run-nasgen" basedir="..">
+    <description>Builds and runs nasgen.</description>
+    <import file="build.xml"/>
+
+    <target name="build-nasgen" depends="compile-asm">
+        <ant inheritAll="false" dir="${basedir}/buildtools/nasgen"
+            antfile="build.xml" target="jar"/>
+    </target>
+
+    <target name="run-nasgen" depends="build-nasgen">
+        <java classname="${nasgen.tool}" fork="true" failonerror="true">
+            <classpath>
+                <pathelement location="${basedir}/jcov2/lib/jcov_j2se_rt.jar"/>
+                <pathelement location="${basedir}/buildtools/nasgen/dist/nasgen.jar"/>
+                <pathelement path="${basedir}/build/classes"/>
+            </classpath>
+            <arg value="${basedir}/build/classes"/>
+            <arg value="jdk.nashorn.internal.objects"/>
+            <arg value="${basedir}/build/classes"/>
+        </java>
+
+        <move todir="${basedir}/build/classes/jdk/nashorn/internal/objects">
+            <fileset dir="${basedir}/build/classes/jdk/nashorn/internal/objects"/>
+            <mapper type="glob" from="*.class" to="*.clazz"/>
+        </move>
+    </target>
+
+    <target name="run-nasgen-eclipse">
+        <mkdir dir="${basedir}/build/eclipse/.nasgentmp"/>
+
+        <java classname="jdk.nashorn.internal.tools.nasgen.Main" fork="true" failonerror="true">
+            <classpath>
+                <pathelement location="${basedir}/buildtools/nasgen/dist/nasgen.jar"/>
+                <pathelement path="${basedir}/build/eclipse"/>
+            </classpath>
+            <arg value="${basedir}/build/eclipse"/>
+            <arg value="jdk.nashorn.internal.objects"/>
+            <arg value="${basedir}/build/eclipse/.nasgentmp"/>
+        </java>
+
+        <move todir="${basedir}/build/eclipse/jdk/nashorn/internal/objects">
+            <fileset dir="${basedir}/build/eclipse/.nasgentmp/jdk/nashorn/internal/objects">
+                <include name="*.class"/>
+            </fileset>
+            <mapper type="glob" from="*.class" to="*.clazz"/>
+        </move>
+
+        <delete includeemptydirs="true"><fileset dir="${basedir}/build/eclipse/.nasgentmp" includes="**"/></delete>
+
+        <copy todir="${basedir}/build/eclipse/jdk/nashorn/internal/objects" preservelastmodified="true">
+            <fileset dir="${basedir}/build/eclipse/jdk/nashorn/internal/objects">
+                <include name="**/*.class"/>
+            </fileset>
+            <mapper type="glob" from="*.class" to="*.clazz"/>
+        </copy>
+    </target>
+
+    <target name="clean-nasgen">
+        <ant inheritAll="false" dir="${basedir}/buildtools/nasgen"
+            antfile="build.xml" target="clean"/>
+    </target>
+
+</project>
diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
new file mode 100644
index 0000000..34f56e4
--- /dev/null
+++ b/nashorn/make/build.xml
@@ -0,0 +1,472 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project name="nashorn" default="test" basedir="..">
+  <import file="build-nasgen.xml"/>
+  <import file="build-benchmark.xml"/>
+  <import file="code_coverage.xml"/>
+
+
+  <target name="init-conditions">
+    <!-- loading locally defined resources and properties. NB they owerwrite default ones defined later -->
+    <property file="${user.home}/.nashorn.project.local.properties"/>
+
+    <loadproperties srcFile="make/project.properties"/>
+    <path id="nashorn.ext.path">
+      <pathelement location="${dist.dir}"/>
+    </path>
+    <property name="ext.class.path" value="-Djava.ext.dirs=&quot;${toString:nashorn.ext.path}&quot;"/>
+    <condition property="svn.executable" value="/usr/local/bin/svn" else="svn">
+      <available file="/usr/local/bin/svn"/>
+    </condition>
+    <condition property="hg.executable" value="/usr/local/bin/hg" else="hg">
+      <available file="/usr/local/bin/hg"/>
+    </condition>
+    <!-- check if JDK already has ASM classes -->
+    <available property="asm.available" classname="jdk.internal.org.objectweb.asm.Type"/>
+    <!-- check if testng.jar is avaiable -->
+    <available property="testng.available" file="${file.reference.testng.jar}"/>
+
+	<!-- enable/disable make code coverage -->
+	<condition property="cc.enabled">
+		<istrue value="${make.code.coverage}" />
+	</condition>
+  </target>
+
+  <target name="init" depends="init-conditions, init-cc">
+
+	<!-- extends jvm args -->
+	<property name="run.test.jvmargs">${run.test.jvmargs.main}  ${run.test.cc.jvmargs}</property>
+	<property name="run.test.jvmargs.octane" value="${run.test.jvmargs.octane.main}  ${run.test.cc.jvmargs}" />
+
+    <echo message="run.test.jvmargs=${run.test.jvmargs}"/>
+    <echo message="run.test.jvmargs.octane=${run.test.jvmargs.octane}"/>
+
+  </target>
+
+  <target name="prepare" depends="init">
+    <mkdir dir="${build.dir}"/>
+    <mkdir dir="${build.classes.dir}"/>
+    <mkdir dir="${build.classes.dir}/META-INF/services"/>
+    <mkdir dir="${build.test.classes.dir}"/>
+    <mkdir dir="${dist.dir}"/>
+    <mkdir dir="${dist.javadoc.dir}"/>
+  </target>
+
+  <target name="clean" depends="init, clean-nasgen, init-cc-cleanup">
+    <delete includeemptydirs="true">
+      <fileset dir="${build.dir}" erroronmissingdir="false"/>
+    </delete>
+    <delete dir="${dist.dir}"/>
+  </target>
+
+  <!-- do it only if ASM is not available -->
+  <target name="compile-asm" depends="prepare" unless="asm.available">
+    <javac srcdir="${jdk.asm.src.dir}"
+           destdir="${build.classes.dir}"
+           excludes="**/optimizer/* **/xml/* **/attrs/*"
+           source="${javac.source}"
+           target="${javac.target}"
+           debug="${javac.debug}"
+           encoding="${javac.encoding}"
+           includeantruntime="false"/>
+  </target>
+
+  <target name="compile" depends="compile-asm" description="Compiles nashorn">
+    <javac srcdir="${src.dir}"
+           destdir="${build.classes.dir}"
+           classpath="${javac.classpath}"
+           source="${javac.source}"
+           target="${javac.target}"
+           debug="${javac.debug}"
+           encoding="${javac.encoding}"
+           includeantruntime="false">
+      <compilerarg value="-Xlint:unchecked"/>
+      <compilerarg value="-Xlint:deprecation"/>
+      <compilerarg value="-XDignore.symbol.file"/>
+    </javac>
+    <copy todir="${build.classes.dir}/META-INF/services">
+       <fileset dir="${meta.inf.dir}/services/"/>
+    </copy>
+     <copy todir="${build.classes.dir}/jdk/nashorn/api/scripting/resources">
+       <fileset dir="${src.dir}/jdk/nashorn/api/scripting/resources/"/>
+    </copy>
+    <copy todir="${build.classes.dir}/jdk/nashorn/internal/runtime/resources">
+       <fileset dir="${src.dir}/jdk/nashorn/internal/runtime/resources/"/>
+    </copy>
+    <copy todir="${build.classes.dir}/jdk/nashorn/tools/resources">
+       <fileset dir="${src.dir}/jdk/nashorn/tools/resources/"/>
+    </copy>
+    <copy file="${src.dir}/jdk/internal/dynalink/support/messages.properties" todir="${build.classes.dir}/jdk/internal/dynalink/support"/>
+
+    <echo message="full=${nashorn.fullversion}" file="${build.classes.dir}/jdk/nashorn/internal/runtime/resources/version.properties"/>
+    <echo file="${build.classes.dir}/jdk/nashorn/internal/runtime/resources/version.properties" append="true">${line.separator}</echo>
+    <echo message="release=${nashorn.version}" file="${build.classes.dir}/jdk/nashorn/internal/runtime/resources/version.properties" append="true"/>
+  </target>
+
+  <target name="jar" depends="compile, run-nasgen" description="Creates nashorn.jar">
+    <jar jarfile="${dist.jar}" manifest="${meta.inf.dir}/MANIFEST.MF" index="true" filesetmanifest="merge">
+      <fileset dir="${build.classes.dir}"/>
+      <manifest>
+        <attribute name="Archiver-Version" value="n/a"/>
+        <attribute name="Build-Jdk" value="${java.runtime.version}"/>
+        <attribute name="Built-By" value="n/a"/>
+        <attribute name="Created-By" value="Ant jar task"/>
+        <section name="jdk/nashorn/">
+          <attribute name="Implementation-Title" value="${nashorn.product.name}"/>
+          <attribute name="Implementation-Version" value="${nashorn.version}"/>
+        </section>
+      </manifest>
+    </jar>
+  </target>
+
+  <target name="javadoc" depends="prepare">
+    <javadoc destdir="${dist.javadoc.dir}" use="yes" overview="src/overview.html" windowtitle="${nashorn.product.name} ${nashorn.version}" additionalparam="-quiet" failonerror="true">
+      <classpath>
+        <pathelement location="${build.classes.dir}"/>
+      </classpath>
+      <fileset dir="${src.dir}" includes="**/*.java"/>
+      <fileset dir="${jdk.asm.src.dir}" includes="**/*.java"/>
+      <link href="http://docs.oracle.com/javase/7/docs/api/"/>
+      <!-- The following tags are used only in ASM sources - just ignore these -->
+      <tag name="label" description="label tag in ASM sources" enabled="false"/>
+      <tag name="linked" description="linked tag in ASM sources" enabled="false"/>
+      <tag name="associates" description="associates tag in ASM sources" enabled="false"/>
+    </javadoc>
+  </target>
+
+  <!-- generate shell.html for shell tool documentation -->
+  <target name="shelldoc" depends="jar">
+    <java classname="${nashorn.shell.tool}" dir="${basedir}" output="${dist.dir}/shell.html" failonerror="true" fork="true">
+      <jvmarg line="${ext.class.path}"/>
+      <arg value="-scripting"/>
+      <arg value="docs/genshelldoc.js"/>
+    </java>
+  </target>
+
+  <!-- generate all docs -->
+  <target name="docs" depends="javadoc, shelldoc"/>
+
+  <!-- create .zip and .tar.gz for nashorn binaries and scripts. -->
+  <target name="dist" depends="jar">
+      <zip destfile="${build.zip}" basedir=".."
+          excludes="nashorn/bin/*.sh" includes="nashorn/bin/** nashorn/dist/**"/>
+      <tar destfile="${build.gzip}" basedir=".." compression="gzip"
+          excludes="nashorn/bin/*.sh" includes="nashorn/bin/** nashorn/dist/**"/>
+  </target>
+
+  <target name="compile-test" depends="compile, run-nasgen" if="testng.available">
+    <!-- testng task -->
+    <taskdef name="testng" classname="org.testng.TestNGAntTask"
+        classpath="${file.reference.testng.jar}"/>
+
+    <javac srcdir="${test.src.dir}"
+           destdir="${build.test.classes.dir}"
+           classpath="${javac.test.classpath}"
+           source="${javac.source}"
+           target="${javac.target}"
+           debug="${javac.debug}"
+           encoding="${javac.encoding}"
+           includeantruntime="false"/>
+
+    <!-- tests that check nashorn internals and internal API -->
+    <jar jarfile="${nashorn.internal.tests.jar}">
+      <fileset dir="${build.test.classes.dir}" excludes="**/api/*"/>
+    </jar>
+
+    <!-- tests that check nashorn script engine (jsr-223) API -->
+    <jar jarfile="${nashorn.api.tests.jar}">
+      <fileset dir="${build.test.classes.dir}" includes="**/api/*"/>
+    </jar>
+
+  </target>
+
+  <target name="generate-policy-file" depends="prepare">
+    <!-- Generating nashorn.policy file -->
+
+    <!-- nashorn internal tests jar requires AllPermission -->
+    <echo message="grant codeBase &quot;file:/${basedir}/${nashorn.internal.tests.jar}&quot; {" file="${build.dir}/nashorn.policy"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    
+    <!-- TestNG framework jar needs AllPermission -->
+    <echo message="grant codeBase &quot;file:/${basedir}/${file.reference.testng.jar}&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+
+    <!-- AllPermission to test/script/trusted tests -->
+    <echo message="grant codeBase &quot;file:/${basedir}/test/script/trusted/*&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+
+    <echo message="grant codeBase &quot;file:/${basedir}/test/script/basic/*&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    <!-- test/script/basic .js scripts load other script tests -->
+    <echo message="    permission java.io.FilePermission &quot;${basedir}/test/script/-&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="    permission java.io.FilePermission &quot;user.dir&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="    permission java.util.PropertyPermission &quot;user.dir&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    <!-- test/script/basic .js scripts can read nashorn.test.* properties -->
+    <echo message="    permission java.util.PropertyPermission &quot;nashorn.test.*&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
+
+    <replace file="${build.dir}/nashorn.policy"><replacetoken>\</replacetoken><replacevalue>/</replacevalue></replace>    <!--hack for Windows - to make URLs with normal path separators -->
+    <replace file="${build.dir}/nashorn.policy"><replacetoken>//</replacetoken><replacevalue>/</replacevalue></replace>   <!--hack for Unix - to avoid leading // in URLs -->
+
+  </target>
+
+  <target name="check-external-tests">
+      <available file="${test.external.dir}/prototype" property="test-sys-prop.external.prototype"/>
+      <available file="${test.external.dir}/sunspider" property="test-sys-prop.external.sunspider"/>
+      <available file="${test.external.dir}/underscore" property="test-sys-prop.external.underscore"/>
+      <available file="${test.external.dir}/octane" property="test-sys-prop.external.octane"/>
+      <available file="${test.external.dir}/yui" property="test-sys-prop.external.yui"/>
+      <available file="${test.external.dir}/jquery" property="test-sys-prop.external.jquery"/>
+      <available file="${test.external.dir}/test262" property="test-sys-prop.external.test262"/>
+  </target>
+
+  <target name="check-testng" unless="testng.available">
+    <echo message="WARNING: TestNG not available, will not run tests. Please copy testng.jar under test/lib directory."/>
+  </target>
+
+  <target name="test" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+    <java classname="${nashorn.shell.tool}" fork="true" dir="${test.script.dir}/representations" output="${build.dir}/output1.log" error="${build.dir}/err.log">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="-Dnashorn.fields.dual=true"/>
+      <arg value="NASHORN-592a.js"/>
+    </java>
+    <java classname="${nashorn.shell.tool}" fork="true" dir="${test.script.dir}/representations" output="${build.dir}/output2.log" error="${build.dir}/err.log">
+      <jvmarg line="${ext.class.path}"/>
+      <arg value="NASHORN-592a.js"/>
+    </java>
+    <condition property="representation-ok">
+      <filesmatch file1="${build.dir}/output1.log" file2="${build.dir}/output2.log"/>
+    </condition>
+    <fail unless="representation-ok">Representation test failed - output differs!</fail>
+    <fileset id="test.classes" dir="${build.test.classes.dir}">
+      <include name="**/api/javaaccess/*Test.class"/>
+      <include name="**/api/scripting/*Test.class"/>
+      <include name="**/codegen/*Test.class"/>
+      <include name="**/parser/*Test.class"/>
+      <include name="**/runtime/*Test.class"/>
+      <include name="**/framework/*Test.class"/>
+    </fileset>
+
+    <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
+       verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${run.test.jvmargs} ${run.test.jvmsecurityargs}"/>
+      <propertyset>
+        <propertyref prefix="test-sys-prop."/>
+        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+      </propertyset>
+      <classpath>
+          <pathelement path="${run.test.classpath}"/>
+      </classpath>
+    </testng>
+  </target>
+
+  <target name="test-basicparallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file">
+      <!-- use just build.test.classes.dir to avoid referring to TestNG -->
+      <java classname="${parallel.test.runner}" dir="${basedir}" classpath="${build.test.classes.dir}" failonerror="true" fork="true">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${run.test.jvmargs} ${run.test.jvmsecurityargs}"/>
+      <syspropertyset>
+          <propertyref prefix="test-sys-prop."/>
+          <mapper type="glob" from="test-sys-prop.*" to="*"/>
+      </syspropertyset>
+      </java>
+  </target>
+
+  <target name="test262" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+    <fileset id="test.classes" dir="${build.test.classes.dir}">
+       <include name="**/framework/*Test.class"/>
+    </fileset>
+
+    <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
+       verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${run.test.jvmargs} ${run.test.jvmsecurityargs}"/>
+      <propertyset>
+        <propertyref prefix="test262-test-sys-prop."/>
+        <mapper from="test262-test-sys-prop.*" to="*" type="glob"/>
+      </propertyset>
+      <classpath>
+          <pathelement path="${run.test.classpath}"/>
+      </classpath>
+    </testng>
+  </target>
+
+  <target name="test262parallel" depends="test262-parallel"/>
+
+  <target name="test262-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+    <!-- use just build.test.classes.dir to avoid referring to TestNG -->
+    <java classname="${parallel.test.runner}" dir="${basedir}" fork="true">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${run.test.jvmargs} ${run.test.jvmsecurityargs}"/>
+      <classpath>
+          <pathelement path="${run.test.classpath}"/>
+      </classpath>
+      <syspropertyset>
+          <propertyref prefix="test262-test-sys-prop."/>
+          <mapper type="glob" from="test262-test-sys-prop.*" to="*"/>
+      </syspropertyset>
+    </java>
+  </target>
+
+  <target name="all" depends="test, docs"
+      description="Build, test and generate docs for nashorn"/>
+
+  <target name="run" depends="jar"
+      description="Run the shell with a sample script">
+    <java classname="${nashorn.shell.tool}" fork="true" dir="samples">
+        <jvmarg line="${ext.class.path}"/>
+        <jvmarg line="${run.test.jvmargs}"/>
+        <arg value="-dump-on-error"/>
+        <arg value="test.js"/>
+    </java>
+  </target>
+
+  <target name="debug" depends="jar"
+      description="Debug the shell with a sample script">
+    <java classname="${nashorn.shell.tool}" fork="true" dir="samples">
+        <jvmarg line="${ext.class.path}"/>
+        <jvmarg line="${run.test.jvmargs}"/>
+        <arg value="--print-code"/>
+        <arg value="--verify-code"/>
+        <arg value="--print-symbols"/>
+        <jvmarg value="-Dnashorn.codegen.debug=true"/>
+        <arg value="test.js"/>
+    </java>
+  </target>
+
+  <!-- targets to get external script tests -->
+
+  <!-- test262 test suite -->
+  <target name="get-test262" depends="init" unless="${test-sys-prop.external.test262}">
+    <!-- clone test262 mercurial repo -->
+    <exec executable="${hg.executable}">
+       <arg value="clone"/>
+       <arg value="http://hg.ecmascript.org/tests/test262"/>
+       <arg value="${test.external.dir}/test262"/>
+    </exec>
+  </target>
+  <target name="update-test262" depends="init" if="${test-sys-prop.external.test262}">
+    <!-- update test262 mercurial repo -->
+    <exec executable="${hg.executable}" dir="${test.external.dir}/test262">
+       <arg value="pull"/>
+       <arg value="-u"/>
+    </exec>
+  </target>
+
+  <!-- octane benchmark -->
+  <target name="get-octane" depends="init" unless="${test-sys-prop.external.octane}">
+    <!-- checkout octane benchmarks -->
+    <exec executable="${svn.executable}">
+       <arg value="--non-interactive"/>
+       <arg value="--trust-server-cert"/>
+       <arg value="checkout"/>
+       <arg value="http://octane-benchmark.googlecode.com/svn/trunk/"/>
+       <arg value="${test.external.dir}/octane"/>
+    </exec>
+  </target>
+  <target name="update-octane" depends="init" if="${test-sys-prop.external.octane}">
+    <!-- update octane benchmarks -->
+    <exec executable="${svn.executable}" dir="${test.external.dir}/octane">
+       <arg value="--non-interactive"/>
+       <arg value="--trust-server-cert"/>
+       <arg value="update"/>
+    </exec>
+  </target>
+
+  <!-- sunspider benchmark -->
+  <target name="get-sunspider" depends="init" unless="${test-sys-prop.external.sunspider}">
+    <!-- checkout sunspider -->
+    <exec executable="${svn.executable}">
+       <arg value="--non-interactive"/>
+       <arg value="--trust-server-cert"/>
+       <arg value="checkout"/>
+       <arg value="http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider"/>
+       <arg value="${test.external.dir}/sunspider"/>
+    </exec>
+  </target>
+  <target name="update-sunspider" depends="init" if="${test-sys-prop.external.sunspider}">
+    <!-- update sunspider -->
+    <exec executable="${svn.executable}" dir="${test.external.dir}/sunspider">
+       <arg value="--non-interactive"/>
+       <arg value="--trust-server-cert"/>
+       <arg value="update"/>
+    </exec>
+  </target>
+
+  <!-- get all external test scripts -->
+  <target name="externals" depends="init, check-external-tests, get-test262, get-octane, get-sunspider">
+    <!-- make external test dir -->
+    <mkdir dir="${test.external.dir}"/> 
+
+    <!-- jquery -->
+    <mkdir dir="${test.external.dir}/jquery"/>    
+    <get src="http://code.jquery.com/jquery-1.7.2.js" dest="${test.external.dir}/jquery" skipexisting="true" ignoreerrors="true"/>
+    <get src="http://code.jquery.com/jquery-1.7.2.min.js" dest="${test.external.dir}/jquery" skipexisting="true" ignoreerrors="true"/>
+
+    <!-- prototype -->
+    <mkdir dir="${test.external.dir}/prototype"/>    
+    <get src="http://ajax.googleapis.com/ajax/libs/prototype/1.7.0/prototype.js" dest="${test.external.dir}/prototype" usetimestamp="true" skipexisting="true" ignoreerrors="true"/>
+
+    <!-- underscorejs -->
+    <mkdir dir="${test.external.dir}/underscore"/> 
+    <get src="http://underscorejs.org/underscore.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true"/>
+    <get src="http://underscorejs.org/underscore-min.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true"/>
+
+    <!-- yui -->
+    <mkdir dir="${test.external.dir}/yui"/> 
+    <get src="http://yui.yahooapis.com/3.5.1/build/yui/yui.js" dest="${test.external.dir}/yui" skipexisting="true" ignoreerrors="true"/>
+    <get src="http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js" dest="${test.external.dir}/yui" skipexisting="true" ignoreerrors="true"/>
+
+  </target>
+
+  <!-- update external test suites that are pulled from source control systems -->
+  <target name="update-externals" depends="init, check-external-tests, update-test262, update-octane, update-sunspider"/>
+
+  <!-- run all perf tests -->
+  <target name="perf" depends="externals, update-externals, sunspider, octane"/>
+
+  <!-- run all tests -->
+  <target name="exit-if-no-testng" depends="init, check-testng" unless="${testng.available}">
+     <fail message="Exiting.."/>
+  </target>
+
+  <target name="alltests" depends="exit-if-no-testng, externals, update-externals, test, test262parallel, perf"/>
+
+</project>
diff --git a/nashorn/make/code_coverage.xml b/nashorn/make/code_coverage.xml
new file mode 100644
index 0000000..41d85ff
--- /dev/null
+++ b/nashorn/make/code_coverage.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project name="code-coverage" default="generate-code-coverage-report" basedir="..">
+
+  <!-- CODE COVERAGE -->
+  <target name="init-cc-enabled" if="${cc.enabled}">
+
+    <echo message="initialize [${jcov}] java coverage"/>
+
+
+    <property name="cc.report.dir" value="${cc.dir}/CC_${jcov}_report"/>
+    <property name="cc.merged.xml" value="${cc.dir}/CC_${jcov}_result-merged.xml"/>
+
+    <condition property="run.test.cc.jvmargs" value="${cc.dynamic.args}">
+      <equals arg1="${jcov}" arg2="dynamic" trim="true"/>
+    </condition>
+
+    <mkdir dir="${cc.dir}"/>
+
+    <!-- info -->
+    <echo message="jcov=${jcov}"/>
+    <echo message="cc.generate.template=${cc.generate.template}"/>
+    <echo message="cc.instrument=${cc.instrument}"/>
+    <echo message="run.test.cc.jvmargs=${run.test.cc.jvmargs}"/>
+    <echo message="cc.report.dir=${cc.report.dir}"/>
+    <echo message="cc.merged.xml=${cc.merged.xml}"/>
+  </target>
+
+  <target name="init-cc-disabled" unless="${cc.enabled}">
+    <property name="run.test.cc.jvmargs" value=""/>
+  </target>
+
+  <target name="init-cc" depends="init-cc-disabled, init-cc-enabled">
+    <property name="run.test.cc.jvmargs" value=""/>
+  </target>
+
+  <target name="init-cc-cleanup" if="${cc.enabled}">
+    <delete dir="${cc.dir}" failonerror="false" />
+  </target>
+
+  <target name="check-merging-files" depends="init">
+	<resourcecount property="cc.xmls">
+  		<filelist dir="${cc.dir}" files="*.xml" />
+	</resourcecount>	
+    <condition property="nothing-to-merge" value="true">
+      <equals arg1="${cc.xmls}" arg2="1" trim="true"/>
+    </condition>
+  </target>
+
+  <target name="fix-merging-files" depends="check-merging-files" if="${nothing-to-merge}">
+	<echo message="making pre-merge workaround"/>
+	<move todir="${cc.dir}" includeemptydirs="false">
+		<fileset dir="${cc.dir}">
+			<include name="*.xml"/>
+		</fileset>
+		<mapper type="glob" from="*.xml" to="CC_${jcov}_result-merged.xml"/>
+	</move>
+  </target>
+ 
+  <target name="merge-code-coverage" depends="fix-merging-files" unless="${nothing-to-merge}">
+	<echo message="merging files"/>
+    <fileset dir="${cc.dir}" id="cc.xmls">
+      <include name="**/*${jcov}*.xml"/>
+      <include name="**/CC_template.xml"/>
+    </fileset>
+
+    <pathconvert pathsep=" " property="cc.all.xmls" refid="cc.xmls"/>
+
+    <java classname="com.sun.tdk.jcov.Merger">
+      <arg value="-verbose"/>
+      <arg value="-output"/>
+      <arg value="${cc.merged.xml}"/>
+      <arg value="-exclude"/>
+      <arg value="com\.oracle\.nashorn\.runtime\.ScriptRuntime*"/>
+      <arg line="${cc.all.xmls}"/>
+      <classpath>
+        <pathelement location="${jcov.jar}"/>
+      </classpath>
+    </java>
+
+  </target>
+
+  <target name="generate-code-coverage-report" depends="merge-code-coverage">
+    <java classname="com.sun.tdk.jcov.RepGen">
+      <arg value="-verbose"/>
+<!--      <arg line ="-exclude_list CC.report.exclude"/> -->
+      <arg line="-output ${cc.report.dir}"/>
+      <arg value="${cc.merged.xml}"/>
+      <classpath>
+        <pathelement location="${jcov.jar}"/>
+      </classpath>
+    </java>
+  </target>
+
+
+</project>
diff --git a/nashorn/make/java.security.override b/nashorn/make/java.security.override
new file mode 100644
index 0000000..0021985
--- /dev/null
+++ b/nashorn/make/java.security.override
@@ -0,0 +1,14 @@
+# We would like to avoid references from anywhere outside nashorn
+# to codegen, IR and parser packages, in particular script generated classes.
+# We ensure that by overriding "package.access" security property.
+
+# The following "package.access" value was copied from  default java.security 
+# of jre/lib/security and appended with nashorn IR, Codegen and Parser packages.
+
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# 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.lookup., jdk.nashorn.internal.parser.
diff --git a/nashorn/make/nbproject/ide-file-targets.xml b/nashorn/make/nbproject/ide-file-targets.xml
new file mode 100644
index 0000000..cb017bb
--- /dev/null
+++ b/nashorn/make/nbproject/ide-file-targets.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project basedir=".." name="nashorn-IDE">
+    <property file="nbproject/nbjdk.properties"/>
+    <property location="${netbeans.user}/build.properties" name="user.properties.file"/>
+    <property file="${user.properties.file}"/>
+    <import file="jdk.xml"/>
+    <import file="${basedir}/build-init.xml"/>
+    <!-- TODO: edit the following target according to your needs -->
+    <!-- (more info: http://www.netbeans.org/kb/articles/freeform-config.html#runsingle) -->
+    <target depends="-jdk-init, init" name="debug-selected-file-in-src">
+        <fail unless="debug.class">Must set property 'debug.class'</fail>
+        <ant antfile="build.xml" inheritall="false" target="jar"/>
+        <nbjpdastart addressproperty="jpda.address" name="nashorn" transport="dt_socket">
+            <classpath path="${run.test.classpath}"/>
+        </nbjpdastart>
+        <java classname="${debug.class}" fork="false">
+            <classpath path="${run.test.classpath}"/>
+            <jvmarg line="${boot.class.path}"/>
+            <jvmarg value="-Xdebug"/>
+            <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
+            <jvmarg line="${run.test.jvmargs}"/>
+            <arg value="${debug.class}"/>
+        </java>
+    </target>
+    <!-- TODO: edit the following target according to your needs -->
+    <!-- (more info: http://www.netbeans.org/kb/articles/freeform-config.html#runsingle) -->
+    <target depends="-jdk-init, init" name="run-selected-file-in-src">
+        <fail unless="run.class">Must set property 'run.class'</fail>
+        <ant antfile="build.xml" inheritall="false" target="jar"/>
+        <java classname="${run.class}" failonerror="true" fork="false">
+            <classpath path="${run.test.classpath}"/>
+            <jvmarg line="${boot.class.path}"/>
+            <jvmarg line="${run.test.jvmargs}"/>
+            <arg value="${run.class}"/>
+        </java>
+    </target>
+</project>
diff --git a/nashorn/make/nbproject/ide-targets.xml b/nashorn/make/nbproject/ide-targets.xml
new file mode 100644
index 0000000..70b3e68
--- /dev/null
+++ b/nashorn/make/nbproject/ide-targets.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<project basedir="../.." name="nashorn-IDE">
+    <import file="../build.xml"/>
+    <!-- TODO: edit the following target according to your needs -->
+    <!-- (more info: http://www.netbeans.org/kb/articles/freeform-config.html#debugj2se) -->
+    <target depends="jar" description="Run the shell with a sample script" name="debug-nb">
+        <nbjpdastart addressproperty="jpda.address" name="nashorn" transport="dt_socket">
+            <classpath path="${run.test.classpath}"/>
+        </nbjpdastart>
+        <java classname="jdk.nashorn.tools.Shell" classpath="${run.test.classpath}" dir="samples" fork="true">
+            <jvmarg line="${ext.class.path}"/> 
+            <jvmarg line="${run.test.jvmargs}"/>
+            <arg value="test.js"/>
+            <jvmarg value="-Xdebug"/>
+            <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
+        </java>
+    </target>
+</project>
diff --git a/nashorn/make/nbproject/jdk.xml b/nashorn/make/nbproject/jdk.xml
new file mode 100644
index 0000000..2fabe8c
--- /dev/null
+++ b/nashorn/make/nbproject/jdk.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?><project name="jdk" basedir=".">
+<!--
+ 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.
+-->
+
+    
+    <description>
+        Permits selection of a JDK to use when building and running project.
+        See: http://www.netbeans.org/issues/show_bug.cgi?id=64160
+    </description>
+
+    <target name="-jdk-pre-preinit">
+        <condition property="nbjdk.active-or-nbjdk.home">
+            <or>
+                <and>
+                    <isset property="nbjdk.active"/>
+                    <not>
+                        <equals arg1="${nbjdk.active}" arg2="default_platform"/>
+                    </not>
+                </and>
+                <and>
+                    <isset property="nbjdk.home"/>
+                    <not>
+                        <isset property="nbjdk.home.defaulted"/>
+                    </not>
+                </and>
+            </or>
+        </condition>
+    </target>
+
+    <target xmlns:common="http://java.netbeans.org/freeform/jdk.xml" name="-jdk-preinit" depends="-jdk-pre-preinit" if="nbjdk.active-or-nbjdk.home">
+        <macrodef name="property" uri="http://java.netbeans.org/freeform/jdk.xml">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${@{value}}"/>
+            </sequential>
+        </macrodef>
+        <common:property name="nbjdk.home" value="platforms.${nbjdk.active}.home"/>
+        <common:property name="nbjdk.javac.tmp" value="platforms.${nbjdk.active}.javac"/>
+        <condition property=".exe" value=".exe">
+            <os family="windows"/> 
+        </condition>
+        <property name=".exe" value=""/>
+        <condition property="nbjdk.javac" value="${nbjdk.home}/bin/javac${.exe}">
+            <equals arg1="${nbjdk.javac.tmp}" arg2="$${platforms.${nbjdk.active}.javac}"/>
+        </condition>
+        <property name="nbjdk.javac" value="${nbjdk.javac.tmp}"/>
+        <common:property name="nbjdk.java.tmp" value="platforms.${nbjdk.active}.java"/>
+        <condition property="nbjdk.java" value="${nbjdk.home}/bin/java${.exe}">
+            <equals arg1="${nbjdk.java.tmp}" arg2="$${platforms.${nbjdk.active}.java}"/>
+        </condition>
+        <property name="nbjdk.java" value="${nbjdk.java.tmp}"/>
+        <common:property name="nbjdk.javadoc.tmp" value="platforms.${nbjdk.active}.javadoc"/>
+        <condition property="nbjdk.javadoc" value="${nbjdk.home}/bin/javadoc${.exe}">
+            <equals arg1="${nbjdk.javadoc.tmp}" arg2="$${platforms.${nbjdk.active}.javadoc}"/>
+        </condition>
+        <property name="nbjdk.javadoc" value="${nbjdk.javadoc.tmp}"/>
+        <common:property name="nbjdk.bootclasspath.tmp" value="platforms.${nbjdk.active}.bootclasspath"/>
+        <condition property="nbjdk.bootclasspath" value="${nbjdk.home}/jre/lib/rt.jar">
+            <equals arg1="${nbjdk.bootclasspath.tmp}" arg2="$${platforms.${nbjdk.active}.bootclasspath}"/>
+        </condition>
+        <property name="nbjdk.bootclasspath" value="${nbjdk.bootclasspath.tmp}"/>
+        <condition property="nbjdk.valid">
+            <and>
+                <available file="${nbjdk.home}" type="dir"/>
+                <available file="${nbjdk.javac}" type="file"/>
+                <available file="${nbjdk.java}" type="file"/>
+                <available file="${nbjdk.javadoc}" type="file"/>
+                
+            </and>
+        </condition>
+        <echo level="verbose">nbjdk.active=${nbjdk.active} nbjdk.home=${nbjdk.home} nbjdk.java=${nbjdk.java} nbjdk.javac=${nbjdk.javac} nbjdk.javadoc=${nbjdk.javadoc} nbjdk.bootclasspath=${nbjdk.bootclasspath} nbjdk.valid=${nbjdk.valid} have-jdk-1.4=${have-jdk-1.4} have-jdk-1.5=${have-jdk-1.5}</echo>
+    </target>
+
+    <target name="-jdk-warn" depends="-jdk-preinit" if="nbjdk.active-or-nbjdk.home" unless="nbjdk.valid">
+        <property name="jdkhome.presumed" location="${java.home}/.."/>
+        <echo level="warning">Warning: nbjdk.active=${nbjdk.active} or nbjdk.home=${nbjdk.home} is an invalid Java platform; ignoring and using ${jdkhome.presumed}</echo>
+    </target>
+
+    <target name="-jdk-presetdef-basic" depends="-jdk-preinit" if="nbjdk.valid" unless="nbjdk.presetdef.basic.done">
+        
+        
+        <macrodef name="javac-presetdef">
+            <attribute name="javacval"/>
+            <sequential>
+                <presetdef name="javac">
+                    <javac fork="yes" executable="@{javacval}"/>
+                </presetdef>
+            </sequential>
+        </macrodef>
+        <javac-presetdef javacval="${nbjdk.javac}"/>
+        <macrodef name="java-presetdef">
+            <attribute name="javaval"/>
+            <sequential>
+                <presetdef name="java">
+                    <java fork="yes" jvm="@{javaval}"/>
+                </presetdef>
+            </sequential>
+        </macrodef>
+        <java-presetdef javaval="${nbjdk.java}"/>
+        <macrodef name="javadoc-presetdef">
+            <attribute name="javadocval"/>
+            <sequential>
+                <presetdef name="javadoc">
+                    <javadoc executable="@{javadocval}"/>
+                </presetdef>
+            </sequential>
+        </macrodef>
+        <javadoc-presetdef javadocval="${nbjdk.javadoc}"/>
+        <macrodef name="junit-presetdef">
+            <attribute name="javaval"/>
+            <sequential>
+                <presetdef name="junit">
+                    <junit fork="yes" jvm="@{javaval}"/>
+                </presetdef>
+            </sequential>
+        </macrodef>
+        <junit-presetdef javaval="${nbjdk.java}"/>
+        <property name="nbjdk.presetdef.basic.done" value="true"/>
+    </target>
+
+    <target name="-jdk-presetdef-nbjpdastart" depends="-jdk-preinit" if="nbjdk.valid" unless="nbjdk.presetdef.nbjpdastart.done">
+        <macrodef name="nbjpdastart-presetdef">
+            <attribute name="bootcpval"/>
+            <sequential>
+                <presetdef name="nbjpdastart">
+                    <nbjpdastart>
+                        <bootclasspath>
+                            <path path="@{bootcpval}"/>
+                        </bootclasspath>
+                    </nbjpdastart>
+                </presetdef>
+            </sequential>
+        </macrodef>
+        <nbjpdastart-presetdef bootcpval="${nbjdk.bootclasspath}"/>
+        <property name="nbjdk.presetdef.nbjpdastart.done" value="true"/>
+    </target>
+
+    <target name="-jdk-default" unless="nbjdk.active-or-nbjdk.home">
+        
+        <property name="java.home.parent" location="${java.home}/.."/>
+        <condition property="nbjdk.home" value="${java.home.parent}">
+            <available file="${java.home.parent}/lib/tools.jar" type="file"/>
+        </condition>
+        <condition property="nbjdk.home" value="${java.home}">
+            <available file="${java.home}/lib/tools.jar" type="file"/>
+        </condition>
+        
+        <condition property="nbjdk.home" value="/Library/Java/Home">
+            <available file="/Library/Java/Home" type="dir"/>
+        </condition>
+        
+        <property name="nbjdk.home" location="${java.home.parent}"/>
+        <property name="nbjdk.home.defaulted" value="true"/>
+    </target>
+
+    <target name="-jdk-init" depends="-jdk-preinit,-jdk-warn,-jdk-presetdef-basic,-jdk-default"/>
+
+</project>
diff --git a/nashorn/make/nbproject/nbjdk.properties b/nashorn/make/nbproject/nbjdk.properties
new file mode 100644
index 0000000..8809e40
--- /dev/null
+++ b/nashorn/make/nbproject/nbjdk.properties
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+nbjdk.active=JDK_1.8
+
diff --git a/nashorn/make/nbproject/nbjdk.xml b/nashorn/make/nbproject/nbjdk.xml
new file mode 100644
index 0000000..102045e
--- /dev/null
+++ b/nashorn/make/nbproject/nbjdk.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project basedir="..">
+    <property file="../global.properties"/>
+    <property file="nbproject/nbjdk.properties"/>
+    <property location="${netbeans.user}/build.properties" name="user.properties.file"/>
+    <property file="${user.properties.file}"/>
+    <import file="jdk.xml"/>
+    <target depends="-jdk-init" name="jar">
+        <ant inheritall="false" target="jar"/>
+    </target>
+    <target depends="-jdk-init" name="clean">
+        <ant inheritall="false" target="clean"/>
+    </target>
+    <target depends="-jdk-init" name="javadoc">
+        <ant inheritall="false" target="javadoc"/>
+    </target>
+    <target depends="-jdk-init" name="test">
+        <ant inheritall="false" target="test"/>
+    </target>
+    <target depends="-jdk-init" name="run">
+        <ant inheritall="false" target="run"/>
+    </target>
+    <target depends="-jdk-init,-jdk-presetdef-nbjpdastart" name="debug-nb">
+        <ant antfile="nbproject/ide-targets.xml" inheritall="false" target="debug-nb"/>
+    </target>
+</project>
diff --git a/nashorn/make/nbproject/project.xml b/nashorn/make/nbproject/project.xml
new file mode 100644
index 0000000..828dc29
--- /dev/null
+++ b/nashorn/make/nbproject/project.xml
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.ant.freeform</type>
+    <configuration>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+            <name>nashorn</name>
+        </general-data>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/2">
+            <!-- Do not use Project Properties customizer when editing this file manually. -->
+            <name>nashorn</name>
+            <properties/>
+            <folders>
+                <source-folder>
+                    <label>nashorn</label>
+                    <location>.</location>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+                <source-folder>
+                    <label>../src</label>
+                    <location>../src</location>
+                </source-folder>
+                <source-folder>
+                    <label>../test/src</label>
+                    <location>../test/src</location>
+                </source-folder>
+                <source-folder>
+                    <label>../buildtools/nasgen/src</label>
+                    <location>../buildtools/nasgen/src</location>
+                </source-folder>
+                <source-folder>
+                    <label>../test/src</label>
+                    <type>java</type>
+                    <location>../test/src</location>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+                <source-folder>
+                    <label>../src</label>
+                    <type>java</type>
+                    <location>../src</location>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+                <source-folder>
+                    <label>../buildtools/nasgen/src</label>
+                    <type>java</type>
+                    <location>../buildtools/nasgen/src</location>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+            </folders>
+            <ide-actions>
+                <action name="build">
+                    <script>nbproject/nbjdk.xml</script>
+                    <target>jar</target>
+                </action>
+                <action name="clean">
+                    <script>nbproject/nbjdk.xml</script>
+                    <target>clean</target>
+                </action>
+                <action name="javadoc">
+                    <script>nbproject/nbjdk.xml</script>
+                    <target>javadoc</target>
+                </action>
+                <action name="test">
+                    <script>nbproject/nbjdk.xml</script>
+                    <target>test</target>
+                </action>
+                <action name="rebuild">
+                    <script>nbproject/nbjdk.xml</script>
+                    <target>clean</target>
+                    <target>jar</target>
+                </action>
+                <action name="run">
+                    <script>nbproject/nbjdk.xml</script>
+                    <target>run</target>
+                </action>
+                <action name="debug">
+                    <script>nbproject/nbjdk.xml</script>
+                    <target>debug-nb</target>
+                </action>
+                <action name="debug.single">
+                    <script>nbproject/ide-file-targets.xml</script>
+                    <target>debug-selected-file-in-src</target>
+                    <context>
+                        <property>debug.class</property>
+                        <folder>test/src</folder>
+                        <pattern>\.java$</pattern>
+                        <format>java-name</format>
+                        <arity>
+                            <one-file-only/>
+                        </arity>
+                    </context>
+                </action>
+                <action name="run.single">
+                    <script>nbproject/ide-file-targets.xml</script>
+                    <target>run-selected-file-in-src</target>
+                    <context>
+                        <property>run.class</property>
+                        <folder>test/src</folder>
+                        <pattern>\.java$</pattern>
+                        <format>java-name</format>
+                        <arity>
+                            <one-file-only/>
+                        </arity>
+                    </context>
+                </action>
+            </ide-actions>
+            <view>
+                <items>
+                    <source-folder style="packages">
+                        <label>../test/src</label>
+                        <location>../test/src</location>
+                    </source-folder>
+                    <source-folder style="packages">
+                        <label>../src</label>
+                        <location>../src</location>
+                    </source-folder>
+                    <source-folder style="packages">
+                        <label>../buildtools/nasgen/src</label>
+                        <location>../buildtools/nasgen/src</location>
+                    </source-folder>
+                    <source-file>
+                        <location>build.xml</location>
+                    </source-file>
+                </items>
+                <context-menu>
+                    <ide-action name="build"/>
+                    <ide-action name="rebuild"/>
+                    <ide-action name="clean"/>
+                    <ide-action name="javadoc"/>
+                    <ide-action name="run"/>
+                    <ide-action name="test"/>
+                    <ide-action name="debug"/>
+                </context-menu>
+            </view>
+            <subprojects/>
+        </general-data>
+        <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
+            <compilation-unit>
+                <package-root>../test/src</package-root>
+                <unit-tests/>
+                <classpath mode="compile">../test/lib/testng.jar:../build/classes:../src</classpath>
+                <source-level>1.7</source-level>
+            </compilation-unit>
+            <compilation-unit>
+                <package-root>../src</package-root>
+                <source-level>1.7</source-level>
+            </compilation-unit>
+            <compilation-unit>
+                <package-root>../buildtools/nasgen/src</package-root>
+                <classpath mode="compile">../build/classes:../src</classpath>
+                <source-level>1.7</source-level>
+            </compilation-unit>
+        </java-data>
+    </configuration>
+</project>
diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties
new file mode 100644
index 0000000..c4d0b94
--- /dev/null
+++ b/nashorn/make/project.properties
@@ -0,0 +1,244 @@
+#
+# 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.
+#
+
+application.title=nashorn
+
+# location of JDK embedded ASM sources
+jdk.asm.src.dir=../jdk/src/share/classes/jdk/internal/org/objectweb/asm
+
+# source and target levels
+build.compiler=modern
+javac.source=1.7
+javac.target=1.7
+
+# nashorn version information
+nashorn.version=0.1
+nashorn.fullversion=0.1
+nashorn.product.name=Oracle Nashorn
+
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.classes.dir=${build.dir}/classes
+build.zip=${build.dir}/nashorn.zip
+build.gzip=${build.dir}/nashorn.tar.gz
+
+# nashorn Shell tool
+nashorn.shell.tool=jdk.nashorn.tools.Shell
+
+# nasgen tool
+nasgen.tool=jdk.nashorn.internal.tools.nasgen.Main
+
+# parallel test runner tool
+parallel.test.runner=jdk.nashorn.internal.test.framework.ParallelTestRunner
+
+# test classes directory
+build.test.classes.dir=${build.dir}/test/classes
+# nashorn test jar - internal tests jar and api tests jar
+nashorn.internal.tests.jar=${build.dir}/nashorn-internal-tests.jar
+nashorn.api.tests.jar=${build.dir}/nashorn-api-tests.jar
+
+# test results directory
+build.test.results.dir=${build.dir}/test/reports
+
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/nashorn.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+
+# jars refererred
+file.reference.testng.jar=test/lib/testng.jar
+
+# Set testng verbose level
+# From TestNG docs: "the verbosity level (0 to 10 where 10 is most detailed) 
+# Actually, this is a lie: you can specify -1 and this will put TestNG in 
+# debug mode (no longer slicing off stack traces and all)."
+
+testng.verbose=2
+
+# TestNG listeners - we want to replace TestNG's own JUnit
+# reporter, but want everything else provided by default
+# Unfortunately, we've to clone the other default reporters here.
+
+testng.listeners=\
+ org.testng.reporters.SuiteHTMLReporter, \
+ org.testng.reporters.jq.Main, \
+ org.testng.reporters.FailedReporter, \
+ org.testng.reporters.XMLReporter \
+ org.testng.reporters.EmailableReporter, \
+ jdk.nashorn.internal.test.framework.JSJUnitReportReporter
+
+javac.debug=true
+javac.encoding=ascii
+javac.classpath=\
+    ${build.classes.dir}
+javac.test.classpath=\
+    ${build.classes.dir}:\
+    ${build.test.classes.dir}:\
+    ${file.reference.testng.jar}
+
+meta.inf.dir=${src.dir}/META-INF
+
+run.classpath=\
+    ${build.classes.dir}
+
+# test scripts to run
+test.dir=test
+test.script.dir=test/script
+test.basic.dir=test/script/basic
+test.error.dir=test/script/error
+test.sandbox.dir=test/script/sandbox
+test.trusted.dir=test/script/trusted
+test.external.dir=test/script/external
+test262.dir=${test.external.dir}/test262
+test262.suite.dir=${test262.dir}/test/suite
+
+test-sys-prop.test.dir=${test.dir}
+test-sys-prop.test.js.roots=${test.basic.dir} ${test.error.dir} ${test.sandbox.dir} ${test.trusted.dir}
+test-sys-prop.test262.suite.dir=${test262.suite.dir}
+test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases
+test-sys-prop.test.basic.dir=${test.basic.dir}
+
+# framework root for our script tests
+test-sys-prop.test.js.framework=${test.script.dir}/assert.js
+
+# Control the verbosity of ParserTest
+test-sys-prop.parsertest.verbose=false
+
+# turn on/off scripting mode for parser tests
+test-sys-prop.parsertest.scripting=true
+
+# turn on/off test262 scripts for parser tests
+test-sys-prop.parsertest.test262=false
+
+# Control the verbosity of the CompilerTest
+test-sys-prop.compilertest.verbose=false
+
+# turn on/off scripting mode for compiler tests
+test-sys-prop.compilertest.scripting=true
+
+# turn on/off test262 scripts for compiler tests
+test-sys-prop.compilertest.test262=false
+
+# test directory to be excluded.
+test-sys-prop.test.js.exclude.dir=${test.script.dir}/currently-failing ${test.external.dir}
+
+# run everything that's js in here, without checking file headers for test annotations
+test-sys-prop.test.js.unchecked.dir=${test262.dir}
+
+# test root for octane
+octane-test-sys-prop.test.js.roots=${test.external.dir}/octane/
+
+# run octane benchmars in separate processes?
+octane-test-sys-prop.separate.process=true
+
+# framework root for octane
+octane-test-sys-prop.test.js.framework=${test.basic.dir}/run-octane.js
+
+# list of tests to be excluded
+# mandreel excluded due to OOM
+octane-test-sys-prop.test.js.exclude.list=\
+    base.js \
+    run.js  \
+    mandreel.js
+
+# test root for sunspider
+sunspider-test-sys-prop.test.js.roots=${test.external.dir}/sunspider/tests/sunspider-1.0/
+
+# framework root for sunspider
+sunspider-test-sys-prop.test.js.framework=${test.basic.dir}/runsunspider.js
+
+# list of tests to be excluded
+sunspider-test-sys-prop.test.js.exclude.list=
+
+# execute our script tests in shared nashorn context or not?
+test-sys-prop.test.js.shared.context=false
+
+# execute test262 tests in shared nashorn context or not?
+test262-test-sys-prop.test.js.shared.context=true
+
+# test262 test root
+test262-test-sys-prop.test.js.roots=${test262.suite.dir}
+# test262 enable/disable strict mode tests
+test262-test-sys-prop.test.js.enable.strict.mode=true
+
+# file containing test262 tests to be excluded
+# test262-test-sys-prop.test.js.excludes.file=${test262.dir}/test/config/excludelist.xml
+
+# list of test262 test dirs to be excluded
+test262-test-sys-prop.test.js.exclude.dir=\
+    ${test262.suite.dir}/intl402/
+
+# test262 test frameworks
+test262-test-sys-prop.test.js.framework=\
+    -timezone=PST \
+    ${test.script.dir}/test262.js \
+    ${test262.dir}/test/harness/framework.js \
+    ${test262.dir}/test/harness/sta.js
+
+run.test.classpath=\
+    ${file.reference.testng.jar}:\
+    ${nashorn.internal.tests.jar}:\
+    ${nashorn.api.tests.jar}
+
+src.dir=src
+test.src.dir=test/src
+
+run.test.xmx=3G
+run.test.xms=2G
+
+#  -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
+# add '-Dtest.js.outofprocess' to run each test in a new sub-process
+run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:-TieredCompilation -esa -ea -Dnashorn.debug=true -Dfile.encoding=UTF-8
+#-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M  
+run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs}
+
+run.test.jvmsecurityargs=-Xverify:all -Djava.security.properties=${basedir}/make/java.security.override -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy
+
+# path of rhino.jar for benchmarks
+rhino.jar=
+
+v8.shell=d8
+
+#path to rhino jar file
+octaneperf-sys-prop.rhino.jar=${rhino.jar}
+
+#timeout for performance tests in minutes
+octaneperf-sys-prop.timeout.value=10
+
+################
+# codecoverage #
+################
+	#enable/disable code coverage; please redifine in the ${user.home}/.nashorn.project.local.properties
+make.code.coverage=false
+	#type of codecoverage; one of static or dynamic. Now only dynamic is supported
+jcov=dynamic
+	#naming of CC results
+	#NB directory specified in the cc.dir will be cleaned up!!!
+cc.dir=${basedir}/../Codecoverage_Nashorn
+cc.result.file.name=cc_nashorn.xml
+	#dynamic CC parameters; please redefine in the ${user.home}/.nashorn.project.local.properties
+jcov2.lib.dir=${basedir}/../jcov2/lib
+jcov.jar=${jcov2.lib.dir}/jcov.jar
+cc.include=jdk\.nashorn\.*
+cc.exclude=jdk\.nashorn\.internal\.scripts\.*
+cc.dynamic.args=-javaagent:${jcov.jar}=include=${cc.include},exclude=${cc.exclude},type=all,verbose=0,file=${cc.dir}/${cc.result.file.name}
diff --git a/nashorn/makefiles/BuildNashorn.gmk b/nashorn/makefiles/BuildNashorn.gmk
new file mode 100644
index 0000000..d08f7e8
--- /dev/null
+++ b/nashorn/makefiles/BuildNashorn.gmk
@@ -0,0 +1,115 @@
+#
+# 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 must be the first rule
+default: all
+
+-include $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+
+JDK_CLASSES := $(JDK_OUTPUTDIR)/classes
+
+NASHORN_JAR := $(NASHORN_DIST)/nashorn.jar
+NASHORN_VERSION := $(JDK_VERSION)
+NASHORN_FULL_VERSION := $(FULL_VERSION)
+
+ifdef MILESTONE
+  ifeq ($(MILESTONE),internal)
+    NASHORN_VERSION = $(FULL_VERSION)
+  endif
+endif
+
+# Need to use source and target 7 for nasgen to work.
+$(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE_DEBUG,\
+    JVM:=$(JAVA),\
+    JAVAC:=$(NEW_JAVAC),\
+    FLAGS:=-g -source 7 -target 7 -bootclasspath $(JDK_CLASSES),\
+    SERVER_DIR:=$(SJAVAC_SERVER_DIR),\
+    SERVER_JVM:=$(SJAVAC_SERVER_JAVA)))
+
+# Build nashorn into intermediate directory
+$(eval $(call SetupJavaCompilation,BUILD_NASHORN,\
+    SETUP:=GENERATE_NEWBYTECODE_DEBUG,\
+    SRC:=$(NASHORN_TOPDIR)/src,\
+    COPY:=.properties .js,\
+    BIN:=$(NASHORN_OUTPUTDIR)/nashorn_classes))
+
+NASGEN_SRC := $(NASHORN_TOPDIR)/buildtools/nasgen/src
+ASM_SRC := $(JDK_TOPDIR)/src/share/classes/jdk/internal/org/objectweb/asm
+
+# Build nasgen
+$(eval $(call SetupJavaCompilation,BUILD_NASGEN,\
+    SETUP:=GENERATE_NEWBYTECODE_DEBUG,\
+    SRC:=$(NASGEN_SRC) $(ASM_SRC), \
+    BIN:=$(NASHORN_OUTPUTDIR)/nasgen_classes,\
+    ADD_JAVAC_FLAGS:=-cp $(NASHORN_OUTPUTDIR)/nashorn_classes))
+
+# Nasgen needs nashorn classes
+$(BUILD_NASGEN): $(BUILD_NASHORN)
+
+# Copy classes to final classes dir and run nasgen to modify classes in jdk.nashorn.internal.objects package
+# Finally rename classes in jdk.nashorn.internal.objects package
+$(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run: $(BUILD_NASGEN)
+	$(ECHO) Running nasgen
+	$(MKDIR) -p $(@D)
+	$(RM) -rf $(@D)/jdk $(@D)/netscape
+	$(CP) -R -p $(NASHORN_OUTPUTDIR)/nashorn_classes/* $(@D)/
+	$(FIXPATH) $(JAVA) \
+		-cp "$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
+		jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
+	for f in `$(FIND) $(@D)/jdk/nashorn/internal/objects/ -name "*.class"`; do \
+	  mv "$$f" `$(ECHO) "$$f" | $(SED) "s/\.class$$/\.clazz/"`; \
+        done
+	$(TOUCH) $@
+
+# Version file needs to be processed with version numbers
+VERSION_FILE := $(NASHORN_OUTPUTDIR)/classes/jdk/nashorn/internal/runtime/resources/version.properties
+# Needs to happen after nasgen run since nasgen run deletes it
+$(VERSION_FILE): $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run
+$(VERSION_FILE): $(NASHORN_TOPDIR)/src/jdk/nashorn/internal/runtime/resources/version.properties-template
+	$(ECHO) Creating version.properties
+	$(MKDIR) -p $(@D)
+	$(CAT) $< | $(SED) -e 's/$$(FULL_VERSION)/$(NASHORN_FULL_VERSION)/g' \
+		-e 's/$$(RELEASE)/$(NASHORN_VERSION)/g' \
+		-e '/^#.*$$/d' -e '/^$$/d'  > $@
+
+
+MANIFEST_ATTRIBUTES:=Name: jdk/nashorn/\nImplementation-Title: Oracle Nashorn\nImplementation-Version: $(NASHORN_FULL_VERSION)
+
+# Create nashorn.jar from the final classes dir
+$(eval $(call SetupArchive,BUILD_NASHORN_JAR,\
+    $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run \
+    $(VERSION_FILE),\
+    SRCS:=$(NASHORN_OUTPUTDIR)/classes,\
+    SUFFIXES:=.class .clazz .js .properties Factory,\
+    MANIFEST:=$(NASHORN_TOPDIR)/src/META-INF/MANIFEST.MF,\
+    EXTRA_MANIFEST_ATTR:=$(MANIFEST_ATTRIBUTES),\
+    SKIP_METAINF:=true,\
+    JAR:=$(NASHORN_JAR)))
+
+all: $(NASHORN_JAR)
+    
+.PHONY: all
diff --git a/nashorn/makefiles/Makefile b/nashorn/makefiles/Makefile
new file mode 100644
index 0000000..9539fe0
--- /dev/null
+++ b/nashorn/makefiles/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Locate this Makefile
+ifeq ($(filter /%,$(lastword $(MAKEFILE_LIST))),)
+    makefile_path:=$(CURDIR)/$(lastword $(MAKEFILE_LIST))
+else
+    makefile_path:=$(lastword $(MAKEFILE_LIST))
+endif
+repo_dir:=$(patsubst %/makefiles/Makefile,%,$(makefile_path))
+
+# What is the name of this subsystem (langtools, corba, etc)?
+subsystem_name:=$(notdir $(repo_dir))
+
+# Try to locate top-level makefile
+top_level_makefile:=$(repo_dir)/../common/makefiles/Makefile
+ifneq ($(wildcard $(top_level_makefile)),)
+  $(info Will run $(subsystem_name) target on top-level Makefile)
+  $(info WARNING: This is a non-recommended way of building!)
+  $(info ===================================================)
+else
+  $(info Cannot locate top-level Makefile. Is this repo not checked out as part of a complete forest?)
+  $(error Build from top-level Makefile instead)
+endif
+
+all:
+	@$(MAKE) -f $(top_level_makefile) $(subsystem_name)
diff --git a/nashorn/samples/counters.js b/nashorn/samples/counters.js
new file mode 100644
index 0000000..226ec3d
--- /dev/null
+++ b/nashorn/samples/counters.js
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * This file can be run along with any script you want to run
+ * to print aggregate stat counters from nashorn.
+ *
+ * Usage:  jjs <your-file.js> counters.js
+ */
+
+Debug.dumpCounters();
diff --git a/nashorn/samples/letter.js b/nashorn/samples/letter.js
new file mode 100644
index 0000000..cbee92d
--- /dev/null
+++ b/nashorn/samples/letter.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Demonstrates "heredoc" feature with "scripting" mode.
+ *
+ * Usage: jjs -scripting letter.js -- <sender> <recipient>
+ */
+
+# This is shell-style line comment
+var obj = { sender: $ARG[0], recipient: $ARG[1] };
+
+// JavaScript style line comment is ok too.
+print(<<EOF);
+Dear ${obj.recipient},
+ 
+I wish you all the best.
+
+Regards,
+${obj.sender}
+EOF
diff --git a/nashorn/samples/parser.js b/nashorn/samples/parser.js
new file mode 100644
index 0000000..2f172cc
--- /dev/null
+++ b/nashorn/samples/parser.js
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * Simple sample demonstrating parser API.
+ */
+
+load("nashorn:parser.js");
+try {
+    var json = parse("print('hello')");
+    print(JSON.stringify(json));
+} catch (e) {
+    print(e);
+}
diff --git a/nashorn/samples/shell.js b/nashorn/samples/shell.js
new file mode 100644
index 0000000..fc4ce9a
--- /dev/null
+++ b/nashorn/samples/shell.js
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * This is a simple shell tool in JavaScript.
+ *
+ * Runs any operating system command using Java "exec". When "eval" command is
+ * used, evaluates argument(s) as JavaScript code.
+ */
+
+var imports = new JavaImporter(java.io, java.lang, java.util);
+
+function prompt() {
+    java.lang.System.out.print(">");
+}
+
+with (imports) {
+    var reader = new BufferedReader(new InputStreamReader(System["in"]));
+    var line = null;
+    prompt();
+    while ((line = reader.readLine()) != null) {
+        if (line != "") {
+            var args = line.split(" ");
+            try {
+                if (args[0] == "eval") {
+                    var code = line.substring("eval".length);
+                    var res = eval(code);
+                    if (res != undefined) {
+                        print(res);
+                    }
+                } else {
+                    var argList = new ArrayList();
+                    for (i in args) { argList.add(args[i]); }                
+                    var procBuilder = new ProcessBuilder(argList);
+                    procBuilder.redirectErrorStream();
+                    var proc = procBuilder.start();
+                    var out = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+                    var line = null;
+                    while ((line = out.readLine()) != null) {
+                        System.out.println(line);
+                    }
+                    proc.waitFor();
+                }
+            } catch (e) {
+                print(e);
+            }
+        }
+        prompt();
+    }
+}
diff --git a/nashorn/samples/test.js b/nashorn/samples/test.js
new file mode 100644
index 0000000..e2f8c93
--- /dev/null
+++ b/nashorn/samples/test.js
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+print("Hello World");
diff --git a/nashorn/samples/uniq.js b/nashorn/samples/uniq.js
new file mode 100644
index 0000000..3da8480
--- /dev/null
+++ b/nashorn/samples/uniq.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Prints unique lines from a given file.
+ */
+
+if (arguments.length != 1) {
+    print("Usage: jjs uniq.js -- <file>");
+    java.lang.System.exit(1);
+}
+
+var imports = new JavaImporter(java.io);
+
+var uniqueLines = {};
+with (imports) {
+    var reader = new BufferedReader(new FileReader(arguments[0]));
+    while ((line = reader.readLine()) != null) {
+        // using a JS object as a map...
+        uniqueLines[line] = true;
+    }
+}
+
+// now print the collected lines
+for (i in uniqueLines) {
+    print(i);
+}
diff --git a/nashorn/src/META-INF/MANIFEST.MF b/nashorn/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..b61190e
--- /dev/null
+++ b/nashorn/src/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0

+Main-Class: jdk.nashorn.tools.Shell

+

+Name: jdk/nashorn/

+Implementation-Vendor: Oracle Corporation

diff --git a/nashorn/src/META-INF/services/javax.script.ScriptEngineFactory b/nashorn/src/META-INF/services/javax.script.ScriptEngineFactory
new file mode 100644
index 0000000..60a8f56
--- /dev/null
+++ b/nashorn/src/META-INF/services/javax.script.ScriptEngineFactory
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+jdk.nashorn.api.scripting.NashornScriptEngineFactory
diff --git a/nashorn/src/jdk/internal/dynalink/CallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/CallSiteDescriptor.java
new file mode 100644
index 0000000..c2bf93b
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/CallSiteDescriptor.java
@@ -0,0 +1,174 @@
+/*
+ * 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;
+
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+
+/**
+ * An immutable descriptor of a call site. It is an immutable object that contains all the information about a call
+ * site: the class performing the lookups, the name of the method being invoked, and the method signature. The library
+ * has a default {@link CallSiteDescriptorFactory} for descriptors that you can use, or you can create your own
+ * descriptor classes, especially if you need to add further information (values passed in additional parameters to the
+ * bootstrap method) to them. Call site descriptors are used in this library in place of passing a real call site to
+ * guarding linkers so they aren't tempted to directly manipulate the call sites. The constructors of built-in
+ * {@link RelinkableCallSite} implementations all need a call site descriptor. Even if you create your own call site
+ * descriptors consider using {@link CallSiteDescriptorFactory#tokenizeName(String)} in your implementation.
+ *
+ * @author Attila Szegedi
+ */
+public interface CallSiteDescriptor {
+    /**
+     * The index of the name token that will carry the operation scheme prefix (usually, "dyn").
+     */
+    public static final int SCHEME = 0;
+    /**
+     * The index of the name token that will usually carry the operation name.
+     */
+
+    public static final int OPERATOR=1;
+    /**
+     * The index of the name token that will usually carry a name of an operand (of a property, method, etc.)
+     */
+
+    public static final int NAME_OPERAND=2;
+
+    /**
+     * Character used to delimit tokens in an call site name.
+     */
+    public static final String TOKEN_DELIMITER = ":";
+
+    /**
+     * Character used to delimit operation names in a composite operation specification.
+     */
+    public static final String OPERATOR_DELIMITER = "|";
+
+    /**
+     * Returns the number of tokens in the name of the method at the call site. Method names are tokenized with the
+     * colon ":" character, i.e. "dyn:getProp:color" would be the name used to describe a method that retrieves the
+     * property named "color" on the object it is invoked on.
+     * @return the number of tokens in the name of the method at the call site.
+     */
+    public int getNameTokenCount();
+
+    /**
+     * Returns the <i>i<sup>th</sup></i> token in the method name at the call site. Method names are tokenized with the
+     * colon ":" character.
+     * @param i the index of the token. Must be between 0 (inclusive) and {@link #getNameTokenCount()} (exclusive)
+     * @throws IllegalArgumentException if the index is outside the allowed range.
+     * @return the <i>i<sup>th</sup></i> token in the method name at the call site. The returned strings are interned.
+     */
+    public String getNameToken(int i);
+
+    /**
+     * Returns the name of the method at the call site. Note that the object internally only stores the tokenized name,
+     * and has to reconstruct the full name from tokens on each invocation.
+     * @return the name of the method at the call site.
+     */
+    public String getName();
+
+    /**
+     * The type of the method at the call site.
+     *
+     * @return type of the method at the call site.
+     */
+    public MethodType getMethodType();
+
+    /**
+     * Returns the lookup passed to the bootstrap method.
+     * @return the lookup passed to the bootstrap method.
+     */
+    public Lookup getLookup();
+
+    /**
+     * Creates a new call site descriptor from this descriptor, which is identical to this, except it changes the method
+     * type.
+     *
+     * @param newMethodType the new method type
+     * @return a new call site descriptor, with the method type changed.
+     */
+    public CallSiteDescriptor changeMethodType(MethodType newMethodType);
+
+}
diff --git a/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java b/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java
new file mode 100644
index 0000000..c242fed
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java
@@ -0,0 +1,211 @@
+/*
+ * 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;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicReference;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.support.AbstractRelinkableCallSite;
+
+/**
+ * A relinkable call site that maintains a chain of linked method handles. In the default implementation, up to 8 method
+ * handles can be chained, cascading from one to the other through
+ * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}. When this call site has to link a new
+ * method handle and the length of the chain is already at the maximum, it will throw away the oldest method handle.
+ * Switchpoint-invalidated handles in the chain are removed eagerly (on each linking request, and whenever a
+ * switchpoint-invalidated method handle is traversed during invocation). There is currently no profiling
+ * attached to the handles in the chain, so they are never reordered based on usage; the most recently linked method
+ * handle is always at the start of the chain.
+ */
+public class ChainedCallSite extends AbstractRelinkableCallSite {
+    private final AtomicReference<LinkedList<GuardedInvocation>> invocations = new AtomicReference<>();
+
+    /**
+     * Creates a new chained call site.
+     * @param descriptor the descriptor for the call site.
+     */
+    public ChainedCallSite(CallSiteDescriptor descriptor) {
+        super(descriptor);
+    }
+
+    /**
+     * The maximum number of method handles in the chain. Defaults to 8. You can override it in a subclass if you need
+     * to change the value. If your override returns a value less than 1, the code will break.
+     * @return the maximum number of method handles in the chain.
+     */
+    @SuppressWarnings("static-method")
+    protected int getMaxChainLength() {
+        return 8;
+    }
+
+    @Override
+    public void relink(GuardedInvocation guardedInvocation, MethodHandle fallback) {
+        relinkInternal(guardedInvocation, fallback, false);
+    }
+
+    @Override
+    public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle fallback) {
+        relinkInternal(guardedInvocation, fallback, true);
+    }
+
+    private MethodHandle relinkInternal(GuardedInvocation invocation, MethodHandle relink, boolean reset) {
+        final LinkedList<GuardedInvocation> currentInvocations = invocations.get();
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        final LinkedList<GuardedInvocation> newInvocations =
+            currentInvocations == null || reset ? new LinkedList<>() : (LinkedList)currentInvocations.clone();
+
+        // First, prune the chain of invalidated switchpoints.
+        for(Iterator<GuardedInvocation> it = newInvocations.iterator(); it.hasNext();) {
+            if(it.next().hasBeenInvalidated()) {
+                it.remove();
+            }
+        }
+
+        // prune() is allowed to invoke this method with invocation == null meaning we're just pruning the chain and not
+        // adding any new invocations to it.
+        if(invocation != null) {
+            // Remove oldest entry if we're at max length
+            if(newInvocations.size() == getMaxChainLength()) {
+                newInvocations.removeFirst();
+            }
+            newInvocations.addLast(invocation);
+        }
+
+        // prune-and-invoke is used as the fallback for invalidated switchpoints. If a switchpoint gets invalidated, we
+        // rebuild the chain and get rid of all invalidated switchpoints instead of letting them linger.
+        final MethodHandle pruneAndInvoke = makePruneAndInvokeMethod(relink);
+
+        // Fold the new chain
+        MethodHandle target = relink;
+        for(GuardedInvocation inv: newInvocations) {
+            target = inv.compose(pruneAndInvoke, target);
+        }
+
+        // If nobody else updated the call site while we were rebuilding the chain, set the target to our chain. In case
+        // we lost the race for multithreaded update, just do nothing. Either the other thread installed the same thing
+        // we wanted to install, or otherwise, we'll be asked to relink again.
+        if(invocations.compareAndSet(currentInvocations, newInvocations)) {
+            setTarget(target);
+        }
+        return target;
+    }
+
+    /**
+     * Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that
+     * chain.
+     * @param relink the ultimate fallback for the chain (the {@code DynamicLinker}'s relink).
+     * @return a method handle for prune-and-invoke
+     */
+    private MethodHandle makePruneAndInvokeMethod(MethodHandle relink) {
+        // Bind prune to (this, relink)
+        final MethodHandle boundPrune = MethodHandles.insertArguments(PRUNE, 0, this, relink);
+        // Make it ignore all incoming arguments
+        final MethodHandle ignoreArgsPrune = MethodHandles.dropArguments(boundPrune, 0, type().parameterList());
+        // Invoke prune, then invoke the call site target with original arguments
+        return MethodHandles.foldArguments(MethodHandles.exactInvoker(type()), ignoreArgsPrune);
+    }
+
+    @SuppressWarnings("unused")
+    private MethodHandle prune(MethodHandle relink) {
+        return relinkInternal(null, relink, false);
+    }
+
+    private static final MethodHandle PRUNE;
+    static {
+        try {
+            PRUNE = MethodHandles.lookup().findSpecial(ChainedCallSite.class, "prune", MethodType.methodType(
+                    MethodHandle.class, MethodHandle.class), ChainedCallSite.class);
+        // NOTE: using two catch blocks so we don't introduce a reference to 1.7 ReflectiveOperationException, allowing
+        // Dynalink to be used on 1.6 JVMs with Remi's backport library.
+        } catch(IllegalAccessException e) {
+            throw new AssertionError(e.getMessage(), e); // Can not happen
+        } catch(NoSuchMethodException e) {
+            throw new AssertionError(e.getMessage(), e); // Can not happen
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java b/nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java
new file mode 100644
index 0000000..c62afe6
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java
@@ -0,0 +1,143 @@
+/*
+ * 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;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+
+/**
+ * A convenience default bootstrapper that exposes static bootstrap methods which language runtimes that need the very
+ * default behavior can use with minimal setup. When first referenced, it will create a dynamic linker with default
+ * settings for the {@link DynamicLinkerFactory}, and its bootstrap methods will create {@link MonomorphicCallSite} for
+ * all call sites. It has two bootstrap methods: one creates call sites that use the
+ * {@link MethodHandles#publicLookup()} as the lookup for all call sites and disregard the one passed in as the caller,
+ * and one that just uses the passed caller as the lookup scope. Using the public lookup one is advised if your language
+ * runtime has no concept of interacting with Java visibility scopes, as it results in a more lightweight runtime
+ * information.
+ *
+ * @author Attila Szegedi
+ */
+public class DefaultBootstrapper {
+    private static final DynamicLinker dynamicLinker = new DynamicLinkerFactory().createLinker();
+
+    private DefaultBootstrapper() {
+    }
+
+    /**
+     * Use this method as your bootstrap method (see the documentation of the java.lang.invoke package for how to do
+     * this). In case your language runtime doesn't have a concept of interaction with Java access scopes, you might
+     * want to consider using
+     * {@link #publicBootstrap(java.lang.invoke.MethodHandles.Lookup, String, MethodType)} instead.
+     *
+     * @param caller the caller's lookup
+     * @param name the name of the method at the call site
+     * @param type the method signature at the call site
+     * @return a new {@link MonomorphicCallSite} linked with the default dynamic linker.
+     */
+    public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
+        return bootstrapInternal(caller, name, type);
+    }
+
+    /**
+     * Use this method as your bootstrap method (see the documentation of the java.lang.invoke package for how to do
+     * this) when your language runtime doesn't have a concept of interaction with Java access scopes. If you need to
+     * preserve the different caller Lookup objects in the call sites, use
+     * {@link #bootstrap(java.lang.invoke.MethodHandles.Lookup, String, MethodType)} instead
+     *
+     * @param caller the caller's lookup. It is ignored as the call sites will be created with
+     * {@link MethodHandles#publicLookup()} instead.
+     * @param name the name of the method at the call site
+     * @param type the method signature at the call site
+     * @return a new {@link MonomorphicCallSite} linked with the default dynamic linker.
+     */
+    public static CallSite publicBootstrap(@SuppressWarnings("unused") MethodHandles.Lookup caller, String name, MethodType type) {
+        return bootstrapInternal(MethodHandles.publicLookup(), name, type);
+    }
+
+    private static CallSite bootstrapInternal(MethodHandles.Lookup caller, String name, MethodType type) {
+        return dynamicLinker.link(new MonomorphicCallSite(CallSiteDescriptorFactory.create(caller, name, type)));
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/DynamicLinker.java b/nashorn/src/jdk/internal/dynalink/DynamicLinker.java
new file mode 100644
index 0000000..c0930da
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/DynamicLinker.java
@@ -0,0 +1,281 @@
+/*
+ * 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;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.util.List;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.internal.dynalink.support.LinkRequestImpl;
+import jdk.internal.dynalink.support.Lookup;
+import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
+
+/**
+ * The linker for {@link RelinkableCallSite} objects. Users of it (scripting frameworks and language runtimes) have to
+ * create a linker using the {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic bootstrap
+ * methods to set the target of all the call sites in the code they generate. Usual usage would be to create one class
+ * per language runtime to contain one linker instance as:
+ *
+ * <pre>
+ * class MyLanguageRuntime {
+ *     private static final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker();
+ *     private static final DynamicLinker dynamicLinker = createDynamicLinker();
+ *
+ *     private static DynamicLinker createDynamicLinker() {
+ *         final DynamicLinkerFactory factory = new DynamicLinkerFactory();
+ *         factory.setPrioritizedLinker(myLanguageLinker);
+ *         return factory.createLinker();
+ *     }
+ *
+ *     public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
+ *         return dynamicLinker.link(new MonomorphicCallSite(CallSiteDescriptorFactory.create(lookup, name, type)));
+ *     }
+ * }
+ * </pre>
+ *
+ * Note how there are three components you will need to provide here:
+ * <ul>
+ * <li>You're expected to provide a {@link GuardingDynamicLinker} for your own language. If your runtime doesn't
+ * have its own language and/or object model (i.e. it's a generic scripting shell), you don't need to implement a
+ * dynamic linker; you would simply not invoke the {@code setPrioritizedLinker} method on the factory, or even better,
+ * simply use {@link DefaultBootstrapper}.</li>
+ * <li>The performance of the programs can depend on your choice of the class to represent call sites. The above
+ * example used {@link MonomorphicCallSite}, but you might want to use {@link ChainedCallSite} instead. You'll need to
+ * experiment and decide what fits your language runtime the best. You can subclass either of these or roll your own if
+ * you need to.</li>
+ * <li>You also need to provide {@link CallSiteDescriptor}s to your call sites. They are immutable objects that contain
+ * all the information about the call site: the class performing the lookups, the name of the method being invoked, and
+ * the method signature. The library has a default {@link CallSiteDescriptorFactory} for descriptors that you can use,
+ * or you can create your own descriptor classes, especially if you need to add further information (values passed in
+ * additional parameters to the bootstrap method) to them.</li>
+ * </ul>
+ *
+ * @author Attila Szegedi
+ */
+public class DynamicLinker {
+
+    private static final String CLASS_NAME = DynamicLinker.class.getName();
+    private static final String RELINK_METHOD_NAME = "relink";
+
+    private final LinkerServices linkerServices;
+    private final int runtimeContextArgCount;
+    private final boolean syncOnRelink;
+    private final int unstableRelinkThreshold;
+
+    /**
+     * Creates a new dynamic linker.
+     *
+     * @param linkerServices the linkerServices used by the linker, created by the factory.
+     * @param runtimeContextArgCount see {@link DynamicLinkerFactory#setRuntimeContextArgCount(int)}
+     */
+    DynamicLinker(LinkerServices linkerServices, int runtimeContextArgCount, boolean syncOnRelink,
+            int unstableRelinkThreshold) {
+        if(runtimeContextArgCount < 0) {
+            throw new IllegalArgumentException("runtimeContextArgCount < 0");
+        }
+        if(unstableRelinkThreshold < 0) {
+            throw new IllegalArgumentException("unstableRelinkThreshold < 0");
+        }
+        this.runtimeContextArgCount = runtimeContextArgCount;
+        this.linkerServices = linkerServices;
+        this.syncOnRelink = syncOnRelink;
+        this.unstableRelinkThreshold = unstableRelinkThreshold;
+    }
+
+    /**
+     * Links an invokedynamic call site. It will install a method handle into the call site that invokes the relinking
+     * mechanism of this linker. Next time the call site is invoked, it will be linked for the actual arguments it was
+     * invoked with.
+     *
+     * @param callSite the call site to link.
+     * @return the callSite, for easy call chaining.
+     */
+    public <T extends RelinkableCallSite> T link(final T callSite) {
+        callSite.initialize(createRelinkAndInvokeMethod(callSite, 0));
+        return callSite;
+    }
+
+    /**
+     * Returns the object representing the lower level linker services of this class that are normally exposed to
+     * individual language-specific linkers. While as a user of this class you normally only care about the
+     * {@link #link(RelinkableCallSite)} method, in certain circumstances you might want to use the lower level services
+     * directly; either to lookup specific method handles, to access the type converters, and so on.
+     * @return the object representing the linker services of this class.
+     */
+    public LinkerServices getLinkerServices() {
+        return linkerServices;
+    }
+
+    private static final MethodHandle RELINK = Lookup.findOwnSpecial(MethodHandles.lookup(), RELINK_METHOD_NAME,
+            MethodHandle.class, RelinkableCallSite.class, int.class, Object[].class);
+
+    private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, int relinkCount) {
+        // Make a bound MH of invoke() for this linker and call site
+        final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf(
+                relinkCount));
+        // Make a MH that gathers all arguments to the invocation into an Object[]
+        final MethodType type = callSite.getDescriptor().getMethodType();
+        final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount());
+        return MethodHandles.foldArguments(MethodHandles.exactInvoker(type), collectingRelinker.asType(
+                type.changeReturnType(MethodHandle.class)));
+    }
+
+    /**
+     * Relinks a call site conforming to the invocation arguments.
+     *
+     * @param callSite the call site itself
+     * @param arguments arguments to the invocation
+     * @return return the method handle for the invocation
+     * @throws Exception rethrows any exception thrown by the linkers
+     */
+    @SuppressWarnings("unused")
+    private MethodHandle relink(RelinkableCallSite callSite, int relinkCount, Object... arguments) throws Exception {
+        final CallSiteDescriptor callSiteDescriptor = callSite.getDescriptor();
+        final boolean unstableDetectionEnabled = unstableRelinkThreshold > 0;
+        final boolean callSiteUnstable = unstableDetectionEnabled && relinkCount >= unstableRelinkThreshold;
+        final LinkRequest linkRequest =
+                runtimeContextArgCount == 0 ? new LinkRequestImpl(callSiteDescriptor, callSiteUnstable, arguments)
+                        : new RuntimeContextLinkRequestImpl(callSiteDescriptor, callSiteUnstable, arguments,
+                                runtimeContextArgCount);
+
+        // Find a suitable method handle with a guard
+        GuardedInvocation guardedInvocation = linkerServices.getGuardedInvocation(linkRequest);
+
+        // None found - throw an exception
+        if(guardedInvocation == null) {
+            throw new NoSuchDynamicMethodException(callSiteDescriptor.toString());
+        }
+
+        // If our call sites have a runtime context, and the linker produced a context-stripped invocation, adapt the
+        // produced invocation into contextual invocation (by dropping the context...)
+        if(runtimeContextArgCount > 0) {
+            final MethodType origType = callSiteDescriptor.getMethodType();
+            final MethodHandle invocation = guardedInvocation.getInvocation();
+            if(invocation.type().parameterCount() == origType.parameterCount() - runtimeContextArgCount) {
+                final List<Class<?>> prefix = origType.parameterList().subList(1, runtimeContextArgCount + 1);
+                final MethodHandle guard = guardedInvocation.getGuard();
+                guardedInvocation = guardedInvocation.dropArguments(1, prefix);
+            }
+        }
+
+        int newRelinkCount = relinkCount;
+        // Note that the short-circuited "&&" evaluation below ensures we'll increment the relinkCount until
+        // threshold + 1 but not beyond that. Threshold + 1 is treated as a special value to signal that resetAndRelink
+        // has already executed once for the unstable call site; we only want the call site to throw away its current
+        // linkage once, when it transitions to unstable.
+        if(unstableDetectionEnabled && newRelinkCount <= unstableRelinkThreshold && newRelinkCount++ == unstableRelinkThreshold) {
+            callSite.resetAndRelink(guardedInvocation, createRelinkAndInvokeMethod(callSite, newRelinkCount));
+        } else {
+            callSite.relink(guardedInvocation, createRelinkAndInvokeMethod(callSite, newRelinkCount));
+        }
+        if(syncOnRelink) {
+            MutableCallSite.syncAll(new MutableCallSite[] { (MutableCallSite)callSite });
+        }
+        return guardedInvocation.getInvocation();
+    }
+
+    /**
+     * Returns a stack trace element describing the location of the call site currently being relinked on the current
+     * thread. The operation internally creates a Throwable object and inspects its stack trace, so it's potentially
+     * expensive. The recommended usage for it is in writing diagnostics code.
+     * @return a stack trace element describing the location of the call site currently being relinked, or null if it is
+     * not invoked while a call site is being relinked.
+     */
+    public static StackTraceElement getRelinkedCallSiteLocation() {
+        final StackTraceElement[] trace = new Throwable().getStackTrace();
+        for(int i = 0; i < trace.length - 1; ++i) {
+            final StackTraceElement frame = trace[i];
+            if(RELINK_METHOD_NAME.equals(frame.getMethodName()) && CLASS_NAME.equals(frame.getClassName())) {
+                return trace[i + 1];
+            }
+        }
+        return null;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java b/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java
new file mode 100644
index 0000000..0f0a347
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java
@@ -0,0 +1,312 @@
+/*
+ * 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;
+
+import java.lang.invoke.MutableCallSite;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.support.AutoDiscovery;
+import jdk.internal.dynalink.support.BottomGuardingDynamicLinker;
+import jdk.internal.dynalink.support.CompositeGuardingDynamicLinker;
+import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.LinkerServicesImpl;
+import jdk.internal.dynalink.support.TypeConverterFactory;
+
+/**
+ * A factory class for creating {@link DynamicLinker}s. The most usual dynamic linker is a linker that is a composition
+ * of all {@link GuardingDynamicLinker}s known and pre-created by the caller as well as any
+ * {@link AutoDiscovery automatically discovered} guarding linkers and the standard fallback {@link BeansLinker}. See
+ * {@link DynamicLinker} documentation for tips on how to use this class.
+ *
+ * @author Attila Szegedi
+ */
+public class DynamicLinkerFactory {
+
+    /**
+     * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink threshold}.
+     */
+    public static final int DEFAULT_UNSTABLE_RELINK_THRESHOLD = 8;
+
+    private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+    private List<? extends GuardingDynamicLinker> prioritizedLinkers;
+    private List<? extends GuardingDynamicLinker> fallbackLinkers;
+    private int runtimeContextArgCount = 0;
+    private boolean syncOnRelink = false;
+    private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD;
+
+    /**
+     * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread
+     * context class loader at the time of the constructor invocation will be used.
+     *
+     * @param classLoader the class loader used for the autodiscovery of available linkers.
+     */
+    public void setClassLoader(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
+    /**
+     * Sets the prioritized linkers. Language runtimes using this framework will usually precreate at least the linker
+     * for their own language. These linkers will be consulted first in the resulting dynamic linker, before any
+     * autodiscovered linkers. If the framework also autodiscovers a linker of the same class as one of the prioritized
+     * linkers, it will be ignored and the explicit prioritized instance will be used.
+     *
+     * @param prioritizedLinkers the list of prioritized linkers. Null can be passed to indicate no prioritized linkers
+     * (this is also the default value).
+     */
+    public void setPrioritizedLinkers(List<? extends GuardingDynamicLinker> prioritizedLinkers) {
+        this.prioritizedLinkers =
+                prioritizedLinkers == null ? null : new ArrayList<>(prioritizedLinkers);
+    }
+
+    /**
+     * Sets the prioritized linkers. Language runtimes using this framework will usually precreate at least the linker
+     * for their own language. These linkers will be consulted first in the resulting dynamic linker, before any
+     * autodiscovered linkers. If the framework also autodiscovers a linker of the same class as one of the prioritized
+     * linkers, it will be ignored and the explicit prioritized instance will be used.
+     *
+     * @param prioritizedLinkers a list of prioritized linkers.
+     */
+    public void setPrioritizedLinkers(GuardingDynamicLinker... prioritizedLinkers) {
+        setPrioritizedLinkers(Arrays.asList(prioritizedLinkers));
+    }
+
+    /**
+     * Sets a single prioritized linker. Identical to calling {@link #setPrioritizedLinkers(List)} with a single-element
+     * list.
+     *
+     * @param prioritizedLinker the single prioritized linker. Must not be null.
+     * @throws IllegalArgumentException if null is passed.
+     */
+    public void setPrioritizedLinker(GuardingDynamicLinker prioritizedLinker) {
+        if(prioritizedLinker == null) {
+            throw new IllegalArgumentException("prioritizedLinker == null");
+        }
+        this.prioritizedLinkers = Collections.singletonList(prioritizedLinker);
+    }
+
+    /**
+     * Sets the fallback linkers. These linkers will be consulted last in the resulting composite linker, after any
+     * autodiscovered linkers. If the framework also autodiscovers a linker of the same class as one of the fallback
+     * linkers, it will be ignored and the explicit fallback instance will be used.
+     *
+     * @param fallbackLinkers the list of fallback linkers. Can be empty to indicate the caller wishes to set no
+     * fallback linkers.
+     */
+    public void setFallbackLinkers(List<? extends GuardingDynamicLinker> fallbackLinkers) {
+        this.fallbackLinkers = fallbackLinkers == null ? null : new ArrayList<>(fallbackLinkers);
+    }
+
+    /**
+     * Sets the fallback linkers. These linkers will be consulted last in the resulting composite linker, after any
+     * autodiscovered linkers. If the framework also autodiscovers a linker of the same class as one of the fallback
+     * linkers, it will be ignored and the explicit fallback instance will be used.
+     *
+     * @param fallbackLinkers the list of fallback linkers. Can be empty to indicate the caller wishes to set no
+     * fallback linkers. If it is left as null, the standard fallback {@link BeansLinker} will be used.
+     */
+    public void setFallbackLinkers(GuardingDynamicLinker... fallbackLinkers) {
+        setFallbackLinkers(Arrays.asList(fallbackLinkers));
+    }
+
+    /**
+     * Sets the number of arguments in the call sites that represent the stack context of the language runtime creating
+     * the linker. If the language runtime uses no context information passed on stack, then it should be zero
+     * (the default value). If it is set to nonzero value, then every dynamic call site emitted by this runtime must
+     * have the argument list of the form: {@code (this, contextArg1[, contextArg2[, ...]], normalArgs)}. It is
+     * advisable to only pass one context-specific argument, though, of an easily recognizable, runtime specific type
+     * encapsulating the runtime thread local state.
+     *
+     * @param runtimeContextArgCount the number of language runtime context arguments in call sites.
+     */
+    public void setRuntimeContextArgCount(int runtimeContextArgCount) {
+        if(runtimeContextArgCount < 0) {
+            throw new IllegalArgumentException("runtimeContextArgCount < 0");
+        }
+        this.runtimeContextArgCount = runtimeContextArgCount;
+    }
+
+    /**
+     * Sets whether the linker created by this factory will invoke {@link MutableCallSite#syncAll(MutableCallSite[])}
+     * after a call site is relinked. Defaults to false. You probably want to set it to true if your runtime supports
+     * multithreaded execution of dynamically linked code.
+     * @param syncOnRelink true for invoking sync on relink, false otherwise.
+     */
+    public void setSyncOnRelink(boolean syncOnRelink) {
+        this.syncOnRelink = syncOnRelink;
+    }
+
+    /**
+     * Sets the unstable relink threshold; the number of times a call site is relinked after which it will be
+     * considered unstable, and subsequent link requests for it will indicate this.
+     * @param unstableRelinkThreshold the new threshold. Must not be less than zero. The value of zero means that
+     * call sites will never be considered unstable.
+     * @see LinkRequest#isCallSiteUnstable()
+     */
+    public void setUnstableRelinkThreshold(int unstableRelinkThreshold) {
+        if(unstableRelinkThreshold < 0) {
+            throw new IllegalArgumentException("unstableRelinkThreshold < 0");
+        }
+        this.unstableRelinkThreshold = unstableRelinkThreshold;
+    }
+
+    /**
+     * Creates a new dynamic linker consisting of all the prioritized, autodiscovered, and fallback linkers.
+     *
+     * @return the new dynamic Linker
+     */
+    public DynamicLinker createLinker() {
+        // Treat nulls appropriately
+        if(prioritizedLinkers == null) {
+            prioritizedLinkers = Collections.emptyList();
+        }
+        if(fallbackLinkers == null) {
+            fallbackLinkers = Collections.singletonList(new BeansLinker());
+        }
+
+        // Gather classes of all precreated (prioritized and fallback) linkers.
+        // We'll filter out any discovered linkers of the same class.
+        final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses =
+                new HashSet<>();
+        addClasses(knownLinkerClasses, prioritizedLinkers);
+        addClasses(knownLinkerClasses, fallbackLinkers);
+
+        final List<GuardingDynamicLinker> discovered = AutoDiscovery.loadLinkers(classLoader);
+        // Now, concatenate ...
+        final List<GuardingDynamicLinker> linkers =
+                new ArrayList<>(prioritizedLinkers.size() + discovered.size()
+                        + fallbackLinkers.size());
+        // ... prioritized linkers, ...
+        linkers.addAll(prioritizedLinkers);
+        // ... filtered discovered linkers, ...
+        for(GuardingDynamicLinker linker: discovered) {
+            if(!knownLinkerClasses.contains(linker.getClass())) {
+                linkers.add(linker);
+            }
+        }
+        // ... and finally fallback linkers.
+        linkers.addAll(fallbackLinkers);
+        final List<GuardingDynamicLinker> optimized = CompositeTypeBasedGuardingDynamicLinker.optimize(linkers);
+        final GuardingDynamicLinker composite;
+        switch(linkers.size()) {
+            case 0: {
+                composite = BottomGuardingDynamicLinker.INSTANCE;
+                break;
+            }
+            case 1: {
+                composite = optimized.get(0);
+                break;
+            }
+            default: {
+                composite = new CompositeGuardingDynamicLinker(optimized);
+                break;
+            }
+        }
+
+        final List<GuardingTypeConverterFactory> typeConverters = new LinkedList<>();
+        for(GuardingDynamicLinker linker: linkers) {
+            if(linker instanceof GuardingTypeConverterFactory) {
+                typeConverters.add((GuardingTypeConverterFactory)linker);
+            }
+        }
+
+        return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters), composite),
+                runtimeContextArgCount, syncOnRelink, unstableRelinkThreshold);
+    }
+
+    private static void addClasses(Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,
+            List<? extends GuardingDynamicLinker> linkers) {
+        for(GuardingDynamicLinker linker: linkers) {
+            knownLinkerClasses.add(linker.getClass());
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/MonomorphicCallSite.java b/nashorn/src/jdk/internal/dynalink/MonomorphicCallSite.java
new file mode 100644
index 0000000..7f1bbed
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/MonomorphicCallSite.java
@@ -0,0 +1,115 @@
+/*
+ * 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;
+
+import java.lang.invoke.MethodHandle;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.support.AbstractRelinkableCallSite;
+
+/**
+ * A relinkable call site that implements monomorphic inline caching strategy. After it linked a method, it will keep it
+ * until either its guard evaluates to false, or its switchpoint is invalidated, at which time it will throw away the
+ * previous linkage, and trigger relinking with its associated {@link DynamicLinker}.
+ *
+ * @author Attila Szegedi
+ */
+public class MonomorphicCallSite extends AbstractRelinkableCallSite {
+    /**
+     * Creates a new call site with monomorphic inline caching strategy.
+     * @param descriptor the descriptor for this call site
+     */
+    public MonomorphicCallSite(CallSiteDescriptor descriptor) {
+        super(descriptor);
+    }
+
+    @Override
+    public void relink(GuardedInvocation guardedInvocation, MethodHandle relink) {
+        setTarget(guardedInvocation.compose(relink));
+    }
+
+    @Override
+    public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle relink) {
+        relink(guardedInvocation, relink);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/NoSuchDynamicMethodException.java b/nashorn/src/jdk/internal/dynalink/NoSuchDynamicMethodException.java
new file mode 100644
index 0000000..8a73af9
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/NoSuchDynamicMethodException.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+
+/**
+ * Thrown at the invocation if the call site can not be linked by any available {@link GuardingDynamicLinker}.
+ *
+ * @author Attila Szegedi
+ */
+public class NoSuchDynamicMethodException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Creates a new NoSuchDynamicMethodException
+     * @param message the message of the exception.
+     */
+    public NoSuchDynamicMethodException(String message) {
+        super(message);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/RelinkableCallSite.java b/nashorn/src/jdk/internal/dynalink/RelinkableCallSite.java
new file mode 100644
index 0000000..4b68045
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/RelinkableCallSite.java
@@ -0,0 +1,147 @@
+/*
+ * 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;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.VolatileCallSite;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+
+/**
+ * Interface for relinkable call sites. Language runtimes wishing to use this framework must use subclasses of
+ * {@link CallSite} that also implement this interface as their call sites. There is a readily usable
+ * {@link MonomorphicCallSite} subclass that implements monomorphic inline caching strategy as well as a
+ * {@link ChainedCallSite} that retains a chain of already linked method handles. The reason this is defined as an
+ * interface instead of a concrete, albeit abstract class is that it allows independent implementations to choose
+ * between {@link MutableCallSite} and {@link VolatileCallSite} as they see fit.
+ *
+ * @author Attila Szegedi
+ */
+public interface RelinkableCallSite {
+    /**
+     * Initializes the relinkable call site by setting a relink-and-invoke method handle. The call site implementation
+     * is supposed to set this method handle as its target.
+     * @param relinkAndInvoke a relink-and-invoke method handle supplied by the {@link DynamicLinker}.
+     */
+    public void initialize(MethodHandle relinkAndInvoke);
+
+    /**
+     * Returns the descriptor for this call site.
+     *
+     * @return the descriptor for this call site.
+     */
+    public CallSiteDescriptor getDescriptor();
+
+    /**
+     * This method will be called by the dynamic linker every time the call site is normally relinked. It will be passed
+     * a {@code GuardedInvocation} that the call site should incorporate into its target method handle. When this method
+     * is called, the call site is allowed to keep other non-invalidated invocations around for implementation of
+     * polymorphic inline caches and compose them with this invocation to form its final target.
+     *
+     * @param guardedInvocation the guarded invocation that the call site should incorporate into its target method
+     * handle.
+     * @param fallback the fallback method. This is a method matching the method type of the call site that is supplied
+     * by the {@link DynamicLinker} to be used by this call site as a fallback when it can't invoke its target with the
+     * passed arguments. The fallback method is such that when it's invoked, it'll try to discover the adequate target
+     * for the invocation, subsequently invoke {@link #relink(GuardedInvocation, MethodHandle)} or
+     * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally invoke the target.
+     */
+    public void relink(GuardedInvocation guardedInvocation, MethodHandle fallback);
+
+    /**
+     * This method will be called by the dynamic linker every time the call site is relinked and the linker wishes the
+     * call site to throw away any prior linkage state. It will be passed a {@code GuardedInvocation} that the call site
+     * should use to build its target method handle. When this method is called, the call site is discouraged from
+     * keeping previous state around, and is supposed to only link the current invocation.
+     *
+     * @param guardedInvocation the guarded invocation that the call site should use to build its target method handle.
+     * @param fallback the fallback method. This is a method matching the method type of the call site that is supplied
+     * by the {@link DynamicLinker} to be used by this call site as a fallback when it can't invoke its target with the
+     * passed arguments. The fallback method is such that when it's invoked, it'll try to discover the adequate target
+     * for the invocation, subsequently invoke {@link #relink(GuardedInvocation, MethodHandle)} or
+     * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally invoke the target.
+     */
+    public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle fallback);
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java b/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java
new file mode 100644
index 0000000..702c150
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java
@@ -0,0 +1,701 @@
+/*
+ * 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.invoke.MethodType;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.internal.dynalink.support.Guards;
+import jdk.internal.dynalink.support.Lookup;
+
+/**
+ * A base class for both {@link StaticClassLinker} and {@link BeanLinker}. Deals with common aspects of property
+ * exposure and method calls for both static and instance facets of a class.
+ *
+ * @author Attila Szegedi
+ */
+abstract class AbstractJavaLinker implements GuardingDynamicLinker {
+    final Class<?> clazz;
+    private final MethodHandle classGuard;
+    private final MethodHandle assignableGuard;
+    private final Map<String, AnnotatedMethodHandle> propertyGetters = new HashMap<>();
+    private final Map<String, DynamicMethod> propertySetters = new HashMap<>();
+    private final Map<String, DynamicMethod> methods = new HashMap<>();
+
+    AbstractJavaLinker(Class<?> clazz, MethodHandle classGuard) {
+        this(clazz, classGuard, classGuard);
+    }
+
+    AbstractJavaLinker(Class<?> clazz, MethodHandle classGuard, MethodHandle assignableGuard) {
+        this.clazz = clazz;
+        this.classGuard = classGuard;
+        this.assignableGuard = assignableGuard;
+
+        final FacetIntrospector introspector = createFacetIntrospector();
+        // Add methods and properties
+        for(Method method: introspector.getMethods()) {
+            final String name = method.getName();
+            final MethodHandle methodHandle = introspector.unreflect(method);
+            // Add method
+            addMember(name, methodHandle, methods);
+            // Add the method as a property getter and/or setter
+            if(name.startsWith("get") && name.length() > 3 && method.getParameterTypes().length == 0) {
+                // Property getter
+                setPropertyGetter(decapitalize(name.substring(3)), introspector.unreflect(
+                        getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
+            } else if(name.startsWith("is") && name.length() > 2 && method.getParameterTypes().length == 0 &&
+                    method.getReturnType() == boolean.class) {
+                // Boolean property getter
+                setPropertyGetter(decapitalize(name.substring(2)), introspector.unreflect(
+                        getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
+            } else if(name.startsWith("set") && name.length() > 3 && method.getParameterTypes().length == 1) {
+                // Property setter
+                addMember(decapitalize(name.substring(3)), methodHandle, propertySetters);
+            }
+        }
+
+        // Add field getter/setters as property getters/setters.
+        for(Field field: introspector.getFields()) {
+            final String name = field.getName();
+            // Only add a property getter when one is not defined already as a getXxx()/isXxx() method.
+            if(!propertyGetters.containsKey(name)) {
+                setPropertyGetter(name, introspector.unreflectGetter(field), ValidationType.EXACT_CLASS);
+            }
+            if(!(Modifier.isFinal(field.getModifiers()) || propertySetters.containsKey(name))) {
+                addMember(name, introspector.unreflectSetter(field), propertySetters);
+            }
+        }
+
+        // Add inner classes, but only those for which we don't hide a property with it
+        for(Map.Entry<String, MethodHandle> innerClassSpec: introspector.getInnerClassGetters().entrySet()) {
+            final String name = innerClassSpec.getKey();
+            if(!propertyGetters.containsKey(name)) {
+                setPropertyGetter(name, innerClassSpec.getValue(), ValidationType.EXACT_CLASS);
+            }
+        }
+    }
+
+    private static String decapitalize(String str) {
+        assert str != null;
+        if(str.isEmpty()) {
+            return str;
+        }
+
+        final char c0 = str.charAt(0);
+        if(Character.isLowerCase(c0)) {
+            return str;
+        }
+
+        // If it has two consecutive upper-case characters, i.e. "URL", don't decapitalize
+        if(str.length() > 1 && Character.isUpperCase(str.charAt(1))) {
+            return str;
+        }
+
+        final char c[] = str.toCharArray();
+        c[0] = Character.toLowerCase(c0);
+        return new String(c);
+    }
+
+    abstract FacetIntrospector createFacetIntrospector();
+
+    void setPropertyGetter(String name, MethodHandle handle, ValidationType validationType) {
+        propertyGetters.put(name, new AnnotatedMethodHandle(handle, validationType));
+    }
+
+    private void addMember(String name, MethodHandle mh, Map<String, DynamicMethod> methodMap) {
+        final DynamicMethod existingMethod = methodMap.get(name);
+        final DynamicMethod newMethod = addMember(mh, existingMethod, clazz, name);
+        if(newMethod != existingMethod) {
+            methodMap.put(name, newMethod);
+        }
+    }
+
+    static DynamicMethod createDynamicMethod(Iterable<MethodHandle> methodHandles, Class<?> clazz, String name) {
+        DynamicMethod dynMethod = null;
+        for(MethodHandle methodHandle: methodHandles) {
+            dynMethod = addMember(methodHandle, dynMethod, clazz, name);
+        }
+        return dynMethod;
+    }
+
+    private static DynamicMethod addMember(MethodHandle mh, DynamicMethod existing, Class<?> clazz, String name) {
+        if(existing == null) {
+            return new SimpleDynamicMethod(mh, clazz, name);
+        } else if(existing.contains(mh)) {
+            return existing;
+        } else if(existing instanceof SimpleDynamicMethod) {
+            final OverloadedDynamicMethod odm = new OverloadedDynamicMethod(clazz, name);
+            odm.addMethod(((SimpleDynamicMethod)existing));
+            odm.addMethod(mh);
+            return odm;
+        } else if(existing instanceof OverloadedDynamicMethod) {
+            ((OverloadedDynamicMethod)existing).addMethod(mh);
+            return existing;
+        }
+        throw new AssertionError();
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest request, final LinkerServices linkerServices)
+            throws Exception {
+        final LinkRequest ncrequest = request.withoutRuntimeContext();
+        // BeansLinker already checked that the name is at least 2 elements long and the first element is "dyn".
+        final CallSiteDescriptor callSiteDescriptor = ncrequest.getCallSiteDescriptor();
+        final String op = callSiteDescriptor.getNameToken(CallSiteDescriptor.OPERATOR);
+        // Either dyn:callMethod:name(this[,args]) or dyn:callMethod(this,name[,args]).
+        if("callMethod" == op) {
+            return getCallPropWithThis(callSiteDescriptor, linkerServices);
+        }
+        List<String> operations = CallSiteDescriptorFactory.tokenizeOperators(callSiteDescriptor);
+        while(!operations.isEmpty()) {
+            final GuardedInvocationComponent gic = getGuardedInvocationComponent(callSiteDescriptor, linkerServices,
+                    operations);
+            if(gic != null) {
+                return gic.getGuardedInvocation();
+            }
+            operations = pop(operations);
+        }
+        return null;
+    }
+
+    protected GuardedInvocationComponent getGuardedInvocationComponent(CallSiteDescriptor callSiteDescriptor,
+            LinkerServices linkerServices, List<String> operations) throws Exception {
+        if(operations.isEmpty()) {
+            return null;
+        }
+        final String op = operations.get(0);
+        // Either dyn:getProp:name(this) or dyn:getProp(this, name)
+        if("getProp".equals(op)) {
+            return getPropertyGetter(callSiteDescriptor, linkerServices, pop(operations));
+        }
+        // Either dyn:setProp:name(this, value) or dyn:setProp(this, name, value)
+        if("setProp".equals(op)) {
+            return getPropertySetter(callSiteDescriptor, linkerServices, pop(operations));
+        }
+        // Either dyn:getMethod:name(this), or dyn:getMethod(this, name)
+        if("getMethod".equals(op)) {
+            return getMethodGetter(callSiteDescriptor, linkerServices, pop(operations));
+        }
+        return null;
+    }
+
+    static final <T> List<T> pop(List<T> l) {
+        return l.subList(1, l.size());
+    }
+
+    MethodHandle getClassGuard(CallSiteDescriptor desc) {
+        return getClassGuard(desc.getMethodType());
+    }
+
+    MethodHandle getClassGuard(MethodType type) {
+        return Guards.asType(classGuard, type);
+    }
+
+    GuardedInvocationComponent getClassGuardedInvocationComponent(MethodHandle invocation, MethodType type) {
+        return new GuardedInvocationComponent(invocation, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
+    }
+
+    private MethodHandle getAssignableGuard(MethodType type) {
+        return Guards.asType(assignableGuard, type);
+    }
+
+    private GuardedInvocation getCallPropWithThis(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) {
+        switch(callSiteDescriptor.getNameTokenCount()) {
+            case 3: {
+                return createGuardedDynamicMethodInvocation(callSiteDescriptor.getMethodType(), linkerServices,
+                        callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), methods);
+            }
+            default: {
+                return null;
+            }
+        }
+    }
+
+    private GuardedInvocation createGuardedDynamicMethodInvocation(MethodType callSiteType,
+            LinkerServices linkerServices, String methodName, Map<String, DynamicMethod> methodMap){
+        final MethodHandle inv = getDynamicMethodInvocation(callSiteType, linkerServices, methodName, methodMap);
+        return inv == null ? null : new GuardedInvocation(inv, getClassGuard(callSiteType));
+    }
+
+    private static MethodHandle getDynamicMethodInvocation(MethodType callSiteType, LinkerServices linkerServices,
+            String methodName, Map<String, DynamicMethod> methodMap) {
+        final DynamicMethod dynaMethod = getDynamicMethod(methodName, methodMap);
+        return dynaMethod != null ? dynaMethod.getInvocation(callSiteType, linkerServices) : null;
+    }
+
+    private static DynamicMethod getDynamicMethod(String methodName, Map<String, DynamicMethod> methodMap) {
+        final DynamicMethod dynaMethod = methodMap.get(methodName);
+        return dynaMethod != null ? dynaMethod : getExplicitSignatureDynamicMethod(methodName, methodMap);
+    }
+
+    private static SimpleDynamicMethod getExplicitSignatureDynamicMethod(String methodName,
+            Map<String, DynamicMethod> methodsMap) {
+        // What's below is meant to support the "name(type, type, ...)" syntax that programmers can use in a method name
+        // to manually pin down an exact overloaded variant. This is not usually required, as the overloaded method
+        // resolution works correctly in almost every situation. However, in presence of many language-specific
+        // conversions with a radically dynamic language, most overloaded methods will end up being constantly selected
+        // at invocation time, so a programmer knowledgable of the situation might choose to pin down an exact overload
+        // for performance reasons.
+
+        // Is the method name lexically of the form "name(types)"?
+        final int lastChar = methodName.length() - 1;
+        if(methodName.charAt(lastChar) != ')') {
+            return null;
+        }
+        final int openBrace = methodName.indexOf('(');
+        if(openBrace == -1) {
+            return null;
+        }
+
+        // Find an existing method for the "name" part
+        final DynamicMethod simpleNamedMethod = methodsMap.get(methodName.substring(0, openBrace));
+        if(simpleNamedMethod == null) {
+            return null;
+        }
+
+        // Try to get a narrowed dynamic method for the explicit parameter types.
+        return simpleNamedMethod.getMethodForExactParamTypes(methodName.substring(openBrace + 1, lastChar));
+    }
+
+    private static final MethodHandle IS_METHOD_HANDLE_NOT_NULL = Guards.isNotNull().asType(MethodType.methodType(
+            boolean.class, MethodHandle.class));
+    private static final MethodHandle CONSTANT_NULL_DROP_METHOD_HANDLE = MethodHandles.dropArguments(
+            MethodHandles.constant(Object.class, null), 0, MethodHandle.class);
+
+    private GuardedInvocationComponent getPropertySetter(CallSiteDescriptor callSiteDescriptor,
+            LinkerServices linkerServices, List<String> operations) throws Exception {
+        final MethodType type = callSiteDescriptor.getMethodType();
+        switch(callSiteDescriptor.getNameTokenCount()) {
+            case 2: {
+                // Must have three arguments: target object, property name, and property value.
+                assertParameterCount(callSiteDescriptor, 3);
+
+                // What's below is basically:
+                //   foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation),
+                //     get_setter_handle(type, linkerServices))
+                // only with a bunch of method signature adjustments. Basically, retrieve method setter
+                // MethodHandle; if it is non-null, invoke it, otherwise either return null, or delegate to next
+                // component's invocation.
+
+                // Call site type is "ret_type(object_type,property_name_type,property_value_type)", which we'll
+                // abbreviate to R(O, N, V) going forward.
+                // We want setters that conform to "R(O, V)"
+                final MethodType setterType = type.dropParameterTypes(1, 2);
+                // Bind property setter handle to the expected setter type and linker services. Type is
+                // MethodHandle(Object, String, Object)
+                final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0, setterType,
+                        linkerServices);
+
+                // Cast getter to MethodHandle(O, N, V)
+                final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType(
+                        MethodHandle.class));
+
+                // Handle to invoke the setter R(MethodHandle, O, V)
+                final MethodHandle invokeHandle = MethodHandles.exactInvoker(setterType);
+                // Handle to invoke the setter, dropping unnecessary fold arguments R(MethodHandle, O, N, V)
+                final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandle, 2, type.parameterType(
+                        1));
+                final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
+                        linkerServices, operations);
+
+                final MethodHandle fallbackFolded;
+                if(nextComponent == null) {
+                    // Object(MethodHandle)->R(MethodHandle, O, N, V); returns constant null
+                    fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_METHOD_HANDLE, 1,
+                            type.parameterList()).asType(type.insertParameterTypes(0, MethodHandle.class));
+                } else {
+                    // R(O, N, V)->R(MethodHandle, O, N, V); adapts the next component's invocation to drop the
+                    // extra argument resulting from fold
+                    fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(),
+                            0, MethodHandle.class);
+                }
+
+                // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
+                final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
+                            IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
+                if(nextComponent == null) {
+                    return getClassGuardedInvocationComponent(compositeSetter, type);
+                }
+                return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
+            }
+            case 3: {
+                // Must have two arguments: target object and property value
+                assertParameterCount(callSiteDescriptor, 2);
+                final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor.getMethodType(),
+                        linkerServices, callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND),
+                        propertySetters);
+                // If we have a property setter with this name, this composite operation will always stop here
+                if(gi != null) {
+                    return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
+                }
+                // If we don't have a property setter with this name, always fall back to the next operation in the
+                // composite (if any)
+                return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
+            }
+            default: {
+                // More than two name components; don't know what to do with it.
+                return null;
+            }
+        }
+    }
+
+    private static final Lookup privateLookup = new Lookup(MethodHandles.lookup());
+
+    private static final MethodHandle IS_ANNOTATED_HANDLE_NOT_NULL = Guards.isNotNull().asType(MethodType.methodType(
+            boolean.class, AnnotatedMethodHandle.class));
+    private static final MethodHandle CONSTANT_NULL_DROP_ANNOTATED_HANDLE = MethodHandles.dropArguments(
+            MethodHandles.constant(Object.class, null), 0, AnnotatedMethodHandle.class);
+    private static final MethodHandle GET_ANNOTATED_HANDLE = privateLookup.findGetter(AnnotatedMethodHandle.class,
+            "handle", MethodHandle.class);
+    private static final MethodHandle GENERIC_PROPERTY_GETTER_HANDLER_INVOKER = MethodHandles.filterArguments(
+            MethodHandles.invoker(MethodType.methodType(Object.class, Object.class)), 0, GET_ANNOTATED_HANDLE);
+
+    private GuardedInvocationComponent getPropertyGetter(CallSiteDescriptor callSiteDescriptor,
+            LinkerServices linkerServices, List<String> ops) throws Exception {
+        final MethodType type = callSiteDescriptor.getMethodType();
+        switch(callSiteDescriptor.getNameTokenCount()) {
+            case 2: {
+                // Must have exactly two arguments: receiver and name
+                assertParameterCount(callSiteDescriptor, 2);
+
+                // What's below is basically:
+                //   foldArguments(guardWithTest(isNotNull, invoke(get_handle), null|nextComponent.invocation), get_getter_handle)
+                // only with a bunch of method signature adjustments. Basically, retrieve method getter
+                // AnnotatedMethodHandle; if it is non-null, invoke its "handle" field, otherwise either return null,
+                // or delegate to next component's invocation.
+
+                final MethodHandle typedGetter = linkerServices.asType(getPropertyGetterHandle, type.changeReturnType(
+                        AnnotatedMethodHandle.class));
+                // Object(AnnotatedMethodHandle, Object)->R(AnnotatedMethodHandle, T0)
+                final MethodHandle invokeHandleTyped = linkerServices.asType(GENERIC_PROPERTY_GETTER_HANDLER_INVOKER,
+                        MethodType.methodType(type.returnType(), AnnotatedMethodHandle.class, type.parameterType(0)));
+                // Since it's in the target of a fold, drop the unnecessary second argument
+                // R(AnnotatedMethodHandle, T0)->R(AnnotatedMethodHandle, T0, T1)
+                final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2,
+                        type.parameterType(1));
+                final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
+                        linkerServices, ops);
+
+                final MethodHandle fallbackFolded;
+                if(nextComponent == null) {
+                    // Object(AnnotatedMethodHandle)->R(AnnotatedMethodHandle, T0, T1); returns constant null
+                    fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_HANDLE, 1,
+                            type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedMethodHandle.class));
+                } else {
+                    // R(T0, T1)->R(AnnotatedMethodHAndle, T0, T1); adapts the next component's invocation to drop the
+                    // extra argument resulting from fold
+                    fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(),
+                            0, AnnotatedMethodHandle.class);
+                }
+
+                // fold(R(AnnotatedMethodHandle, T0, T1), AnnotatedMethodHandle(T0, T1))
+                final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
+                            IS_ANNOTATED_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
+                if(nextComponent == null) {
+                    return getClassGuardedInvocationComponent(compositeGetter, type);
+                }
+                return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
+            }
+            case 3: {
+                // Must have exactly one argument: receiver
+                assertParameterCount(callSiteDescriptor, 1);
+                // Fixed name
+                final AnnotatedMethodHandle annGetter = propertyGetters.get(callSiteDescriptor.getNameToken(
+                        CallSiteDescriptor.NAME_OPERAND));
+                if(annGetter == null) {
+                    // We have no such property, always delegate to the next component operation
+                    return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, ops);
+                }
+                final MethodHandle getter = annGetter.handle;
+                // NOTE: since property getters (not field getters!) are no-arg, we don't have to worry about them being
+                // overloaded in a subclass. Therefore, we can discover the most abstract superclass that has the
+                // method, and use that as the guard with Guards.isInstance() for a more stably linked call site. If
+                // we're linking against a field getter, don't make the assumption.
+                // NOTE: No delegation to the next component operation if we have a property with this name, even if its
+                // value is null.
+                final ValidationType validationType = annGetter.validationType;
+                return new GuardedInvocationComponent(linkerServices.asType(getter, type), getGuard(validationType,
+                        type), clazz, validationType);
+            }
+            default: {
+                // Can't do anything with more than 3 name components
+                return null;
+            }
+        }
+    }
+
+    private MethodHandle getGuard(ValidationType validationType, MethodType methodType) {
+        switch(validationType) {
+            case EXACT_CLASS: {
+                return getClassGuard(methodType);
+            }
+            case INSTANCE_OF: {
+                return getAssignableGuard(methodType);
+            }
+            case IS_ARRAY: {
+                return Guards.isArray(0, methodType);
+            }
+            case NONE: {
+                return null;
+            }
+            default: {
+                throw new AssertionError();
+            }
+        }
+    }
+
+    private static final MethodHandle IS_DYNAMIC_METHOD_NOT_NULL = Guards.asType(Guards.isNotNull(),
+            MethodType.methodType(boolean.class, DynamicMethod.class));
+    private static final MethodHandle DYNAMIC_METHOD_IDENTITY = MethodHandles.identity(DynamicMethod.class);
+
+    private GuardedInvocationComponent getMethodGetter(CallSiteDescriptor callSiteDescriptor,
+            LinkerServices linkerServices, List<String> ops) throws Exception {
+        final MethodType type = callSiteDescriptor.getMethodType();
+        switch(callSiteDescriptor.getNameTokenCount()) {
+            case 2: {
+                // Must have exactly two arguments: receiver and name
+                assertParameterCount(callSiteDescriptor, 2);
+                final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
+                        linkerServices, ops);
+                if(nextComponent == null) {
+                    // No next component operation; just return a component for this operation.
+                    return getClassGuardedInvocationComponent(linkerServices.asType(getDynamicMethod, type), type);
+                }
+
+                // What's below is basically:
+                // foldArguments(guardWithTest(isNotNull, identity, nextComponent.invocation), getter) only with a
+                // bunch of method signature adjustments. Basically, execute method getter; if it returns a non-null
+                // DynamicMethod, use identity to return it, otherwise delegate to nextComponent's invocation.
+
+                final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type.changeReturnType(
+                        DynamicMethod.class));
+                // Since it is part of the foldArgument() target, it will have extra args that we need to drop.
+                final MethodHandle returnMethodHandle = linkerServices.asType(MethodHandles.dropArguments(
+                        DYNAMIC_METHOD_IDENTITY, 1, type.parameterList()), type.insertParameterTypes(0,
+                                DynamicMethod.class));
+                final MethodHandle nextComponentInvocation = nextComponent.getGuardedInvocation().getInvocation();
+                // The assumption is that getGuardedInvocationComponent() already asType()'d it correctly
+                assert nextComponentInvocation.type().equals(type);
+                // Since it is part of the foldArgument() target, we have to drop an extra arg it receives.
+                final MethodHandle nextCombinedInvocation = MethodHandles.dropArguments(nextComponentInvocation, 0,
+                        DynamicMethod.class);
+                // Assemble it all into a fold(guard(isNotNull, identity, nextInvocation), get)
+                final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
+                        IS_DYNAMIC_METHOD_NOT_NULL, returnMethodHandle, nextCombinedInvocation), typedGetter);
+
+                return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
+            }
+            case 3: {
+                // Must have exactly one argument: receiver
+                assertParameterCount(callSiteDescriptor, 1);
+                final DynamicMethod method = getDynamicMethod(callSiteDescriptor.getNameToken(
+                        CallSiteDescriptor.NAME_OPERAND));
+                if(method == null) {
+                    // We have no such method, always delegate to the next component
+                    return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, ops);
+                }
+                // No delegation to the next component of the composite operation; if we have a method with that name,
+                // we'll always return it at this point.
+                return getClassGuardedInvocationComponent(linkerServices.asType(MethodHandles.dropArguments(
+                        MethodHandles.constant(DynamicMethod.class, method), 0, type.parameterType(0)), type), type);
+            }
+            default: {
+                // Can't do anything with more than 3 name components
+                return null;
+            }
+        }
+    }
+
+    private static void assertParameterCount(CallSiteDescriptor descriptor, int paramCount) {
+        if(descriptor.getMethodType().parameterCount() != paramCount) {
+            throw new BootstrapMethodError(descriptor.getName() + " must have exactly " + paramCount + " parameters.");
+        }
+    }
+
+    private static MethodHandle GET_PROPERTY_GETTER_HANDLE = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
+            "getPropertyGetterHandle", Object.class, Object.class), 1, Object.class);
+    private final MethodHandle getPropertyGetterHandle = GET_PROPERTY_GETTER_HANDLE.bindTo(this);
+
+    /**
+     * @param id the property ID
+     * @return the method handle for retrieving the property, or null if the property does not exist
+     */
+    @SuppressWarnings("unused")
+    private Object getPropertyGetterHandle(Object id) {
+        return propertyGetters.get(id);
+    }
+
+    // Type is MethodHandle(BeanLinker, MethodType, LinkerServices, Object, String, Object), of which the two "Object"
+    // args are dropped; this makes handles with first three args conform to "Object, String, Object" though, which is
+    // a typical property setter with variable name signature (target, name, value).
+    private static final MethodHandle GET_PROPERTY_SETTER_HANDLE = MethodHandles.dropArguments(MethodHandles.dropArguments(
+            privateLookup.findOwnSpecial("getPropertySetterHandle", MethodHandle.class, MethodType.class,
+                    LinkerServices.class, Object.class), 3, Object.class), 5, Object.class);
+    // Type is MethodHandle(MethodType, LinkerServices, Object, String, Object)
+    private final MethodHandle getPropertySetterHandle = GET_PROPERTY_SETTER_HANDLE.bindTo(this);
+
+    @SuppressWarnings("unused")
+    private MethodHandle getPropertySetterHandle(MethodType setterType, LinkerServices linkerServices, Object id) {
+        return getDynamicMethodInvocation(setterType, linkerServices, String.valueOf(id), propertySetters);
+    }
+
+    private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
+            "getDynamicMethod", DynamicMethod.class, Object.class), 1, Object.class);
+    private final MethodHandle getDynamicMethod = GET_DYNAMIC_METHOD.bindTo(this);
+
+    @SuppressWarnings("unused")
+    private DynamicMethod getDynamicMethod(Object name) {
+        return getDynamicMethod(String.valueOf(name), methods);
+    }
+
+    /**
+     * Returns a dynamic method of the specified name.
+     *
+     * @param name name of the method
+     * @return the dynamic method (either {@link SimpleDynamicMethod} or {@link OverloadedDynamicMethod}, or null if the
+     * method with the specified name does not exist.
+     */
+    DynamicMethod getDynamicMethod(String name) {
+        return getDynamicMethod(name, methods);
+    }
+
+    /**
+     * Find the most generic superclass that declares this getter. Since getters have zero args (aside from the
+     * receiver), they can't be overloaded, so we're free to link with an instanceof guard for the most generic one,
+     * creating more stable call sites.
+     * @param getter the getter
+     * @return getter with same name, declared on the most generic superclass/interface of the declaring class
+     */
+    private static Method getMostGenericGetter(Method getter) {
+        return getMostGenericGetter(getter.getName(), getter.getReturnType(), getter.getDeclaringClass());
+    }
+
+    private static Method getMostGenericGetter(String name, Class<?> returnType, Class<?> declaringClass) {
+        if(declaringClass == null) {
+            return null;
+        }
+        // Prefer interfaces
+        for(Class<?> itf: declaringClass.getInterfaces()) {
+            final Method itfGetter = getMostGenericGetter(name, returnType, itf);
+            if(itfGetter != null) {
+                return itfGetter;
+            }
+        }
+        final Method superGetter = getMostGenericGetter(name, returnType, declaringClass.getSuperclass());
+        if(superGetter != null) {
+            return superGetter;
+        }
+        if(!CheckRestrictedPackage.isRestrictedClass(declaringClass)) {
+            try {
+                return declaringClass.getMethod(name);
+            } catch(NoSuchMethodException e) {
+                // Intentionally ignored, meant to fall through
+            }
+        }
+        return null;
+    }
+
+    private static final class AnnotatedMethodHandle {
+        final MethodHandle handle;
+        /*private*/ final ValidationType validationType;
+
+        AnnotatedMethodHandle(MethodHandle handle, ValidationType validationType) {
+            this.handle = handle;
+            this.validationType = validationType;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java b/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java
new file mode 100644
index 0000000..c82e334
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java
@@ -0,0 +1,262 @@
+/*
+ * 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.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Utility class for discovering accessible methods and inner classes. Normally, a public member declared on a class is
+ * accessible (that is, it can be invoked from anywhere). However, this is not the case if the class itself is not
+ * public, or belongs to a restricted-access package. In that case, it is required to lookup a member in a publicly
+ * accessible superclass or implemented interface of the class, and use it instead of the member discovered on the
+ * class.
+ *
+ * @author Attila Szegedi
+ */
+class AccessibleMembersLookup {
+    private final Map<MethodSignature, Method> methods;
+    private final Set<Class<?>> innerClasses;
+    private boolean instance;
+
+    /**
+     * Creates a mapping for all accessible methods and inner classes on a class.
+     *
+     * @param clazz the inspected class
+     * @param instance true to inspect instance methods, false to inspect static methods.
+     */
+    AccessibleMembersLookup(final Class<?> clazz, boolean instance) {
+        this.methods = new HashMap<>();
+        this.innerClasses = new LinkedHashSet<>();
+        this.instance = instance;
+        lookupAccessibleMembers(clazz);
+    }
+
+    /**
+     * Returns an accessible method equivalent of a method.
+     *
+     * @param m the method whose accessible equivalent is requested.
+     * @return the accessible equivalent for the method (can be the same as the passed in method), or null if there is
+     * no accessible method equivalent.
+     */
+    Method getAccessibleMethod(final Method m) {
+        return m == null ? null : methods.get(new MethodSignature(m));
+    }
+
+    Collection<Method> getMethods() {
+        return methods.values();
+    }
+
+    Class<?>[] getInnerClasses() {
+        return innerClasses.toArray(new Class<?>[innerClasses.size()]);
+    }
+
+    /**
+     * A helper class that represents a method signature - name and argument types.
+     *
+     * @author Attila Szegedi
+     */
+    static final class MethodSignature {
+        private final String name;
+        private final Class<?>[] args;
+
+        /**
+         * Creates a new method signature from arbitrary data.
+         *
+         * @param name the name of the method this signature represents.
+         * @param args the argument types of the method.
+         */
+        MethodSignature(String name, Class<?>[] args) {
+            this.name = name;
+            this.args = args;
+        }
+
+        /**
+         * Creates a signature for the given method.
+         *
+         * @param method the method for which a signature is created.
+         */
+        MethodSignature(final Method method) {
+            this(method.getName(), method.getParameterTypes());
+        }
+
+        /**
+         * Compares this object to another object
+         *
+         * @param o the other object
+         * @return true if the other object is also a method signature with the same name, same number of arguments, and
+         * same types of arguments.
+         */
+        @Override
+        public boolean equals(final Object o) {
+            if(o instanceof MethodSignature) {
+                final MethodSignature ms = (MethodSignature)o;
+                return ms.name.equals(name) && Arrays.equals(args, ms.args);
+            }
+            return false;
+        }
+
+        /**
+         * Returns a hash code, consistent with the overridden {@link #equals(Object)}.
+         */
+        @Override
+        public int hashCode() {
+            return name.hashCode() ^ Arrays.hashCode(args);
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder b = new StringBuilder();
+            b.append("[MethodSignature ").append(name).append('(');
+            if(args.length > 0) {
+                b.append(args[0].getCanonicalName());
+                for(int i = 1; i < args.length; ++i) {
+                    b.append(", ").append(args[i].getCanonicalName());
+                }
+            }
+            return b.append(")]").toString();
+        }
+    }
+
+    private void lookupAccessibleMembers(final Class<?> clazz) {
+        boolean searchSuperTypes;
+
+        if(!CheckRestrictedPackage.isRestrictedClass(clazz)) {
+            searchSuperTypes = false;
+            for(Method method: clazz.getMethods()) {
+                if(instance != Modifier.isStatic(method.getModifiers())) {
+                    final MethodSignature sig = new MethodSignature(method);
+                    if(!methods.containsKey(sig)) {
+                        final Class<?> declaringClass = method.getDeclaringClass();
+                        if(declaringClass != clazz && CheckRestrictedPackage.isRestrictedClass(declaringClass)) {
+                            //Sometimes, the declaring class of a method (Method.getDeclaringClass())
+                            //retrieved through Class.getMethods() for a public class will be a
+                            //non-public superclass. For such a method, we need to find a method with
+                            //the same name and signature in a public superclass or implemented
+                            //interface.
+                            //This typically doesn't happen with classes emitted by a reasonably modern
+                            //javac, as it'll create synthetic delegator methods in all public
+                            //immediate subclasses of the non-public class. We have, however, observed
+                            //this in the wild with class files compiled with older javac that doesn't
+                            //generate the said synthetic delegators.
+                            searchSuperTypes = true;
+                        } else {
+                            methods.put(sig, method);
+                        }
+                    }
+                }
+            }
+            for(Class<?> innerClass: clazz.getClasses()) {
+                // Add both static and non-static classes, regardless of instance flag. StaticClassLinker will just
+                // expose non-static classes with explicit constructor outer class argument.
+                // NOTE: getting inner class objects through getClasses() does not resolve them, so if those classes
+                // were not yet loaded, they'll only get loaded in a non-resolved state; no static initializers for
+                // them will trigger just by doing this.
+                innerClasses.add(innerClass);
+            }
+        } else {
+            searchSuperTypes = true;
+        }
+
+        if(searchSuperTypes) {
+            // If we reach here, the class is either not public, or it is in a restricted package. Alternatively, it is
+            // public, but some of its methods claim that their declaring class is non-public. We'll try superclasses
+            // and implemented interfaces then looking for public ones.
+            final Class<?>[] interfaces = clazz.getInterfaces();
+            for(int i = 0; i < interfaces.length; i++) {
+                lookupAccessibleMembers(interfaces[i]);
+            }
+            final Class<?> superclass = clazz.getSuperclass();
+            if(superclass != null) {
+                lookupAccessibleMembers(superclass);
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java b/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java
new file mode 100644
index 0000000..a232caf
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java
@@ -0,0 +1,220 @@
+/*
+ * 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.MethodType;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.internal.dynalink.support.TypeUtilities;
+
+/**
+ * Represents overloaded methods applicable to a specific call site signature.
+ *
+ * @author Attila Szegedi
+ */
+class ApplicableOverloadedMethods {
+    private final List<MethodHandle> methods;
+    private final boolean varArgs;
+
+    /**
+     * Creates a new ApplicableOverloadedMethods instance
+     *
+     * @param methods a list of all overloaded methods with the same name for a class.
+     * @param callSiteType the type of the call site
+     * @param test applicability test. One of {@link #APPLICABLE_BY_SUBTYPING},
+     * {@link #APPLICABLE_BY_METHOD_INVOCATION_CONVERSION}, or {@link #APPLICABLE_BY_VARIABLE_ARITY}.
+     */
+    ApplicableOverloadedMethods(final List<MethodHandle> methods, final MethodType callSiteType,
+            final ApplicabilityTest test) {
+        this.methods = new LinkedList<>();
+        for(MethodHandle m: methods) {
+            if(test.isApplicable(callSiteType, m)) {
+                this.methods.add(m);
+            }
+        }
+        varArgs = test == APPLICABLE_BY_VARIABLE_ARITY;
+    }
+
+    /**
+     * Retrieves all the methods this object holds.
+     *
+     * @return list of all methods.
+     */
+    List<MethodHandle> getMethods() {
+        return methods;
+    }
+
+    /**
+     * Returns a list of all methods in this objects that are maximally specific.
+     *
+     * @return a list of maximally specific methods.
+     */
+    List<MethodHandle> findMaximallySpecificMethods() {
+        return MaximallySpecific.getMaximallySpecificMethods(methods, varArgs);
+    }
+
+    abstract static class ApplicabilityTest {
+        abstract boolean isApplicable(MethodType callSiteType, MethodHandle method);
+    }
+
+    /**
+     * Implements the applicability-by-subtyping test from JLS 15.12.2.2.
+     */
+    static final ApplicabilityTest APPLICABLE_BY_SUBTYPING = new ApplicabilityTest() {
+        @Override
+        boolean isApplicable(MethodType callSiteType, MethodHandle method) {
+            final MethodType methodType = method.type();
+            final int methodArity = methodType.parameterCount();
+            if(methodArity != callSiteType.parameterCount()) {
+                return false;
+            }
+            // 0th arg is receiver; it doesn't matter for overload
+            // resolution.
+            for(int i = 1; i < methodArity; ++i) {
+                if(!TypeUtilities.isSubtype(callSiteType.parameterType(i), methodType.parameterType(i))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    };
+
+    /**
+     * Implements the applicability-by-method-invocation-conversion test from JLS 15.12.2.3.
+     */
+    static final ApplicabilityTest APPLICABLE_BY_METHOD_INVOCATION_CONVERSION = new ApplicabilityTest() {
+        @Override
+        boolean isApplicable(MethodType callSiteType, MethodHandle method) {
+            final MethodType methodType = method.type();
+            final int methodArity = methodType.parameterCount();
+            if(methodArity != callSiteType.parameterCount()) {
+                return false;
+            }
+            // 0th arg is receiver; it doesn't matter for overload
+            // resolution.
+            for(int i = 1; i < methodArity; ++i) {
+                if(!TypeUtilities.isMethodInvocationConvertible(callSiteType.parameterType(i),
+                        methodType.parameterType(i))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    };
+
+    /**
+     * Implements the applicability-by-variable-arity test from JLS 15.12.2.4.
+     */
+    static final ApplicabilityTest APPLICABLE_BY_VARIABLE_ARITY = new ApplicabilityTest() {
+        @Override
+        boolean isApplicable(MethodType callSiteType, MethodHandle method) {
+            if(!method.isVarargsCollector()) {
+                return false;
+            }
+            final MethodType methodType = method.type();
+            final int methodArity = methodType.parameterCount();
+            final int fixArity = methodArity - 1;
+            final int callSiteArity = callSiteType.parameterCount();
+            if(fixArity > callSiteArity) {
+                return false;
+            }
+            // 0th arg is receiver; it doesn't matter for overload
+            // resolution.
+            for(int i = 1; i < fixArity; ++i) {
+                if(!TypeUtilities.isMethodInvocationConvertible(callSiteType.parameterType(i),
+                        methodType.parameterType(i))) {
+                    return false;
+                }
+            }
+            final Class<?> varArgType = methodType.parameterType(fixArity).getComponentType();
+            for(int i = fixArity; i < callSiteArity; ++i) {
+                if(!TypeUtilities.isMethodInvocationConvertible(callSiteType.parameterType(i), varArgType)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    };
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/BeanIntrospector.java b/nashorn/src/jdk/internal/dynalink/beans/BeanIntrospector.java
new file mode 100644
index 0000000..fc54e35
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/BeanIntrospector.java
@@ -0,0 +1,104 @@
+/*
+ * 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.util.Collections;
+import java.util.Map;
+
+class BeanIntrospector extends FacetIntrospector {
+    BeanIntrospector(Class<?> clazz) {
+        super(clazz, true);
+    }
+
+    @Override
+    Map<String, MethodHandle> getInnerClassGetters() {
+        return Collections.emptyMap(); // NOTE: non-static inner classes are also on StaticClassIntrospector.
+    }
+
+    @Override
+    MethodHandle editMethodHandle(MethodHandle mh) {
+        return mh;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/BeanLinker.java b/nashorn/src/jdk/internal/dynalink/beans/BeanLinker.java
new file mode 100644
index 0000000..519036b
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/BeanLinker.java
@@ -0,0 +1,492 @@
+/*
+ * 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.invoke.MethodType;
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.Guards;
+import jdk.internal.dynalink.support.Lookup;
+import jdk.internal.dynalink.support.TypeUtilities;
+
+/**
+ * A class that provides linking capabilities for a single POJO class. Normally not used directly, but managed by
+ * {@link BeansLinker}.
+ *
+ * @author Attila Szegedi
+ */
+class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicLinker {
+    BeanLinker(Class<?> clazz) {
+        super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz));
+        if(clazz.isArray()) {
+            // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an
+            // explicit property is beneficial for them.
+            // REVISIT: is it maybe a code smell that "dyn:getLength" is not needed?
+            setPropertyGetter("length", GET_ARRAY_LENGTH, ValidationType.IS_ARRAY);
+        }
+    }
+
+    @Override
+    public boolean canLinkType(Class<?> type) {
+        return type == clazz;
+    }
+
+    @Override
+    FacetIntrospector createFacetIntrospector() {
+        return new BeanIntrospector(clazz);
+    }
+
+    @Override
+    protected GuardedInvocationComponent getGuardedInvocationComponent(CallSiteDescriptor callSiteDescriptor,
+            LinkerServices linkerServices, List<String> operations) throws Exception {
+        final GuardedInvocationComponent superGic = super.getGuardedInvocationComponent(callSiteDescriptor,
+                linkerServices, operations);
+        if(superGic != null) {
+            return superGic;
+        }
+        if(operations.isEmpty()) {
+            return null;
+        }
+        final String op = operations.get(0);
+        // dyn:getElem(this, id)
+        // id is typically either an int (for arrays and lists) or an object (for maps). linkerServices can provide
+        // conversion from call site argument type though.
+        if("getElem".equals(op)) {
+            return getElementGetter(callSiteDescriptor, linkerServices, pop(operations));
+        }
+        if("setElem".equals(op)) {
+            return getElementSetter(callSiteDescriptor, linkerServices, pop(operations));
+        }
+        // dyn:getLength(this) (works on Java arrays, collections, and maps)
+        if("getLength".equals(op)) {
+            return getLengthGetter(callSiteDescriptor);
+        }
+        return null;
+    }
+
+    private static MethodHandle GET_LIST_ELEMENT = Lookup.PUBLIC.findVirtual(List.class, "get",
+            MethodType.methodType(Object.class, int.class));
+
+    private static MethodHandle GET_MAP_ELEMENT = Lookup.PUBLIC.findVirtual(Map.class, "get",
+            MethodType.methodType(Object.class, Object.class));
+
+    private static MethodHandle LIST_GUARD = Guards.getInstanceOfGuard(List.class);
+    private static MethodHandle MAP_GUARD = Guards.getInstanceOfGuard(Map.class);
+
+    private GuardedInvocationComponent getElementGetter(final CallSiteDescriptor callSiteDescriptor,
+            final LinkerServices linkerServices, List<String> operations) throws Exception {
+        final MethodType callSiteType = callSiteDescriptor.getMethodType();
+        final Class<?> declaredType = callSiteType.parameterType(0);
+        final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
+                linkerServices, operations);
+
+        // If declared type of receiver at the call site is already an array, a list or map, bind without guard. Thing
+        // is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance they're
+        // dealing with an array, or a list or map, but hey...
+        // Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
+        // in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
+        final GuardedInvocationComponent gic;
+        final boolean isMap;
+        if(declaredType.isArray()) {
+            gic = new GuardedInvocationComponent(MethodHandles.arrayElementGetter(declaredType));
+            isMap = false;
+        } else if(List.class.isAssignableFrom(declaredType)) {
+            gic = new GuardedInvocationComponent(GET_LIST_ELEMENT);
+            isMap = false;
+        } else if(Map.class.isAssignableFrom(declaredType)) {
+            gic = new GuardedInvocationComponent(GET_MAP_ELEMENT);
+            isMap = true;
+        } else if(clazz.isArray()) {
+            gic = getClassGuardedInvocationComponent(MethodHandles.arrayElementGetter(clazz), callSiteType);
+            isMap = false;
+        } else if(List.class.isAssignableFrom(clazz)) {
+            gic = new GuardedInvocationComponent(GET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class,
+                    ValidationType.INSTANCE_OF);
+            isMap = false;
+        } else if(Map.class.isAssignableFrom(clazz)) {
+            gic = new GuardedInvocationComponent(GET_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class,
+                    ValidationType.INSTANCE_OF);
+            isMap = true;
+        } else {
+            // Can't retrieve elements for objects that are neither arrays, nor list, nor maps.
+            return nextComponent;
+        }
+
+        // We can have "dyn:getElem:foo", especially in composites, i.e. "dyn:getElem|getProp|getMethod:foo"
+        final String fixedKey = getFixedKey(callSiteDescriptor);
+        // Convert the key to a number if we're working with a list or array
+        final Object typedFixedKey;
+        if(!isMap && fixedKey != null) {
+            typedFixedKey = convertKeyToInteger(fixedKey, linkerServices);
+            if(typedFixedKey == null) {
+                // key is not numeric, it can never succeed
+                return nextComponent;
+            }
+        } else {
+            typedFixedKey = fixedKey;
+        }
+
+        final GuardedInvocation gi = gic.getGuardedInvocation();
+        final Binder binder = new Binder(linkerServices, callSiteType, typedFixedKey);
+        final MethodHandle invocation = gi.getInvocation();
+
+        if(nextComponent == null) {
+            return gic.replaceInvocation(binder.bind(invocation));
+        }
+
+        final MethodHandle checkGuard;
+        if(invocation == GET_LIST_ELEMENT) {
+            checkGuard = convertArgToInt(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor);
+        } else if(invocation == GET_MAP_ELEMENT) {
+            // TODO: A more complex solution could be devised for maps, one where we do a get() first, and fold it
+            // into a GWT that tests if it returned null, and if it did, do another GWT with containsKey()
+            // that returns constant null (on true), or falls back to next component (on false)
+            checkGuard = CONTAINS_MAP;
+        } else {
+            checkGuard = convertArgToInt(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
+        }
+        return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard),
+                binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
+                gic.getValidatorClass(), gic.getValidationType());
+    }
+
+    private static String getFixedKey(final CallSiteDescriptor callSiteDescriptor) {
+        return callSiteDescriptor.getNameTokenCount() == 2 ? null : callSiteDescriptor.getNameToken(
+                CallSiteDescriptor.NAME_OPERAND);
+    }
+
+    private static Object convertKeyToInteger(String fixedKey, LinkerServices linkerServices) throws Exception {
+        try {
+            if(linkerServices.canConvert(String.class, Number.class)) {
+                try {
+                    final Object val = linkerServices.getTypeConverter(String.class, Number.class).invoke(fixedKey);
+                    if(!(val instanceof Number)) {
+                        return null; // not a number
+                    }
+                    final Number n = (Number)val;
+                    if(n instanceof Integer) {
+                        return n;
+                    }
+                    final int intIndex = n.intValue();
+                    final double doubleValue = n.doubleValue();
+                    if(intIndex != doubleValue && !Double.isInfinite(doubleValue)) { // let infinites trigger IOOBE
+                        return null; // not an exact integer
+                    }
+                    return Integer.valueOf(intIndex);
+                } catch(Exception|Error e) {
+                    throw e;
+                } catch(Throwable t) {
+                    throw new RuntimeException(t);
+                }
+            }
+            return Integer.valueOf(fixedKey);
+        } catch(NumberFormatException e) {
+            // key is not a number
+            return null;
+        }
+    }
+
+    private static MethodHandle convertArgToInt(MethodHandle mh, LinkerServices ls, CallSiteDescriptor desc) {
+        final Class<?> sourceType = desc.getMethodType().parameterType(1);
+        if(TypeUtilities.isMethodInvocationConvertible(sourceType, Number.class)) {
+            return mh;
+        } else if(ls.canConvert(sourceType, Number.class)) {
+            final MethodHandle converter = ls.getTypeConverter(sourceType, Number.class);
+            return MethodHandles.filterArguments(mh, 1, converter.asType(converter.type().changeReturnType(
+                    mh.type().parameterType(1))));
+        }
+        return mh;
+    }
+
+    /**
+     * Contains methods to adapt an item getter/setter method handle to the requested type, optionally binding it to a
+     * fixed key first.
+     * @author Attila Szegedi
+     * @version $Id: $
+     */
+    private static class Binder {
+        private final LinkerServices linkerServices;
+        private final MethodType methodType;
+        private final Object fixedKey;
+
+        Binder(LinkerServices linkerServices, MethodType methodType, Object fixedKey) {
+            this.linkerServices = linkerServices;
+            this.methodType = fixedKey == null ? methodType : methodType.insertParameterTypes(1, fixedKey.getClass());
+            this.fixedKey = fixedKey;
+        }
+
+        /*private*/ MethodHandle bind(MethodHandle handle) {
+            return bindToFixedKey(linkerServices.asType(handle, methodType));
+        }
+
+        /*private*/ MethodHandle bindTest(MethodHandle handle) {
+            return bindToFixedKey(Guards.asType(handle, methodType));
+        }
+
+        private MethodHandle bindToFixedKey(MethodHandle handle) {
+            return fixedKey == null ? handle : MethodHandles.insertArguments(handle, 1, fixedKey);
+        }
+    }
+
+    private static MethodHandle RANGE_CHECK_ARRAY = findRangeCheck(Object.class);
+    private static MethodHandle RANGE_CHECK_LIST = findRangeCheck(List.class);
+    private static MethodHandle CONTAINS_MAP = Lookup.PUBLIC.findVirtual(Map.class, "containsKey",
+            MethodType.methodType(boolean.class, Object.class));
+
+    private static MethodHandle findRangeCheck(Class<?> collectionType) {
+        return Lookup.findOwnStatic(MethodHandles.lookup(), "rangeCheck", boolean.class, collectionType, Object.class);
+    }
+
+    @SuppressWarnings("unused")
+    private static final boolean rangeCheck(Object array, Object index) {
+        if(!(index instanceof Number)) {
+            return false;
+        }
+        final Number n = (Number)index;
+        final int intIndex = n.intValue();
+        final double doubleValue = n.doubleValue();
+        if(intIndex != doubleValue && !Double.isInfinite(doubleValue)) { // let infinite trigger IOOBE
+            return false;
+        }
+        if(0 <= intIndex && intIndex < Array.getLength(array)) {
+            return true;
+        }
+        throw new ArrayIndexOutOfBoundsException("Array index out of range: " + n);
+    }
+
+    @SuppressWarnings("unused")
+    private static final boolean rangeCheck(List<?> list, Object index) {
+        if(!(index instanceof Number)) {
+            return false;
+        }
+        final Number n = (Number)index;
+        final int intIndex = n.intValue();
+        final double doubleValue = n.doubleValue();
+        if(intIndex != doubleValue && !Double.isInfinite(doubleValue)) { // let infinite trigger IOOBE
+            return false;
+        }
+        if(0 <= intIndex && intIndex < list.size()) {
+            return true;
+        }
+        throw new IndexOutOfBoundsException("Index: " + n + ", Size: " + list.size());
+    }
+
+    private static MethodHandle SET_LIST_ELEMENT = Lookup.PUBLIC.findVirtual(List.class, "set",
+            MethodType.methodType(Object.class, int.class, Object.class));
+
+    private static MethodHandle PUT_MAP_ELEMENT = Lookup.PUBLIC.findVirtual(Map.class, "put",
+            MethodType.methodType(Object.class, Object.class, Object.class));
+
+    private GuardedInvocationComponent getElementSetter(CallSiteDescriptor callSiteDescriptor,
+            LinkerServices linkerServices, List<String> operations) throws Exception {
+        final MethodType callSiteType = callSiteDescriptor.getMethodType();
+        final Class<?> declaredType = callSiteType.parameterType(0);
+
+        final GuardedInvocationComponent gic;
+        // If declared type of receiver at the call site is already an array, a list or map, bind without guard. Thing
+        // is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance they're
+        // dealing with an array, or a list or map, but hey...
+        // Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
+        // in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
+        final boolean isMap;
+        if(declaredType.isArray()) {
+            gic = new GuardedInvocationComponent(MethodHandles.arrayElementSetter(declaredType));
+            isMap = false;
+        } else if(List.class.isAssignableFrom(declaredType)) {
+            gic = new GuardedInvocationComponent(SET_LIST_ELEMENT);
+            isMap = false;
+        } else if(Map.class.isAssignableFrom(declaredType)) {
+            gic = new GuardedInvocationComponent(PUT_MAP_ELEMENT);
+            isMap = true;
+        } else if(clazz.isArray()) {
+            gic = getClassGuardedInvocationComponent(MethodHandles.arrayElementSetter(clazz), callSiteType);
+            isMap = false;
+        } else if(List.class.isAssignableFrom(clazz)) {
+            gic = new GuardedInvocationComponent(SET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class,
+                    ValidationType.INSTANCE_OF);
+            isMap = false;
+        } else if(Map.class.isAssignableFrom(clazz)) {
+            gic = new GuardedInvocationComponent(PUT_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class,
+                    ValidationType.INSTANCE_OF);
+            isMap = true;
+        } else {
+            // Can't set elements for objects that are neither arrays, nor list, nor maps.
+            gic = null;
+            isMap = false;
+        }
+
+        // In contrast to, say, getElementGetter, we only compute the nextComponent if the target object is not a map,
+        // as maps will always succeed in setting the element and will never need to fall back to the next component
+        // operation.
+        final GuardedInvocationComponent nextComponent = isMap ? null : getGuardedInvocationComponent(
+                callSiteDescriptor, linkerServices, operations);
+        if(gic == null) {
+            return nextComponent;
+        }
+
+        // We can have "dyn:setElem:foo", especially in composites, i.e. "dyn:setElem|setProp:foo"
+        final String fixedKey = getFixedKey(callSiteDescriptor);
+        // Convert the key to a number if we're working with a list or array
+        final Object typedFixedKey;
+        if(!isMap && fixedKey != null) {
+            typedFixedKey = convertKeyToInteger(fixedKey, linkerServices);
+            if(typedFixedKey == null) {
+                // key is not numeric, it can never succeed
+                return nextComponent;
+            }
+        } else {
+            typedFixedKey = fixedKey;
+        }
+
+        final GuardedInvocation gi = gic.getGuardedInvocation();
+        final Binder binder = new Binder(linkerServices, callSiteType, typedFixedKey);
+        final MethodHandle invocation = gi.getInvocation();
+
+        if(nextComponent == null) {
+            return gic.replaceInvocation(binder.bind(invocation));
+        }
+
+        final MethodHandle checkGuard = convertArgToInt(invocation == SET_LIST_ELEMENT ? RANGE_CHECK_LIST :
+            RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
+        return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard),
+                binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
+                gic.getValidatorClass(), gic.getValidationType());
+    }
+
+    private static MethodHandle GET_ARRAY_LENGTH = Lookup.PUBLIC.findStatic(Array.class, "getLength",
+            MethodType.methodType(int.class, Object.class));
+
+    private static MethodHandle GET_COLLECTION_LENGTH = Lookup.PUBLIC.findVirtual(Collection.class, "size",
+            MethodType.methodType(int.class));
+
+    private static MethodHandle GET_MAP_LENGTH = Lookup.PUBLIC.findVirtual(Map.class, "size",
+            MethodType.methodType(int.class));
+
+    private static MethodHandle COLLECTION_GUARD = Guards.getInstanceOfGuard(Collection.class);
+
+    private GuardedInvocationComponent getLengthGetter(CallSiteDescriptor callSiteDescriptor) {
+        assertParameterCount(callSiteDescriptor, 1);
+        final MethodType callSiteType = callSiteDescriptor.getMethodType();
+        final Class<?> declaredType = callSiteType.parameterType(0);
+        // If declared type of receiver at the call site is already an array, collection, or map, bind without guard.
+        // Thing is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance
+        // they're dealing with an array, collection, or map, but hey...
+        if(declaredType.isArray()) {
+            return new GuardedInvocationComponent(GET_ARRAY_LENGTH.asType(callSiteType));
+        } else if(Collection.class.isAssignableFrom(declaredType)) {
+            return new GuardedInvocationComponent(GET_COLLECTION_LENGTH.asType(callSiteType));
+        } else if(Map.class.isAssignableFrom(declaredType)) {
+            return new GuardedInvocationComponent(GET_MAP_LENGTH.asType(callSiteType));
+        }
+
+        // Otherwise, create a binding based on the actual type of the argument with an appropriate guard.
+        if(clazz.isArray()) {
+            return new GuardedInvocationComponent(GET_ARRAY_LENGTH.asType(callSiteType), Guards.isArray(0,
+                    callSiteType), ValidationType.IS_ARRAY);
+        } if(Collection.class.isAssignableFrom(clazz)) {
+            return new GuardedInvocationComponent(GET_COLLECTION_LENGTH.asType(callSiteType), Guards.asType(
+                    COLLECTION_GUARD, callSiteType), Collection.class, ValidationType.INSTANCE_OF);
+        } if(Map.class.isAssignableFrom(clazz)) {
+            return new GuardedInvocationComponent(GET_MAP_LENGTH.asType(callSiteType), Guards.asType(MAP_GUARD,
+                    callSiteType), Map.class, ValidationType.INSTANCE_OF);
+        }
+        // Can't retrieve length for objects that are neither arrays, nor collections, nor maps.
+        return null;
+    }
+
+    private static void assertParameterCount(CallSiteDescriptor descriptor, int paramCount) {
+        if(descriptor.getMethodType().parameterCount() != paramCount) {
+            throw new BootstrapMethodError(descriptor.getName() + " must have exactly " + paramCount + " parameters.");
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java b/nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java
new file mode 100644
index 0000000..8581123
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java
@@ -0,0 +1,186 @@
+/*
+ * 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.MethodHandles;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.DynamicLinkerFactory;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+
+/**
+ * A linker for POJOs. Normally used as the ultimate fallback linker by the {@link DynamicLinkerFactory} so it is given
+ * the chance to link calls to all objects that no other language runtime recognizes. Specifically, this linker will:
+ * <ul>
+ * <li>expose all public methods of form {@code setXxx()}, {@code getXxx()}, and {@code isXxx()} as property setters and
+ * getters for {@code dyn:setProp} and {@code dyn:getProp} operations;</li>
+ * <li>expose all public methods for invocation through {@code dyn:callMethod} operation;</li>
+ * <li>expose all public methods for retrieval for {@code dyn:getMethod} operation; the methods thus retrieved can then
+ * be invoked using {@code dyn:call};</li>
+ * <li>expose all public fields as properties, unless there are getters or setters for the properties of the same name;</li>
+ * <li>expose {@code dyn:getLength}, {@code dyn:getElem} and {@code dyn:setElem} on native Java arrays, as well as
+ * {@link java.util.List} and {@link java.util.Map} objects; ({@code dyn:getLength} works on any
+ * {@link java.util.Collection});</li>
+ * <li>expose a virtual property named {@code length} on Java arrays;</li>
+ * <li>expose {@code dyn:new} on instances of {@link StaticClass} as calls to constructors, including those static class
+ * objects that represent Java arrays (their constructors take a single {@code int} parameter representing the length of
+ * the array to create);</li>
+ * <li>expose static methods, fields, and properties of classes in a similar manner to how instance method, fields, and
+ * properties are exposed, on {@link StaticClass} objects.</li>
+ * <li>expose a virtual property named {@code static} on instances of {@link java.lang.Class} to access their
+ * {@link StaticClass}.</li>
+ * </ul>
+ * <p><strong>Overloaded method resolution</strong> is performed automatically for property setters, methods, and
+ * constructors. Additionally, manual overloaded method selection is supported by having a call site specify a name for
+ * a method that contains an explicit signature, i.e. {@code dyn:getMethod:parseInt(String,int)}. You can use
+ * non-qualified class names in such signatures regardless of those classes' packages, they will match any class with
+ * the same non-qualified name. You only have to use a fully qualified class name in case non-qualified class names
+ * would cause selection ambiguity (that is extremely rare).</p>
+ * <p><strong>Variable argument invocation</strong> is handled for both methods and constructors.</p>
+ * <p>Currently, only public fields and methods are supported. Any Lookup objects passed in the
+ * {@link LinkRequest}s are ignored and {@link MethodHandles#publicLookup()} is used instead.</p>
+ *
+ * @author Attila Szegedi
+ */
+public class BeansLinker implements GuardingDynamicLinker {
+    private static final ClassValue<TypeBasedGuardingDynamicLinker> linkers = new ClassValue<TypeBasedGuardingDynamicLinker>() {
+        @Override
+        protected TypeBasedGuardingDynamicLinker computeValue(Class<?> clazz) {
+            // If ClassValue.put() were public, we could just pre-populate with these known mappings...
+            return
+                clazz == Class.class ? new ClassLinker() :
+                clazz == StaticClass.class ? new StaticClassLinker() :
+                DynamicMethod.class.isAssignableFrom(clazz) ? new DynamicMethodLinker() :
+                new BeanLinker(clazz);
+        }
+    };
+
+    /**
+     * Creates a new POJO linker.
+     */
+    public BeansLinker() {
+    }
+
+    /**
+     * Returns a bean linker for a particular single class. Useful when you need to override or extend the behavior of
+     * linking for some classes in your language runtime's linker, but still want to delegate to the default behavior in
+     * some cases.
+     * @param clazz the class
+     * @return a bean linker for that class
+     */
+    public static TypeBasedGuardingDynamicLinker getLinkerForClass(Class<?> clazz) {
+        return linkers.get(clazz);
+    }
+
+    /**
+     * Returns true if the object is a Dynalink Java dynamic method.
+     *
+     * @param obj the object we want to test for being a dynamic method
+     * @return true if it is a dynamic method, false otherwise.
+     */
+    public static boolean isDynamicMethod(final Object obj) {
+        return obj instanceof DynamicMethod;
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest request, final LinkerServices linkerServices)
+            throws Exception {
+        final CallSiteDescriptor callSiteDescriptor = request.getCallSiteDescriptor();
+        final int l = callSiteDescriptor.getNameTokenCount();
+        // All names conforming to the dynalang MOP should have at least two tokens, the first one being "dyn"
+        if(l < 2 || "dyn" != callSiteDescriptor.getNameToken(CallSiteDescriptor.SCHEME)) {
+            return null;
+        }
+
+        final Object receiver = request.getReceiver();
+        if(receiver == null) {
+            // Can't operate on null
+            return null;
+        }
+        return getLinkerForClass(receiver.getClass()).getGuardedInvocation(request, linkerServices);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java b/nashorn/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java
new file mode 100644
index 0000000..360759f
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java
@@ -0,0 +1,138 @@
+/*
+ * 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.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.
+ */
+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) {
+        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 AccessControlContext createNoPermissionsContext() {
+        return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/ClassLinker.java b/nashorn/src/jdk/internal/dynalink/beans/ClassLinker.java
new file mode 100644
index 0000000..15c9e18
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/ClassLinker.java
@@ -0,0 +1,109 @@
+/*
+ * 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.invoke.MethodType;
+import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
+import jdk.internal.dynalink.support.Lookup;
+
+/**
+ * A linker for java.lang.Class objects. Provides a synthetic property "static" that allows access to static fields and
+ * methods on the class (respecting property getter/setter conventions). Note that Class objects are not recognized by
+ * the Dynalink as constructors for the instances of the class, {@link StaticClass} is used for this purpose.
+ * @author Attila Szegedi
+ */
+class ClassLinker extends BeanLinker {
+
+    ClassLinker() {
+        super(Class.class);
+        // Map "classObject.static" to StaticClass.forClass(classObject). Can use EXACT_CLASS since class Class is final.
+        setPropertyGetter("static", FOR_CLASS, ValidationType.EXACT_CLASS);
+    }
+
+    private static final MethodHandle FOR_CLASS = new Lookup(MethodHandles.lookup()).findStatic(StaticClass.class,
+            "forClass", MethodType.methodType(StaticClass.class, Class.class));
+
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/ClassString.java b/nashorn/src/jdk/internal/dynalink/beans/ClassString.java
new file mode 100644
index 0000000..d6c6da0
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/ClassString.java
@@ -0,0 +1,208 @@
+/*
+ * 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.MethodType;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.Guards;
+import jdk.internal.dynalink.support.TypeUtilities;
+
+/**
+ *
+ * @author Attila Szegedi
+ */
+final class ClassString {
+    private final Class<?>[] classes;
+    private int hashCode;
+
+    ClassString(Class<?>[] classes) {
+        this.classes = classes;
+    }
+
+    ClassString(MethodType type) {
+        this(type.parameterArray());
+    }
+
+    Class<?>[] getClasses() {
+        return classes;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if(!(other instanceof ClassString)) {
+            return false;
+        }
+        final Class<?>[] otherClasses = ((ClassString)other).classes;
+        if(otherClasses.length != classes.length) {
+            return false;
+        }
+        for(int i = 0; i < otherClasses.length; ++i) {
+            if(otherClasses[i] != classes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        if(hashCode == 0) {
+            int h = 0;
+            for(int i = 0; i < classes.length; ++i) {
+                h ^= classes[i].hashCode();
+            }
+            hashCode = h;
+        }
+        return hashCode;
+    }
+
+    boolean isVisibleFrom(final ClassLoader classLoader) {
+        for(int i = 0; i < classes.length; ++i) {
+            if(!Guards.canReferenceDirectly(classLoader, classes[i].getClassLoader())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    List<MethodHandle> getMaximallySpecifics(List<MethodHandle> methods, LinkerServices linkerServices, boolean varArg) {
+        return MaximallySpecific.getMaximallySpecificMethods(getApplicables(methods, linkerServices, varArg), varArg,
+                classes, linkerServices);
+    }
+
+    /**
+     * Returns all methods that are applicable to actual parameter classes represented by this ClassString object.
+     */
+    LinkedList<MethodHandle> getApplicables(List<MethodHandle> methods, LinkerServices linkerServices, boolean varArg) {
+        final LinkedList<MethodHandle> list = new LinkedList<>();
+        for(final MethodHandle member: methods) {
+            if(isApplicable(member, linkerServices, varArg)) {
+                list.add(member);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Returns true if the supplied method is applicable to actual parameter classes represented by this ClassString
+     * object.
+     *
+     */
+    private boolean isApplicable(MethodHandle method, LinkerServices linkerServices, boolean varArg) {
+        final Class<?>[] formalTypes = method.type().parameterArray();
+        final int cl = classes.length;
+        final int fl = formalTypes.length - (varArg ? 1 : 0);
+        if(varArg) {
+            if(cl < fl) {
+                return false;
+            }
+        } else {
+            if(cl != fl) {
+                return false;
+            }
+        }
+        // Starting from 1 as we ignore the receiver type
+        for(int i = 1; i < fl; ++i) {
+            if(!canConvert(linkerServices, classes[i], formalTypes[i])) {
+                return false;
+            }
+        }
+        if(varArg) {
+            final Class<?> varArgType = formalTypes[fl].getComponentType();
+            for(int i = fl; i < cl; ++i) {
+                if(!canConvert(linkerServices, classes[i], varArgType)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private static boolean canConvert(LinkerServices ls, Class<?> from, Class<?> to) {
+        return ls == null ? TypeUtilities.isMethodInvocationConvertible(from, to) : ls.canConvert(from, to);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java
new file mode 100644
index 0000000..aee69ff
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java
@@ -0,0 +1,168 @@
+/*
+ * 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.MethodType;
+import java.util.StringTokenizer;
+import jdk.internal.dynalink.linker.LinkerServices;
+
+/**
+ * Represents a single dynamic method. A "dynamic" method can be bound to a single Java method, or can be bound to all
+ * overloaded methods of the same name on a class. Getting an invocation of a dynamic method bound to multiple
+ * overloaded methods will perform overload resolution (actually, it will perform partial overloaded resolution at link
+ * time, but if that fails to identify exactly one target method, it will generate a method handle that will perform the
+ * rest of the overload resolution at invocation time for actual argument types).
+ *
+ * @author Attila Szegedi
+ */
+abstract class DynamicMethod {
+    private final String name;
+
+    DynamicMethod(String name) {
+        this.name = name;
+    }
+
+    String getName() {
+        return name;
+    }
+
+    /**
+     * Creates an invocation for the dynamic method. If the method is overloaded, it will perform overloaded method
+     * resolution based on the specified method type. The resulting resolution can either identify a single method to be
+     * invoked among the overloads, or it can identify multiple ones. In the latter case, the returned method handle
+     * will perform further overload resolution among these candidates at every invocation. If the method to be invoked
+     * is a variable arguments (vararg) method, it will pack the extra arguments in an array before the invocation of
+     * the underlying method if it is not already done.
+     *
+     * @param callSiteType the method type at a call site
+     * @param linkerServices linker services. Used for language-specific type conversions.
+     * @return an invocation suitable for calling the method from the specified call site.
+     */
+    abstract MethodHandle getInvocation(MethodType callSiteType, LinkerServices linkerServices);
+
+    /**
+     * Returns a simple dynamic method representing a single underlying Java method (possibly selected among several
+     * overloads) with formal parameter types exactly matching the passed signature.
+     * @param paramTypes the comma-separated list of requested parameter type names. The names will match both
+     * qualified and unqualified type names.
+     * @return a simple dynamic method representing a single underlying Java method, or null if none of the Java methods
+     * behind this dynamic method exactly match the requested parameter types.
+     */
+    abstract SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes);
+
+    /**
+     * True if this dynamic method already contains a method handle with an identical signature as the passed in method
+     * handle.
+     * @param mh the method handle to check
+     * @return true if it already contains an equivalent method handle.
+     */
+    abstract boolean contains(MethodHandle mh);
+
+    static boolean typeMatchesDescription(String paramTypes, MethodType type) {
+        final StringTokenizer tok = new StringTokenizer(paramTypes, ", ");
+        for(int i = 1; i < type.parameterCount(); ++i) { // i = 1 as we ignore the receiver
+            if(!(tok.hasMoreTokens() && typeNameMatches(tok.nextToken(), type.parameterType(i)))) {
+                return false;
+            }
+        }
+        return !tok.hasMoreTokens();
+    }
+
+    private static boolean typeNameMatches(String typeName, Class<?> type) {
+        final int lastDot = typeName.lastIndexOf('.');
+        final String fullTypeName = type.getCanonicalName();
+        return lastDot != -1 && fullTypeName.endsWith(typeName.substring(lastDot)) || typeName.equals(fullTypeName);
+    }
+
+    static String getClassAndMethodName(Class<?> clazz, String name) {
+        final String clazzName = clazz.getCanonicalName();
+        return (clazzName == null ? clazz.getName() : clazzName) + "." + name;
+    }
+
+    @Override
+    public String toString() {
+        return "[" + getClass().getName() + " " + getName() + "]";
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java
new file mode 100644
index 0000000..d8ceeea
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java
@@ -0,0 +1,129 @@
+/*
+ * 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.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.Guards;
+
+/**
+ * Simple linker that implements the "dyn:call" operation for {@link DynamicMethod} objects - the objects returned by
+ * "dyn:getMethod" from {@link AbstractJavaLinker}.
+ */
+class DynamicMethodLinker implements TypeBasedGuardingDynamicLinker {
+    @Override
+    public boolean canLinkType(Class<?> type) {
+        return DynamicMethod.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) {
+        final Object receiver = linkRequest.getReceiver();
+        if(!(receiver instanceof DynamicMethod)) {
+            return null;
+        }
+        final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
+        if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn")  {
+            return null;
+        }
+        final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
+        if(operator == "call") {
+            final MethodType type = desc.getMethodType();
+            final MethodHandle invocation = ((DynamicMethod)receiver).getInvocation(type.dropParameterTypes(0, 1),
+                    linkerServices);
+            if(invocation == null) {
+                return null;
+            }
+            return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0, type.parameterType(0)),
+                    Guards.getIdentityGuard(receiver));
+        }
+        return null;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java b/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java
new file mode 100644
index 0000000..f4fbd82
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java
@@ -0,0 +1,182 @@
+/*
+ * 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.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Base for classes that expose class field and method information to an {@link AbstractJavaLinker}. There are
+ * subclasses for instance (bean) and static facet of a class.
+ * @author Attila Szegedi
+ */
+abstract class FacetIntrospector {
+    private final Class<?> clazz;
+    private final boolean instance;
+    private final boolean isRestricted;
+
+    protected final AccessibleMembersLookup membersLookup;
+
+    FacetIntrospector(Class<?> clazz, boolean instance) {
+        this.clazz = clazz;
+        this.instance = instance;
+        isRestricted = CheckRestrictedPackage.isRestrictedClass(clazz);
+        membersLookup = new AccessibleMembersLookup(clazz, instance);
+    }
+
+    /**
+     * Returns getters for inner classes.
+     * @return getters for inner classes.
+     */
+    abstract Map<String, MethodHandle> getInnerClassGetters();
+
+    /**
+     * Returns the fields for the class facet.
+     * @return the fields for the class facet.
+     */
+    Collection<Field> getFields() {
+        if(isRestricted) {
+            // NOTE: we can't do anything here. Unlike with methods in AccessibleMethodsLookup, we can't just return
+            // the fields from a public superclass, because this class might define same-named fields which will shadow
+            // the superclass fields, and we have no way to know if they do, since we're denied invocation of
+            // getFields(). Therefore, the only correct course of action is to not expose any public fields from a class
+            // defined in a restricted package.
+            return Collections.emptySet();
+        }
+
+        final Field[] fields = clazz.getFields();
+        final Collection<Field> cfields = new ArrayList<>(fields.length);
+        for(Field field: fields) {
+            if(instance != Modifier.isStatic(field.getModifiers()) && isAccessible(field)) {
+                cfields.add(field);
+            }
+        }
+        return cfields;
+    }
+
+    boolean isAccessible(Member m) {
+        final Class<?> declaring = m.getDeclaringClass();
+        // (declaring == clazz) is just an optimization - we're calling this only from code that operates on a
+        // non-restriced class, so if the declaring class is identical to the class being inspected, then forego
+        // a potentially expensive restricted-package check.
+        return declaring == clazz || !CheckRestrictedPackage.isRestrictedClass(declaring);
+    }
+
+    /**
+     * Returns all the methods in the facet.
+     * @return all the methods in the facet.
+     */
+    Collection<Method> getMethods() {
+        return membersLookup.getMethods();
+    }
+
+
+    MethodHandle unreflectGetter(Field field) {
+        return editMethodHandle(SafeUnreflector.unreflectGetter(field));
+    }
+
+    MethodHandle unreflectSetter(Field field) {
+        return editMethodHandle(SafeUnreflector.unreflectSetter(field));
+    }
+
+    MethodHandle unreflect(Method method) {
+        return editMethodHandle(SafeUnreflector.unreflect(method));
+    }
+
+    /**
+     * Returns an edited method handle. A facet might need to edit an unreflected method handle before it is usable with
+     * the facet. By default, returns the passed method handle unchanged. The class' static facet will introduce a
+     * dropArguments.
+     * @param mh the method handle to edit.
+     * @return the edited method handle.
+     */
+    abstract MethodHandle editMethodHandle(MethodHandle mh);
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/GuardedInvocationComponent.java b/nashorn/src/jdk/internal/dynalink/beans/GuardedInvocationComponent.java
new file mode 100644
index 0000000..f2c76db
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/GuardedInvocationComponent.java
@@ -0,0 +1,252 @@
+/*
+ * 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 jdk.internal.dynalink.linker.GuardedInvocation;
+
+/**
+ * Represents one component for a GuardedInvocation of a potentially composite operation of an
+ * {@link AbstractJavaLinker}. In addition to holding a guarded invocation, it holds semantic information about its
+ * guard. All guards produced in the AbstractJavaLinker are either "Class.isInstance()" or "getClass() == clazz"
+ * expressions. This allows choosing the most restrictive guard as the guard for the composition of two components.
+ * @author Attila Szegedi
+ * @version $Id: $
+ */
+class GuardedInvocationComponent {
+    enum ValidationType {
+        NONE, // No guard; the operation can be linked unconditionally (quite rare); least strict.
+        INSTANCE_OF, // "validatorClass.isInstance(obj)" guard
+        EXACT_CLASS, // "obj.getClass() == validatorClass" guard; most strict.
+        IS_ARRAY, // "obj.getClass().isArray()"
+    }
+
+    private final GuardedInvocation guardedInvocation;
+    private final Validator validator;
+
+    GuardedInvocationComponent(MethodHandle invocation) {
+        this(invocation, null, ValidationType.NONE);
+    }
+
+    GuardedInvocationComponent(MethodHandle invocation, MethodHandle guard, ValidationType validationType) {
+        this(invocation, guard, null, validationType);
+    }
+
+    GuardedInvocationComponent(MethodHandle invocation, MethodHandle guard, Class<?> validatorClass,
+            ValidationType validationType) {
+        this(invocation, guard, new Validator(validatorClass, validationType));
+    }
+
+    GuardedInvocationComponent(GuardedInvocation guardedInvocation, Class<?> validatorClass,
+            ValidationType validationType) {
+        this(guardedInvocation, new Validator(validatorClass, validationType));
+    }
+
+    GuardedInvocationComponent replaceInvocation(MethodHandle newInvocation) {
+        return replaceInvocation(newInvocation, guardedInvocation.getGuard());
+    }
+
+    GuardedInvocationComponent replaceInvocation(MethodHandle newInvocation, MethodHandle newGuard) {
+        return new GuardedInvocationComponent(guardedInvocation.replaceMethods(newInvocation,
+                newGuard), validator);
+    }
+
+    private GuardedInvocationComponent(MethodHandle invocation, MethodHandle guard, Validator validator) {
+        this(new GuardedInvocation(invocation, guard), validator);
+    }
+
+    private GuardedInvocationComponent(GuardedInvocation guardedInvocation, Validator validator) {
+        this.guardedInvocation = guardedInvocation;
+        this.validator = validator;
+    }
+
+    GuardedInvocation getGuardedInvocation() {
+        return guardedInvocation;
+    }
+
+    Class<?> getValidatorClass() {
+        return validator.validatorClass;
+    }
+
+    ValidationType getValidationType() {
+        return validator.validationType;
+    }
+
+    GuardedInvocationComponent compose(MethodHandle compositeInvocation, MethodHandle otherGuard,
+            Class<?> otherValidatorClass, ValidationType otherValidationType) {
+        final Validator compositeValidator = validator.compose(new Validator(otherValidatorClass, otherValidationType));
+        final MethodHandle compositeGuard = compositeValidator == validator ? guardedInvocation.getGuard() : otherGuard;
+        return new GuardedInvocationComponent(compositeInvocation, compositeGuard, compositeValidator);
+    }
+
+    private static class Validator {
+        /*private*/ final Class<?> validatorClass;
+        /*private*/ final ValidationType validationType;
+
+        Validator(Class<?> validatorClass, ValidationType validationType) {
+            this.validatorClass = validatorClass;
+            this.validationType = validationType;
+        }
+
+        Validator compose(Validator other) {
+            if(other.validationType == ValidationType.NONE) {
+                return this;
+            }
+            switch(validationType) {
+                case NONE:
+                    return other;
+                case INSTANCE_OF:
+                    switch(other.validationType) {
+                        case INSTANCE_OF:
+                            if(isAssignableFrom(other)) {
+                                return other;
+                            } else if(other.isAssignableFrom(this)) {
+                                return this;
+                            }
+                            break;
+                        case EXACT_CLASS:
+                            if(isAssignableFrom(other)) {
+                                return other;
+                            }
+                            break;
+                        case IS_ARRAY:
+                            if(validatorClass.isArray()) {
+                                return this;
+                            }
+                            break;
+                        default:
+                            throw new AssertionError();
+                    }
+                    break;
+                case EXACT_CLASS:
+                    switch(other.validationType) {
+                        case INSTANCE_OF:
+                            if(other.isAssignableFrom(this)) {
+                                return this;
+                            }
+                            break;
+                        case EXACT_CLASS:
+                            if(validatorClass == other.validatorClass) {
+                                return this;
+                            }
+                            break;
+                        case IS_ARRAY:
+                            if(validatorClass.isArray()) {
+                                return this;
+                            }
+                            break;
+                        default:
+                            throw new AssertionError();
+                    }
+                    break;
+                case IS_ARRAY:
+                    switch(other.validationType) {
+                        case INSTANCE_OF:
+                        case EXACT_CLASS:
+                            if(other.validatorClass.isArray()) {
+                                return other;
+                            }
+                            break;
+                        case IS_ARRAY:
+                            return this;
+                        default:
+                            throw new AssertionError();
+                    }
+                    break;
+                default:
+                    throw new AssertionError();
+            }
+            throw new AssertionError("Incompatible composition " + this + " vs " + other);
+        }
+
+        private boolean isAssignableFrom(Validator other) {
+            return validatorClass.isAssignableFrom(other.validatorClass);
+        }
+
+        @Override
+        public String toString() {
+            return "Validator[" + validationType + (validatorClass == null ? "" : (" " + validatorClass.getName())) + "]";
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java b/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java
new file mode 100644
index 0000000..182fd01
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java
@@ -0,0 +1,214 @@
+/*
+ * 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.MethodType;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.TypeUtilities;
+
+/**
+ * Utility class that encapsulates the algorithm for choosing the maximally specific methods.
+ *
+ * @author Attila Szegedi
+ */
+class MaximallySpecific {
+    /**
+     * Given a list of methods, returns a list of maximally specific methods.
+     *
+     * @param methods the list of methods
+     * @param varArgs whether to assume the methods are varargs
+     * @return the list of maximally specific methods.
+     */
+    static List<MethodHandle> getMaximallySpecificMethods(List<MethodHandle> methods, boolean varArgs) {
+        return getMaximallySpecificMethods(methods, varArgs, null, null);
+    }
+
+    /**
+     * Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific
+     * conversion preferences.
+     *
+     * @param methods the list of methods
+     * @param varArgs whether to assume the methods are varargs
+     * @param argTypes concrete argument types for the invocation
+     * @return the list of maximally specific methods.
+     */
+    static List<MethodHandle> getMaximallySpecificMethods(List<MethodHandle> methods, boolean varArgs,
+            Class<?>[] argTypes, LinkerServices ls) {
+        if(methods.size() < 2) {
+            return methods;
+        }
+        final LinkedList<MethodHandle> maximals = new LinkedList<>();
+        for(MethodHandle m: methods) {
+            final MethodType methodType = m.type();
+            boolean lessSpecific = false;
+            for(Iterator<MethodHandle> maximal = maximals.iterator(); maximal.hasNext();) {
+                final MethodHandle max = maximal.next();
+                switch(isMoreSpecific(methodType, max.type(), varArgs, argTypes, ls)) {
+                    case TYPE_1_BETTER: {
+                        maximal.remove();
+                        break;
+                    }
+                    case TYPE_2_BETTER: {
+                        lessSpecific = true;
+                        break;
+                    }
+                    case INDETERMINATE: {
+                        // do nothing
+                        break;
+                    }
+                    default: {
+                        throw new AssertionError();
+                    }
+                }
+            }
+            if(!lessSpecific) {
+                maximals.addLast(m);
+            }
+        }
+        return maximals;
+    }
+
+    private static Comparison isMoreSpecific(MethodType t1, MethodType t2, boolean varArgs, Class<?>[] argTypes,
+            LinkerServices ls) {
+        final int pc1 = t1.parameterCount();
+        final int pc2 = t2.parameterCount();
+        assert varArgs || (pc1 == pc2) && (argTypes == null || argTypes.length == pc1);
+        assert (argTypes == null) == (ls == null);
+        final int maxPc = Math.max(Math.max(pc1, pc2), argTypes == null ? 0 : argTypes.length);
+        boolean t1MoreSpecific = false;
+        boolean t2MoreSpecific = false;
+        // NOTE: Starting from 1 as overloaded method resolution doesn't depend on 0th element, which is the type of
+        // 'this'. We're only dealing with instance methods here, not static methods. Actually, static methods will have
+        // a fake 'this' of type StaticClass.
+        for(int i = 1; i < maxPc; ++i) {
+            final Class<?> c1 = getParameterClass(t1, pc1, i, varArgs);
+            final Class<?> c2 = getParameterClass(t2, pc2, i, varArgs);
+            if(c1 != c2) {
+                final Comparison cmp = compare(c1, c2, argTypes, i, ls);
+                if(cmp == Comparison.TYPE_1_BETTER && !t1MoreSpecific) {
+                    t1MoreSpecific = true;
+                    if(t2MoreSpecific) {
+                        return Comparison.INDETERMINATE;
+                    }
+                }
+                if(cmp == Comparison.TYPE_2_BETTER && !t2MoreSpecific) {
+                    t2MoreSpecific = true;
+                    if(t1MoreSpecific) {
+                        return Comparison.INDETERMINATE;
+                    }
+                }
+            }
+        }
+        if(t1MoreSpecific) {
+            return Comparison.TYPE_1_BETTER;
+        } else if(t2MoreSpecific) {
+            return Comparison.TYPE_2_BETTER;
+        }
+        return Comparison.INDETERMINATE;
+    }
+
+    private static Comparison compare(Class<?> c1, Class<?> c2, Class<?>[] argTypes, int i, LinkerServices cmp) {
+        if(cmp != null) {
+            final Comparison c = cmp.compareConversion(argTypes[i], c1, c2);
+            if(c != Comparison.INDETERMINATE) {
+                return c;
+            }
+        }
+        if(TypeUtilities.isSubtype(c1, c2)) {
+            return Comparison.TYPE_1_BETTER;
+        } if(TypeUtilities.isSubtype(c2, c1)) {
+            return Comparison.TYPE_2_BETTER;
+        }
+        return Comparison.INDETERMINATE;
+    }
+
+    private static Class<?> getParameterClass(MethodType t, int l, int i, boolean varArgs) {
+        return varArgs && i >= l - 1 ? t.parameterType(l - 1).getComponentType() : t.parameterType(i);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java
new file mode 100644
index 0000000..7873cf1
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java
@@ -0,0 +1,320 @@
+/*
+ * 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.MethodType;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.internal.dynalink.beans.ApplicableOverloadedMethods.ApplicabilityTest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.TypeUtilities;
+
+/**
+ * Represents an overloaded method.
+ *
+ * @author Attila Szegedi
+ */
+class OverloadedDynamicMethod extends DynamicMethod {
+    /**
+     * Holds a list of all methods.
+     */
+    private final LinkedList<MethodHandle> methods;
+    private final ClassLoader classLoader;
+
+    /**
+     * Creates a new overloaded dynamic method.
+     *
+     * @param clazz the class this method belongs to
+     * @param name the name of the method
+     */
+    OverloadedDynamicMethod(Class<?> clazz, String name) {
+        this(new LinkedList<MethodHandle>(), clazz.getClassLoader(), getClassAndMethodName(clazz, name));
+    }
+
+    private OverloadedDynamicMethod(LinkedList<MethodHandle> methods, ClassLoader classLoader, String name) {
+        super(name);
+        this.methods = methods;
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes) {
+        final LinkedList<MethodHandle> matchingMethods = new LinkedList<>();
+        for(MethodHandle method: methods) {
+            if(typeMatchesDescription(paramTypes, method.type())) {
+                matchingMethods.add(method);
+            }
+        }
+        switch(matchingMethods.size()) {
+            case 0: {
+                return null;
+            }
+            case 1: {
+                final MethodHandle target = matchingMethods.get(0);
+                return new SimpleDynamicMethod(target, SimpleDynamicMethod.getMethodNameWithSignature(target, getName()));
+            }
+            default: {
+                throw new BootstrapMethodError("Can't choose among " + matchingMethods + " for argument types "
+                        + paramTypes + " for method " + getName());
+            }
+        }
+    }
+
+    @Override
+    public MethodHandle getInvocation(final MethodType callSiteType, final LinkerServices linkerServices) {
+        // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2)
+        final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType,
+                ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING);
+        // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3).
+        final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType,
+                ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION);
+        // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4).
+        final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType,
+                ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY);
+
+        // Find the methods that are maximally specific based on the call site signature
+        List<MethodHandle> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods();
+        if(maximallySpecifics.isEmpty()) {
+            maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods();
+            if(maximallySpecifics.isEmpty()) {
+                maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods();
+            }
+        }
+
+        // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based
+        // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they
+        // might match more concrete types passed in invocations. That's why we provisionally call them "invokables".
+        // This is typical for very generic signatures at call sites. Typical example: call site specifies
+        // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability
+        // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation.
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        final List<MethodHandle> invokables = (List)methods.clone();
+        invokables.removeAll(subtypingApplicables.getMethods());
+        invokables.removeAll(methodInvocationApplicables.getMethods());
+        invokables.removeAll(variableArityApplicables.getMethods());
+        for(final Iterator<MethodHandle> it = invokables.iterator(); it.hasNext();) {
+            final MethodHandle m = it.next();
+            if(!isApplicableDynamically(linkerServices, callSiteType, m)) {
+                it.remove();
+            }
+        }
+
+        // If no additional methods can apply at invocation time, and there's more than one maximally specific method
+        // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an
+        // ambiguity error.
+        if(invokables.isEmpty() && maximallySpecifics.size() > 1) {
+            throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types "
+                    + callSiteType);
+        }
+
+        // Merge them all.
+        invokables.addAll(maximallySpecifics);
+        switch(invokables.size()) {
+            case 0: {
+                // No overloads can ever match the call site type
+                return null;
+            }
+            case 1: {
+                // Very lucky, we ended up with a single candidate method handle based on the call site signature; we
+                // can link it very simply by delegating to a SimpleDynamicMethod.
+                final MethodHandle mh = invokables.iterator().next();
+                return new SimpleDynamicMethod(mh).getInvocation(callSiteType, linkerServices);
+            }
+            default: {
+                // We have more than one candidate. We have no choice but to link to a method that resolves overloads on
+                // every invocation (alternatively, we could opportunistically link the one method that resolves for the
+                // current arguments, but we'd need to install a fairly complex guard for that and when it'd fail, we'd
+                // go back all the way to candidate selection.
+                // TODO: cache per call site type
+                return new OverloadedMethod(invokables, this, callSiteType, linkerServices).getInvoker();
+            }
+        }
+
+    }
+
+    @Override
+    public boolean contains(MethodHandle mh) {
+        final MethodType type = mh.type();
+        for(MethodHandle method: methods) {
+            if(typesEqualNoReceiver(type, method.type())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean typesEqualNoReceiver(MethodType type1, MethodType type2) {
+        final int pc = type1.parameterCount();
+        if(pc != type2.parameterCount()) {
+            return false;
+        }
+        for(int i = 1; i < pc; ++i) { // i = 1: ignore receiver
+            if(type1.parameterType(i) != type2.parameterType(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    ClassLoader getClassLoader() {
+        return classLoader;
+    }
+
+    private static boolean isApplicableDynamically(LinkerServices linkerServices, MethodType callSiteType,
+            MethodHandle m) {
+        final MethodType methodType = m.type();
+        final boolean varArgs = m.isVarargsCollector();
+        final int fixedArgLen = methodType.parameterCount() - (varArgs ? 1 : 0);
+        final int callSiteArgLen = callSiteType.parameterCount();
+
+        // Arity checks
+        if(varArgs) {
+            if(callSiteArgLen < fixedArgLen) {
+                return false;
+            }
+        } else if(callSiteArgLen != fixedArgLen) {
+            return false;
+        }
+
+        // Fixed arguments type checks, starting from 1, as receiver type doesn't participate
+        for(int i = 1; i < fixedArgLen; ++i) {
+            if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), methodType.parameterType(i))) {
+                return false;
+            }
+        }
+        if(!varArgs) {
+            // Not vararg; both arity and types matched.
+            return true;
+        }
+
+        final Class<?> varArgArrayType = methodType.parameterType(fixedArgLen);
+        final Class<?> varArgType = varArgArrayType.getComponentType();
+
+        if(fixedArgLen == callSiteArgLen - 1) {
+            // Exactly one vararg; check both array type matching and array component type matching.
+            final Class<?> callSiteArgType = callSiteType.parameterType(fixedArgLen);
+            return isApplicableDynamically(linkerServices, callSiteArgType, varArgArrayType)
+                    || isApplicableDynamically(linkerServices, callSiteArgType, varArgType);
+        }
+
+        // Either zero, or more than one vararg; check if all actual vararg types match the vararg array component type.
+        for(int i = fixedArgLen; i < callSiteArgLen; ++i) {
+            if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), varArgType)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private static boolean isApplicableDynamically(LinkerServices linkerServices, Class<?> callSiteType,
+            Class<?> methodType) {
+        return TypeUtilities.isPotentiallyConvertible(callSiteType, methodType)
+                || linkerServices.canConvert(callSiteType, methodType);
+    }
+
+    private ApplicableOverloadedMethods getApplicables(MethodType callSiteType, ApplicabilityTest test) {
+        return new ApplicableOverloadedMethods(methods, callSiteType, test);
+    }
+
+    /**
+     * Add a method identified by a {@link SimpleDynamicMethod} to this overloaded method's set.
+     *
+     * @param method the method to add.
+     */
+    void addMethod(SimpleDynamicMethod method) {
+        addMethod(method.getTarget());
+    }
+
+    /**
+     * Add a method to this overloaded method's set.
+     *
+     * @param method a method to add
+     */
+    public void addMethod(MethodHandle method) {
+        methods.add(method);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java b/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java
new file mode 100644
index 0000000..d001516
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java
@@ -0,0 +1,265 @@
+/*
+ * 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.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.Lookup;
+
+/**
+ * Represents a subset of overloaded methods for a certain method name on a certain class. It can be either a fixarg or
+ * a vararg subset depending on the subclass. The method is for a fixed number of arguments though (as it is generated
+ * for a concrete call site). As such, all methods in the subset can be invoked with the specified number of arguments
+ * (exactly matching for fixargs, or having less than or equal fixed arguments, for varargs).
+ *
+ * @author Attila Szegedi
+ */
+class OverloadedMethod {
+    private final Map<ClassString, MethodHandle> argTypesToMethods = new ConcurrentHashMap<>();
+    private final OverloadedDynamicMethod parent;
+    private final MethodType callSiteType;
+    private final MethodHandle invoker;
+    private final LinkerServices linkerServices;
+    private final ArrayList<MethodHandle> fixArgMethods;
+    private final ArrayList<MethodHandle> varArgMethods;
+
+    OverloadedMethod(List<MethodHandle> methodHandles, OverloadedDynamicMethod parent, MethodType callSiteType,
+            LinkerServices linkerServices) {
+        this.parent = parent;
+        this.callSiteType = callSiteType;
+        this.linkerServices = linkerServices;
+
+        fixArgMethods = new ArrayList<>(methodHandles.size());
+        varArgMethods = new ArrayList<>(methodHandles.size());
+        final int argNum = callSiteType.parameterCount();
+        for(MethodHandle mh: methodHandles) {
+            if(mh.isVarargsCollector()) {
+                final MethodHandle asFixed = mh.asFixedArity();
+                if(argNum == asFixed.type().parameterCount()) {
+                    fixArgMethods.add(asFixed);
+                }
+                varArgMethods.add(mh);
+            } else {
+                fixArgMethods.add(mh);
+            }
+        }
+        fixArgMethods.trimToSize();
+        varArgMethods.trimToSize();
+
+        final MethodHandle bound = SELECT_METHOD.bindTo(this);
+        final MethodHandle collecting = SimpleDynamicMethod.collectArguments(bound, argNum).asType(
+                callSiteType.changeReturnType(MethodHandle.class));
+        invoker = MethodHandles.foldArguments(MethodHandles.exactInvoker(callSiteType), collecting);
+    }
+
+    MethodHandle getInvoker() {
+        return invoker;
+    }
+
+    private static final MethodHandle SELECT_METHOD = Lookup.findOwnSpecial(MethodHandles.lookup(), "selectMethod",
+            MethodHandle.class, Object[].class);
+
+    @SuppressWarnings("unused")
+    private MethodHandle selectMethod(Object[] args) throws NoSuchMethodException {
+        final Class<?>[] argTypes = new Class[args.length];
+        for(int i = 0; i < argTypes.length; ++i) {
+            final Object arg = args[i];
+            argTypes[i] = arg == null ? callSiteType.parameterType(i) : arg.getClass();
+        }
+        final ClassString classString = new ClassString(argTypes);
+        MethodHandle method = argTypesToMethods.get(classString);
+        if(method == null) {
+            List<MethodHandle> methods = classString.getMaximallySpecifics(fixArgMethods, linkerServices, false);
+            if(methods.isEmpty()) {
+                methods = classString.getMaximallySpecifics(varArgMethods, linkerServices, true);
+            }
+            switch(methods.size()) {
+                case 0: {
+                    method = getNoSuchMethodThrower(argTypes);
+                    break;
+                }
+                case 1: {
+                    method = new SimpleDynamicMethod(methods.get(0)).getInvocation(callSiteType, linkerServices);
+                    break;
+                }
+                default: {
+                    // This is unfortunate - invocation time ambiguity. We can still save the day if
+                    method = getAmbiguousMethodThrower(argTypes, methods);
+                    break;
+                }
+            }
+            // Avoid keeping references to unrelated classes; this ruins the performance a bit, but avoids class loader
+            // memory leaks.
+            if(classString.isVisibleFrom(parent.getClassLoader())) {
+                argTypesToMethods.put(classString, method);
+            }
+        }
+        return method;
+    }
+
+    private MethodHandle getNoSuchMethodThrower(Class<?>[] argTypes) {
+        return adaptThrower(MethodHandles.insertArguments(THROW_NO_SUCH_METHOD, 0, this, argTypes));
+    }
+
+    private static final MethodHandle THROW_NO_SUCH_METHOD = Lookup.findOwnSpecial(MethodHandles.lookup(),
+            "throwNoSuchMethod", void.class, Class[].class);
+
+    @SuppressWarnings("unused")
+    private void throwNoSuchMethod(Class<?>[] argTypes) throws NoSuchMethodException {
+        if(varArgMethods.isEmpty()) {
+            throw new NoSuchMethodException("None of the fixed arity signatures " + getSignatureList(fixArgMethods) +
+                    " of method " + parent.getName() + " match the argument types " + argTypesString(argTypes));
+        }
+        throw new NoSuchMethodException("None of the fixed arity signatures " + getSignatureList(fixArgMethods) +
+                " or the variable arity signatures " + getSignatureList(varArgMethods) + " of the method " +
+                parent.getName() + " match the argument types " + argTypesString(argTypes));
+    }
+
+    private MethodHandle getAmbiguousMethodThrower(Class<?>[] argTypes, List<MethodHandle> methods) {
+        return adaptThrower(MethodHandles.insertArguments(THROW_AMBIGUOUS_METHOD, 0, this, argTypes, methods));
+    }
+
+    private MethodHandle adaptThrower(MethodHandle rawThrower) {
+        return MethodHandles.dropArguments(rawThrower, 0, callSiteType.parameterList()).asType(callSiteType);
+    }
+
+    private static final MethodHandle THROW_AMBIGUOUS_METHOD = Lookup.findOwnSpecial(MethodHandles.lookup(),
+            "throwAmbiguousMethod", void.class, Class[].class, List.class);
+
+    @SuppressWarnings("unused")
+    private void throwAmbiguousMethod(Class<?>[] argTypes, List<MethodHandle> methods) throws NoSuchMethodException {
+        final String arity = methods.get(0).isVarargsCollector() ? "variable" : "fixed";
+        throw new NoSuchMethodException("Can't unambiguously select between " + arity + " arity signatures " +
+                getSignatureList(methods) + " of the method " + parent.getName() + " for argument types " +
+                argTypesString(argTypes));
+    }
+
+    private static String argTypesString(Class<?>[] classes) {
+        final StringBuilder b = new StringBuilder().append('[');
+        appendTypes(b, classes, false);
+        return b.append(']').toString();
+    }
+
+    private static String getSignatureList(List<MethodHandle> methods) {
+        final StringBuilder b = new StringBuilder().append('[');
+        final Iterator<MethodHandle> it = methods.iterator();
+        if(it.hasNext()) {
+            appendSig(b, it.next());
+            while(it.hasNext()) {
+                appendSig(b.append(", "), it.next());
+            }
+        }
+        return b.append(']').toString();
+    }
+
+    private static void appendSig(StringBuilder b, MethodHandle m) {
+        b.append('(');
+        appendTypes(b, m.type().parameterArray(), m.isVarargsCollector());
+        b.append(')');
+    }
+
+    private static void appendTypes(StringBuilder b, Class<?>[] classes, boolean varArg) {
+        final int l = classes.length;
+        if(!varArg) {
+            if(l > 1) {
+                b.append(classes[1].getCanonicalName());
+                for(int i = 2; i < l; ++i) {
+                    b.append(", ").append(classes[i].getCanonicalName());
+                }
+            }
+        } else {
+            for(int i = 1; i < l - 1; ++i) {
+                b.append(classes[i].getCanonicalName()).append(", ");
+            }
+            b.append(classes[l - 1].getComponentType().getCanonicalName()).append("...");
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/SafeUnreflector.java b/nashorn/src/jdk/internal/dynalink/beans/SafeUnreflector.java
new file mode 100644
index 0000000..e828701
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/SafeUnreflector.java
@@ -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);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/SafeUnreflectorImpl.java b/nashorn/src/jdk/internal/dynalink/beans/SafeUnreflectorImpl.java
new file mode 100644
index 0000000..5ae8430
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/SafeUnreflectorImpl.java
@@ -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;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/SandboxClassLoader.java b/nashorn/src/jdk/internal/dynalink/beans/SandboxClassLoader.java
new file mode 100644
index 0000000..00f1e7a
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/SandboxClassLoader.java
@@ -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);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java
new file mode 100644
index 0000000..1fbf7db
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java
@@ -0,0 +1,239 @@
+/*
+ * 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.invoke.MethodType;
+import java.lang.reflect.Array;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.Guards;
+
+/**
+ * A dynamic method bound to exactly one, non-overloaded Java method. Handles varargs.
+ *
+ * @author Attila Szegedi
+ */
+class SimpleDynamicMethod extends DynamicMethod {
+    private final MethodHandle target;
+
+    /**
+     * Creates a simple dynamic method with no name.
+     * @param target the target method handle
+     */
+    SimpleDynamicMethod(MethodHandle target) {
+        this(target, null);
+    }
+
+    /**
+     * Creates a new simple dynamic method, with a name constructed from the class name, method name, and handle
+     * signature.
+     *
+     * @param target the target method handle
+     * @param clazz the class declaring the method
+     * @param name the simple name of the method
+     */
+    SimpleDynamicMethod(MethodHandle target, Class<?> clazz, String name) {
+        this(target, getName(target, clazz, name));
+    }
+
+    SimpleDynamicMethod(MethodHandle target, String name) {
+        super(name);
+        this.target = target;
+    }
+
+    private static String getName(MethodHandle target, Class<?> clazz, String name) {
+        return getMethodNameWithSignature(target, getClassAndMethodName(clazz, name));
+    }
+
+    static String getMethodNameWithSignature(MethodHandle target, String methodName) {
+        final String typeStr = target.type().toString();
+        final int retTypeIndex = typeStr.lastIndexOf(')') + 1;
+        int secondParamIndex = typeStr.indexOf(',') + 1;
+        if(secondParamIndex == 0) {
+            secondParamIndex = retTypeIndex - 1;
+        }
+        return typeStr.substring(retTypeIndex) + " " + methodName + "(" + typeStr.substring(secondParamIndex, retTypeIndex);
+    }
+
+    /**
+     * Returns the target of this dynamic method
+     *
+     * @return the target of this dynamic method
+     */
+    MethodHandle getTarget() {
+        return target;
+    }
+
+    @Override
+    SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes) {
+        return typeMatchesDescription(paramTypes, target.type()) ? this : null;
+    }
+
+    @Override
+    MethodHandle getInvocation(MethodType callSiteType, LinkerServices linkerServices) {
+        final MethodType methodType = target.type();
+        final int paramsLen = methodType.parameterCount();
+        final boolean varArgs = target.isVarargsCollector();
+        final MethodHandle fixTarget = varArgs ? target.asFixedArity() : target;
+        final int fixParamsLen = varArgs ? paramsLen - 1 : paramsLen;
+        final int argsLen = callSiteType.parameterCount();
+        if(argsLen < fixParamsLen) {
+            // Less actual arguments than number of fixed declared arguments; can't invoke.
+            return null;
+        }
+        // Method handle has the same number of fixed arguments as the call site type
+        if(argsLen == fixParamsLen) {
+            // Method handle that matches the number of actual arguments as the number of fixed arguments
+            final MethodHandle matchedMethod;
+            if(varArgs) {
+                // If vararg, add a zero-length array of the expected type as the last argument to signify no variable
+                // arguments.
+                matchedMethod = MethodHandles.insertArguments(fixTarget, fixParamsLen, Array.newInstance(
+                        methodType.parameterType(fixParamsLen).getComponentType(), 0));
+            } else {
+                // Otherwise, just use the method
+                matchedMethod = fixTarget;
+            }
+            return createConvertingInvocation(matchedMethod, linkerServices, callSiteType);
+        }
+
+        // What's below only works for varargs
+        if(!varArgs) {
+            return null;
+        }
+
+        final Class<?> varArgType = methodType.parameterType(fixParamsLen);
+        // Handle a somewhat sinister corner case: caller passes exactly one argument in the vararg position, and we
+        // must handle both a prepacked vararg array as well as a genuine 1-long vararg sequence.
+        if(argsLen == paramsLen) {
+            final Class<?> callSiteLastArgType = callSiteType.parameterType(fixParamsLen);
+            if(varArgType.isAssignableFrom(callSiteLastArgType)) {
+                // Call site signature guarantees we'll always be passed a single compatible array; just link directly
+                // to the method.
+                return createConvertingInvocation(fixTarget, linkerServices, callSiteType);
+            }
+            if(!linkerServices.canConvert(callSiteLastArgType, varArgType)) {
+                // Call site signature guarantees the argument can definitely not be an array (i.e. it is primitive);
+                // link immediately to a vararg-packing method handle.
+                return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
+            }
+            // Call site signature makes no guarantees that the single argument in the vararg position will be
+            // compatible across all invocations. Need to insert an appropriate guard and fall back to generic vararg
+            // method when it is not.
+            return MethodHandles.guardWithTest(Guards.isInstance(varArgType, fixParamsLen, callSiteType),
+                    createConvertingInvocation(fixTarget, linkerServices, callSiteType),
+                    createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType));
+        }
+
+        // Remaining case: more than one vararg.
+        return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
+    }
+
+    @Override
+    public boolean contains(MethodHandle mh) {
+        return target.type().parameterList().equals(mh.type().parameterList());
+    }
+
+    /**
+     * Creates a method handle out of the original target that will collect the varargs for the exact component type of
+     * the varArg array. Note that this will nicely trigger language-specific type converters for exactly those varargs
+     * for which it is necessary when later passed to linkerServices.convertArguments().
+     *
+     * @param target the original method handle
+     * @param parameterCount the total number of arguments in the new method handle
+     * @return a collecting method handle
+     */
+    static MethodHandle collectArguments(MethodHandle target, final int parameterCount) {
+        final MethodType methodType = target.type();
+        final int fixParamsLen = methodType.parameterCount() - 1;
+        final Class<?> arrayType = methodType.parameterType(fixParamsLen);
+        return target.asCollector(arrayType, parameterCount - fixParamsLen);
+    }
+
+    private static MethodHandle createConvertingInvocation(final MethodHandle sizedMethod,
+            final LinkerServices linkerServices, final MethodType callSiteType) {
+        return linkerServices.asType(sizedMethod, callSiteType);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/StaticClass.java b/nashorn/src/jdk/internal/dynalink/beans/StaticClass.java
new file mode 100644
index 0000000..5008c21
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/StaticClass.java
@@ -0,0 +1,138 @@
+/*
+ * 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.Serializable;
+
+/**
+ * Object that represents the static facet of a class (its static methods, properties, and fields, as well as
+ * construction of instances using "dyn:new"). Objects of this class are recognized by the {@link BeansLinker} as being
+ * special, and operations on them will be linked against the represented class' static facet. The "class" synthetic
+ * property is additionally recognized and returns the Java {@link Class} object, as per {@link #getRepresentedClass()}
+ * method. Conversely, {@link Class} objects exposed through {@link BeansLinker} expose the "static" synthetic property
+ * which returns an instance of this class.
+ */
+public class StaticClass implements Serializable {
+    private static final ClassValue<StaticClass> staticClasses = new ClassValue<StaticClass>() {
+        @Override
+        protected StaticClass computeValue(Class<?> type) {
+            return new StaticClass(type);
+        }
+    };
+
+    private static final long serialVersionUID = 1L;
+
+    private final Class<?> clazz;
+
+    /*private*/ StaticClass(Class<?> clazz) {
+        clazz.getClass(); // NPE check
+        this.clazz = clazz;
+    }
+
+    /**
+     * Retrieves the {@link StaticClass} instance for the specified class.
+     * @param clazz the class for which the static facet is requested.
+     * @return the {@link StaticClass} instance representing the specified class.
+     */
+    public static StaticClass forClass(Class<?> clazz) {
+        return staticClasses.get(clazz);
+    }
+
+    /**
+     * Returns the represented Java class.
+     * @return the represented Java class.
+     */
+    public Class<?> getRepresentedClass() {
+        return clazz;
+    }
+
+    @Override
+    public String toString() {
+        return "JavaClassStatics[" + clazz.getName() + "]";
+    }
+
+    private Object readResolve() {
+        return forClass(clazz);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java b/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java
new file mode 100644
index 0000000..d4cedb7
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java
@@ -0,0 +1,117 @@
+/*
+ * 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.invoke.MethodType;
+import java.util.HashMap;
+import java.util.Map;
+
+class StaticClassIntrospector extends FacetIntrospector {
+    StaticClassIntrospector(Class<?> clazz) {
+        super(clazz, false);
+    }
+
+    @Override
+    Map<String, MethodHandle> getInnerClassGetters() {
+        final Map<String, MethodHandle> map = new HashMap<>();
+        for(Class<?> innerClass: membersLookup.getInnerClasses()) {
+            map.put(innerClass.getSimpleName(), editMethodHandle(MethodHandles.constant(StaticClass.class,
+                    StaticClass.forClass(innerClass))));
+        }
+        return map;
+    }
+
+    @Override
+    MethodHandle editMethodHandle(MethodHandle mh) {
+        MethodHandle newHandle = MethodHandles.dropArguments(mh, 0, Object.class);
+        // NOTE: this is a workaround for the fact that dropArguments doesn't preserve vararg collector state.
+        if(mh.isVarargsCollector() && !newHandle.isVarargsCollector()) {
+            final MethodType type = mh.type();
+            newHandle = newHandle.asVarargsCollector(type.parameterType(type.parameterCount() - 1));
+        }
+        return newHandle;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java b/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java
new file mode 100644
index 0000000..c87d666
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java
@@ -0,0 +1,203 @@
+/*
+ * 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.invoke.MethodType;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.Lookup;
+
+/**
+ * Provides a linker for the {@link StaticClass} objects.
+ * @author Attila Szegedi
+ */
+class StaticClassLinker implements TypeBasedGuardingDynamicLinker {
+    private final ClassValue<GuardingDynamicLinker> linkers = new ClassValue<GuardingDynamicLinker>() {
+        @Override
+        protected GuardingDynamicLinker computeValue(Class<?> clazz) {
+            return new SingleClassStaticsLinker(clazz);
+        }
+    };
+
+    private static class SingleClassStaticsLinker extends AbstractJavaLinker {
+        private final DynamicMethod constructor;
+
+        SingleClassStaticsLinker(Class<?> clazz) {
+            super(clazz, IS_CLASS.bindTo(clazz));
+            // Map "staticClassObject.class" to StaticClass.getRepresentedClass(). Some adventurous soul could subclass
+            // StaticClass, so we use INSTANCE_OF validation instead of EXACT_CLASS.
+            setPropertyGetter("class", GET_CLASS, ValidationType.INSTANCE_OF);
+            constructor = createConstructorMethod(clazz);
+        }
+
+        /**
+         * Creates a dynamic method containing all overloads of a class' public constructor
+         * @param clazz the target class
+         * @return a dynamic method containing all overloads of a class' public constructor. If the class has no public
+         * constructors, returns null.
+         */
+        private static DynamicMethod createConstructorMethod(Class<?> clazz) {
+            if(clazz.isArray()) {
+                final MethodHandle boundArrayCtor = ARRAY_CTOR.bindTo(clazz.getComponentType());
+                return new SimpleDynamicMethod(drop(boundArrayCtor.asType(boundArrayCtor.type().changeReturnType(
+                        clazz))), clazz, "<init>");
+            }
+
+            final Constructor<?>[] ctrs = clazz.getConstructors();
+            final List<MethodHandle> mhs = new ArrayList<>(ctrs.length);
+            for(int i = 0; i < ctrs.length; ++i) {
+                mhs.add(drop(SafeUnreflector.unreflectConstructor(ctrs[i])));
+            }
+            return createDynamicMethod(mhs, clazz, "<init>");
+        }
+
+        private static MethodHandle drop(MethodHandle mh) {
+            return MethodHandles.dropArguments(mh, 0, StaticClass.class);
+        }
+
+        @Override
+        FacetIntrospector createFacetIntrospector() {
+            return new StaticClassIntrospector(clazz);
+        }
+
+        @Override
+        public GuardedInvocation getGuardedInvocation(LinkRequest request, LinkerServices linkerServices)
+                throws Exception {
+            final GuardedInvocation gi = super.getGuardedInvocation(request, linkerServices);
+            if(gi != null) {
+                return gi;
+            }
+            final CallSiteDescriptor desc = request.getCallSiteDescriptor();
+            final String op = desc.getNameToken(CallSiteDescriptor.OPERATOR);
+            final MethodType methodType = desc.getMethodType();
+            if("new" == op && constructor != null) {
+                final MethodHandle ctorInvocation = constructor.getInvocation(methodType, linkerServices);
+                if(ctorInvocation != null) {
+                    return new GuardedInvocation(ctorInvocation, getClassGuard(methodType));
+                }
+            }
+            return null;
+        }
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest request, LinkerServices linkerServices) throws Exception {
+        final Object receiver = request.getReceiver();
+        if(receiver instanceof StaticClass) {
+            return linkers.get(((StaticClass)receiver).getRepresentedClass()).getGuardedInvocation(request,
+                    linkerServices);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean canLinkType(Class<?> type) {
+        return type == StaticClass.class;
+    }
+
+    /*private*/ static final MethodHandle GET_CLASS = new Lookup(MethodHandles.lookup()).findVirtual(StaticClass.class,
+            "getRepresentedClass", MethodType.methodType(Class.class));
+
+    /*private*/ static final MethodHandle IS_CLASS = new Lookup(MethodHandles.lookup()).findStatic(StaticClassLinker.class,
+            "isClass", MethodType.methodType(Boolean.TYPE, Class.class, Object.class));
+
+    /*private*/ static final MethodHandle ARRAY_CTOR = Lookup.PUBLIC.findStatic(Array.class, "newInstance",
+            MethodType.methodType(Object.class, Class.class, int.class));
+
+    @SuppressWarnings("unused")
+    private static boolean isClass(Class<?> clazz, Object obj) {
+        return obj instanceof StaticClass && ((StaticClass)obj).getRepresentedClass() == clazz;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/beans/messages.properties b/nashorn/src/jdk/internal/dynalink/beans/messages.properties
new file mode 100644
index 0000000..b930988
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/messages.properties
@@ -0,0 +1,25 @@
+#  Copyright 2009-2013 Attila Szegedi
+#
+#  Licensed under either the Apache License, Version 2.0 (the "Apache 
+#  License") or 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.
+#
+#  A copy of the BSD License is available in the root directory of the 
+#  source distribution of the project under the file name
+#  "Dynalink-License-BSD.txt".
+#
+#  A copy of the Apache License is available in the root directory of the
+#  source distribution of the project under the file name 
+#  "Dynalink-License-Apache-2.0.txt". Alternatively, 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 your chosen License for the specific language governing permissions
+#  and limitations under that License.
+
+couldNotDiscoverAccessibleMethods=Could not discover accessible methods of class {0}, trying its superclasses and interfaces.
\ No newline at end of file
diff --git a/nashorn/src/jdk/internal/dynalink/beans/package.html b/nashorn/src/jdk/internal/dynalink/beans/package.html
new file mode 100644
index 0000000..f405d16
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/package.html
@@ -0,0 +1,86 @@
+<!--

+   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.

+-->

+  <body>

+    <p>

+      Contains the linker for POJOs.

+    </p>

+  </body>

diff --git a/nashorn/src/jdk/internal/dynalink/beans/sandbox/Unreflector.java b/nashorn/src/jdk/internal/dynalink/beans/sandbox/Unreflector.java
new file mode 100644
index 0000000..b5174cd
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/beans/sandbox/Unreflector.java
@@ -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);
+
+}
diff --git a/nashorn/src/jdk/internal/dynalink/linker/ConversionComparator.java b/nashorn/src/jdk/internal/dynalink/linker/ConversionComparator.java
new file mode 100644
index 0000000..8f2d1e0
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/linker/ConversionComparator.java
@@ -0,0 +1,114 @@
+/*
+ * 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.linker;
+
+
+/**
+ * Optional interface to be implemented by {@link GuardingTypeConverterFactory} implementers. Language-specific
+ * conversions can cause increased overloaded method resolution ambiguity, as many methods can become applicable because
+ * of additional conversions. The static way of selecting the "most specific" method will fail more often, because there
+ * will be multiple maximally specific method with unrelated signatures. In these cases, language runtimes can be asked
+ * to resolve the ambiguity by expressing preferences for one conversion over the other.
+ * @author Attila Szegedi
+ */
+public interface ConversionComparator {
+    /**
+     * Enumeration of possible outcomes of comparing one conversion to another.
+     */
+    enum Comparison {
+        INDETERMINATE,
+        TYPE_1_BETTER,
+        TYPE_2_BETTER,
+    }
+
+    /**
+     * Determines which of the two target types is the preferred conversion target from a source type.
+     * @param sourceType the source type.
+     * @param targetType1 one potential target type
+     * @param targetType2 another potential target type.
+     * @return one of Comparison constants that establish which - if any - of the target types is preferred for the
+     * conversion.
+     */
+    public Comparison compareConversion(Class<?> sourceType, Class<?> targetType1, Class<?> targetType2);
+}
diff --git a/nashorn/src/jdk/internal/dynalink/linker/GuardedInvocation.java b/nashorn/src/jdk/internal/dynalink/linker/GuardedInvocation.java
new file mode 100644
index 0000000..26a741e
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/linker/GuardedInvocation.java
@@ -0,0 +1,314 @@
+/*
+ * 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.linker;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.SwitchPoint;
+import java.lang.invoke.WrongMethodTypeException;
+import java.util.List;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.support.Guards;
+
+/**
+ * Represents a conditionally valid method handle. It is an immutable triple of an invocation method handle, a guard
+ * method handle that defines the applicability of the invocation handle, and a switch point that can be used for
+ * external invalidation of the invocation handle. The invocation handle is suitable for invocation if the guard
+ * handle returns true for its arguments, and as long as the switch point is not invalidated. Both the guard and the
+ * switch point are optional; neither, one, or both can be present.
+ *
+ * @author Attila Szegedi
+ */
+public class GuardedInvocation {
+    private final MethodHandle invocation;
+    private final MethodHandle guard;
+    private final SwitchPoint switchPoint;
+
+    /**
+     * Creates a new guarded invocation.
+     *
+     * @param invocation the method handle representing the invocation. Must not be null.
+     * @param guard the method handle representing the guard. Must have the same method type as the invocation, except
+     * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null to represent
+     * an unconditional invocation, although that is unusual.
+     * @throws NullPointerException if invocation is null.
+     */
+    public GuardedInvocation(MethodHandle invocation, MethodHandle guard) {
+        this(invocation, guard, null);
+    }
+
+    /**
+     * Creates a new guarded invocation.
+     *
+     * @param invocation the method handle representing the invocation. Must not be null.
+     * @param guard the method handle representing the guard. Must have the same method type as the invocation, except
+     * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it
+     * and the switch point are null, this represents an unconditional invocation, which is legal but unusual.
+     * @param switchPoint the optional switch point that can be used to invalidate this linkage.
+     * @throws NullPointerException if invocation is null.
+     */
+    public GuardedInvocation(MethodHandle invocation, MethodHandle guard, SwitchPoint switchPoint) {
+        invocation.getClass(); // NPE check
+        this.invocation = invocation;
+        this.guard = guard;
+        this.switchPoint = switchPoint;
+    }
+
+    /**
+     * Creates a new guarded invocation.
+     *
+     * @param invocation the method handle representing the invocation. Must not be null.
+     * @param switchPoint the optional switch point that can be used to invalidate this linkage.
+     * @param guard the method handle representing the guard. Must have the same method type as the invocation, except
+     * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it
+     * and the switch point are null, this represents an unconditional invocation, which is legal but unusual.
+     * @throws NullPointerException if invocation is null.
+     */
+    public GuardedInvocation(MethodHandle invocation, SwitchPoint switchPoint, MethodHandle guard) {
+        this(invocation, guard, switchPoint);
+    }
+    /**
+     * Returns the invocation method handle.
+     *
+     * @return the invocation method handle. It will never be null.
+     */
+    public MethodHandle getInvocation() {
+        return invocation;
+    }
+
+    /**
+     * Returns the guard method handle.
+     *
+     * @return the guard method handle. Can be null.
+     */
+    public MethodHandle getGuard() {
+        return guard;
+    }
+
+    /**
+     * Returns the switch point that can be used to invalidate the invocation handle.
+     *
+     * @return the switch point that can be used to invalidate the invocation handle. Can be null.
+     */
+    public SwitchPoint getSwitchPoint() {
+        return switchPoint;
+    }
+
+    /**
+     * Returns true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated.
+     * @return true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated.
+     */
+    public boolean hasBeenInvalidated() {
+        return switchPoint != null && switchPoint.hasBeenInvalidated();
+    }
+
+    /**
+     * Asserts that the invocation is of the specified type, and the guard (if present) is of the specified type with a
+     * boolean return type.
+     *
+     * @param type the asserted type
+     * @throws WrongMethodTypeException if the invocation and the guard are not of the expected method type.
+     */
+    public void assertType(MethodType type) {
+        assertType(invocation, type);
+        if(guard != null) {
+            assertType(guard, type.changeReturnType(Boolean.TYPE));
+        }
+    }
+
+    /**
+     * Creates a new guarded invocation with different methods, preserving the switch point.
+     *
+     * @param newInvocation the new invocation
+     * @param newGuard the new guard
+     * @return a new guarded invocation with the replaced methods and the same switch point as this invocation.
+     */
+    public GuardedInvocation replaceMethods(MethodHandle newInvocation, MethodHandle newGuard) {
+        return new GuardedInvocation(newInvocation, newGuard, switchPoint);
+    }
+
+    private GuardedInvocation replaceMethodsOrThis(MethodHandle newInvocation, MethodHandle newGuard) {
+        if(newInvocation == invocation && newGuard == guard) {
+            return this;
+        }
+        return replaceMethods(newInvocation, newGuard);
+    }
+
+    /**
+     * Changes the type of the invocation, as if {@link MethodHandle#asType(MethodType)} was applied to its invocation
+     * and its guard, if it has one (with return type changed to boolean, and parameter count potentially truncated for
+     * the guard). If the invocation already is of the required type, returns this object.
+     * @param newType the new type of the invocation.
+     * @return a guarded invocation with the new type applied to it.
+     */
+    public GuardedInvocation asType(MethodType newType) {
+        return replaceMethodsOrThis(invocation.asType(newType), guard == null ? null : Guards.asType(guard, newType));
+    }
+
+    /**
+     * Changes the type of the invocation, as if {@link LinkerServices#asType(MethodHandle, MethodType)} was applied to
+     * its invocation and its guard, if it has one (with return type changed to boolean, and parameter count potentially
+     * truncated for the guard). If the invocation already is of the required type, returns this object.
+     * @param linkerServices the linker services to use for the conversion
+     * @param newType the new type of the invocation.
+     * @return a guarded invocation with the new type applied to it.
+     */
+    public GuardedInvocation asType(LinkerServices linkerServices, MethodType newType) {
+        return replaceMethodsOrThis(linkerServices.asType(invocation, newType), guard == null ? null :
+            Guards.asType(linkerServices, guard, newType));
+    }
+
+    /**
+     * Changes the type of the invocation, as if {@link MethodHandle#asType(MethodType)} was applied to its invocation
+     * and its guard, if it has one (with return type changed to boolean for guard). If the invocation already is of the
+     * required type, returns this object.
+     * @param desc a call descriptor whose method type is adapted.
+     * @return a guarded invocation with the new type applied to it.
+     */
+    public GuardedInvocation asType(CallSiteDescriptor desc) {
+        return asType(desc.getMethodType());
+    }
+
+    /**
+     * Applies argument filters to both the invocation and the guard (if there is one).
+     * @param pos the position of the first argumen being filtered
+     * @param filters the argument filters
+     * @return a filtered invocation
+     */
+    public GuardedInvocation filterArguments(int pos, MethodHandle... filters) {
+        return replaceMethods(MethodHandles.filterArguments(invocation, pos, filters), guard == null ? null :
+            MethodHandles.filterArguments(guard, pos, filters));
+    }
+
+    /**
+     * Makes an invocation that drops arguments in both the invocation and the guard (if there is one).
+     * @param pos the position of the first argument being dropped
+     * @param valueTypes the types of the values being dropped
+     * @return an invocation that drops arguments
+     */
+    public GuardedInvocation dropArguments(int pos, List<Class<?>> valueTypes) {
+        return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null :
+            MethodHandles.dropArguments(guard, pos, valueTypes));
+    }
+
+    /**
+     * Makes an invocation that drops arguments in both the invocation and the guard (if there is one).
+     * @param pos the position of the first argument being dropped
+     * @param valueTypes the types of the values being dropped
+     * @return an invocation that drops arguments
+     */
+    public GuardedInvocation dropArguments(int pos, Class<?>... valueTypes) {
+        return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null :
+            MethodHandles.dropArguments(guard, pos, valueTypes));
+    }
+
+
+    /**
+     * Composes the invocation, switchpoint, and the guard into a composite method handle that knows how to fall back.
+     * @param fallback the fallback method handle in case switchpoint is invalidated or guard returns false.
+     * @return a composite method handle.
+     */
+    public MethodHandle compose(MethodHandle fallback) {
+        return compose(fallback, fallback);
+    }
+
+    /**
+     * Composes the invocation, switchpoint, and the guard into a composite method handle that knows how to fall back.
+     * @param switchpointFallback the fallback method handle in case switchpoint is invalidated.
+     * @param guardFallback the fallback method handle in case guard returns false.
+     * @return a composite method handle.
+     */
+    public MethodHandle compose(MethodHandle switchpointFallback, MethodHandle guardFallback) {
+        final MethodHandle guarded =
+                guard == null ? invocation : MethodHandles.guardWithTest(guard, invocation, guardFallback);
+        return switchPoint == null ? guarded : switchPoint.guardWithTest(guarded, switchpointFallback);
+    }
+
+    private static void assertType(MethodHandle mh, MethodType type) {
+        if(!mh.type().equals(type)) {
+            throw new WrongMethodTypeException("Expected type: " + type + " actual type: " + mh.type());
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/linker/GuardingDynamicLinker.java b/nashorn/src/jdk/internal/dynalink/linker/GuardingDynamicLinker.java
new file mode 100644
index 0000000..2cd0d0f
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/linker/GuardingDynamicLinker.java
@@ -0,0 +1,112 @@
+/*
+ * 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.linker;
+
+/**
+ * The base interface for language-specific dynamic linkers. Such linkers always have to produce method handles with
+ * guards, as the validity of the method handle for calls at a call site inevitably depends on some condition (at the
+ * very least, it depends on the receiver belonging to the language runtime of the linker). Language runtime
+ * implementors will normally implement one for their own language, and declare it in the
+ * <tt>META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker</tt> file within their JAR file.
+ *
+ * @author Attila Szegedi
+ */
+public interface GuardingDynamicLinker {
+    /**
+     * Creates a guarded invocation appropriate for a particular invocation with the specified arguments at a call site.
+     *
+     * @param linkRequest the object describing the request for linking a particular invocation
+     * @param linkerServices linker services
+     * @return a guarded invocation with a method handle suitable for the arguments, as well as a guard condition that
+     * if fails should trigger relinking. Must return null if it can't resolve the invocation. If the returned
+     * invocation is unconditional (which is actually quite rare), the guard in the return value can be null. The
+     * invocation can also have a switch point for asynchronous invalidation of the linkage. If the linker does not
+     * recognize any native language runtime contexts in arguments, or does recognize its own, but receives a call site
+     * descriptor without its recognized context in the arguments, it should invoke
+     * {@link LinkRequest#withoutRuntimeContext()} and link for that.
+     * @throws Exception if the operation fails for whatever reason
+     */
+    public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices)
+            throws Exception;
+}
diff --git a/nashorn/src/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java b/nashorn/src/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java
new file mode 100644
index 0000000..30ab946
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java
@@ -0,0 +1,114 @@
+/*
+ * 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.linker;
+
+import jdk.internal.dynalink.support.TypeUtilities;
+
+/**
+ * Optional interface that can be implemented by {@link GuardingDynamicLinker} implementations to provide
+ * language-runtime specific implicit type conversion capabilities. Note that if you implement this interface, you will
+ * very likely want to implement {@link ConversionComparator} interface too, as your additional language-specific
+ * conversions, in absence of a strategy for prioritizing these conversions, will cause more ambiguity in selecting the
+ * correct overload when trying to link to an overloaded POJO method.
+ *
+ * @author Attila Szegedi
+ */
+public interface GuardingTypeConverterFactory {
+    /**
+     * Returns a guarded invocation that receives an Object of the specified source type and returns an Object converted
+     * to the specified target type. The type of the invocation is targetType(sourceType), while the type of the guard
+     * is boolean(sourceType). Note that this will never be invoked for type conversions allowed by the JLS 5.3 "Method
+     * Invocation Conversion", see {@link TypeUtilities#isMethodInvocationConvertible(Class, Class)} for details. An
+     * implementation can assume it is never requested to produce a converter for these conversions.
+     *
+     * @param sourceType source type
+     * @param targetType the target type.
+     * @return a guarded invocation that can take an object (if it passes guard) and returns another object that is its
+     * representation coerced into the target type. In case the factory is certain it is unable to handle a conversion,
+     * it can return null. In case the factory is certain that it can always handle the conversion, it can return an
+     * unconditional invocation (one whose guard is null).
+     * @throws Exception if there was an error during creation of the converter
+     */
+    public GuardedInvocation convertToType(Class<?> sourceType, Class<?> targetType) throws Exception;
+}
diff --git a/nashorn/src/jdk/internal/dynalink/linker/LinkRequest.java b/nashorn/src/jdk/internal/dynalink/linker/LinkRequest.java
new file mode 100644
index 0000000..1a82a4f
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/linker/LinkRequest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.linker;
+
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.DynamicLinkerFactory;
+
+/**
+ * Represents a request to link a particular invocation at a particular call site. Instances of these requests are being
+ * passed to {@link GuardingDynamicLinker}.
+ *
+ * @author Attila Szegedi
+ */
+public interface LinkRequest {
+    /**
+     * Returns the call site descriptor for the call site being linked.
+     *
+     * @return the call site descriptor for the call site being linked.
+     */
+    public CallSiteDescriptor getCallSiteDescriptor();
+
+    /**
+     * Returns the arguments for the invocation being linked. The returned array is a clone; modifications to it won't
+     * affect the arguments in this request.
+     *
+     * @return the arguments for the invocation being linked.
+     */
+    public Object[] getArguments();
+
+    /**
+     * Returns the 0th argument for the invocation being linked; this is typically the receiver object.
+     *
+     * @return the receiver object.
+     */
+    public Object getReceiver();
+
+    /**
+     * Returns true if the call site is considered unstable, that is, it has been relinked more times than was
+     * specified in {@link DynamicLinkerFactory#setUnstableRelinkThreshold(int)}. Linkers should use this as a
+     * hint to prefer producing linkage that is more stable (its guard fails less frequently), even if that assumption
+     * causes a less effective version of an operation to be linked. This is just a hint, of course, and linkers are
+     * free to ignore this property.
+     * @return true if the call site is considered unstable.
+     */
+    public boolean isCallSiteUnstable();
+
+    /**
+     * Returns a request stripped from runtime context arguments. Some language runtimes will include runtime-specific
+     * context parameters in their call sites as few arguments between 0th argument "this" and the normal arguments. If
+     * a linker does not recognize such contexts at all, or does not recognize the call site as one with its own
+     * context, it can ask for the alternative link request with context parameters and arguments removed, and link
+     * against it instead.
+     *
+     * @return the context-stripped request. If the link request does not have any language runtime specific context
+     * parameters, the same link request is returned.
+     */
+    public LinkRequest withoutRuntimeContext();
+
+    /**
+     * Returns a request identical to this one with call site descriptor and arguments replaced with the ones specified.
+     *
+     * @param callSiteDescriptor the new call site descriptor
+     * @param arguments the new arguments
+     * @return a new request identical to this one, except with the call site descriptor and arguments replaced with the
+     * specified ones.
+     */
+    public LinkRequest replaceArguments(CallSiteDescriptor callSiteDescriptor, Object[] arguments);
+}
diff --git a/nashorn/src/jdk/internal/dynalink/linker/LinkerServices.java b/nashorn/src/jdk/internal/dynalink/linker/LinkerServices.java
new file mode 100644
index 0000000..deaf820
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/linker/LinkerServices.java
@@ -0,0 +1,164 @@
+/*
+ * 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.linker;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.DynamicLinker;
+import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
+
+/**
+ * Interface for services provided to {@link GuardingDynamicLinker} instances by the {@link DynamicLinker} that owns
+ * them. You can think of it as the interface of the {@link DynamicLinker} that faces the {@link GuardingDynamicLinker}
+ * s.
+ *
+ * @author Attila Szegedi
+ */
+public interface LinkerServices {
+    /**
+     * Similar to {@link MethodHandle#asType(MethodType)} except it also hooks in method handles produced by
+     * {@link GuardingTypeConverterFactory} implementations, providing for language-specific type coercing of
+     * parameters. It will apply {@link MethodHandle#asType(MethodType)} for all primitive-to-primitive,
+     * wrapper-to-primitive, primitive-to-wrapper conversions as well as for all upcasts. For all other conversions,
+     * it'll insert {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with composite filters
+     * provided by {@link GuardingTypeConverterFactory} implementations. It doesn't use language-specific conversions on
+     * the return type.
+     *
+     * @param handle target method handle
+     * @param fromType the types of source arguments
+     * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)} and
+     * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with
+     * {@link GuardingTypeConverterFactory} produced type converters as filters.
+     */
+    public MethodHandle asType(MethodHandle handle, MethodType fromType);
+
+    /**
+     * Given a source and target type, returns a method handle that converts between them. Never returns null; in worst
+     * case it will return an identity conversion (that might fail for some values at runtime). You rarely need to use
+     * this method directly; you should mostly rely on {@link #asType(MethodHandle, MethodType)} instead. You really
+     * only need this method if you have a piece of your program that is written in Java, and you need to reuse existing
+     * type conversion machinery in a non-invokedynamic context.
+     * @param sourceType the type to convert from
+     * @param targetType the type to convert to
+     * @return a method handle performing the conversion.
+     */
+    public MethodHandle getTypeConverter(Class<?> sourceType, Class<?> targetType);
+
+    /**
+     * Returns true if there might exist a conversion between the requested types (either an automatic JVM conversion,
+     * or one provided by any available {@link GuardingTypeConverterFactory}), or false if there definitely does not
+     * exist a conversion between the requested types. Note that returning true does not guarantee that the conversion
+     * will succeed at runtime (notably, if the "from" or "to" types are sufficiently generic), but returning false
+     * guarantees that it would fail.
+     *
+     * @param from the source type for the conversion
+     * @param to the target type for the conversion
+     * @return true if there can be a conversion, false if there can not.
+     */
+    public boolean canConvert(Class<?> from, Class<?> to);
+
+    /**
+     * Creates a guarded invocation using the {@link DynamicLinker} that exposes this linker services interface. Linkers
+     * can typically use them to delegate linking of wrapped objects.
+     *
+     * @param linkRequest a request for linking the invocation
+     * @return a guarded invocation linked by the top-level linker (or any of its delegates). Can be null if no
+     * available linker is able to link the invocation.
+     * @throws Exception in case the top-level linker throws an exception
+     */
+    public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest) throws Exception;
+
+    /**
+     * Determines which of the two type conversions from a source type to the two target types is preferred. This is
+     * used for dynamic overloaded method resolution. If the source type is convertible to exactly one target type with
+     * a method invocation conversion, it is chosen, otherwise available {@link ConversionComparator}s are consulted.
+     * @param sourceType the source type.
+     * @param targetType1 one potential target type
+     * @param targetType2 another potential target type.
+     * @return one of Comparison constants that establish which - if any - of the target types is preferable for the
+     * conversion.
+     */
+    public Comparison compareConversion(Class<?> sourceType, Class<?> targetType1, Class<?> targetType2);
+}
diff --git a/nashorn/src/jdk/internal/dynalink/linker/TypeBasedGuardingDynamicLinker.java b/nashorn/src/jdk/internal/dynalink/linker/TypeBasedGuardingDynamicLinker.java
new file mode 100644
index 0000000..c7fac02
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/linker/TypeBasedGuardingDynamicLinker.java
@@ -0,0 +1,102 @@
+/*
+ * 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.linker;
+
+/**
+ * A guarding dynamic linker that can determine whether it can link the call site solely based on the type of the first
+ * argument at linking invocation time. (The first argument is usually the receiver class). Most language-specific
+ * linkers will fall into this category, as they recognize their native objects as Java objects of classes implementing
+ * a specific language-native interface or superclass. The linker mechanism can optimize the dispatch for these linkers.
+ *
+ * @author Attila Szegedi
+ */
+public interface TypeBasedGuardingDynamicLinker extends GuardingDynamicLinker {
+    /**
+     * Returns true if the linker can link an invocation where the first argument (receiver) is of the specified type.
+     *
+     * @param type the type to link
+     * @return true if the linker can link calls for the receiver type, or false otherwise.
+     */
+    public boolean canLinkType(Class<?> type);
+}
diff --git a/nashorn/src/jdk/internal/dynalink/linker/package.html b/nashorn/src/jdk/internal/dynalink/linker/package.html
new file mode 100644
index 0000000..4e3991d
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/linker/package.html
@@ -0,0 +1,87 @@
+<!--

+   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.

+-->

+  <body>

+    <p>

+      Contains interfaces and classes needed by language runtimes to implement

+      their own language-specific linkers.

+    </p>

+  </body>

diff --git a/nashorn/src/jdk/internal/dynalink/package.html b/nashorn/src/jdk/internal/dynalink/package.html
new file mode 100644
index 0000000..588823a
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/package.html
@@ -0,0 +1,93 @@
+<!--

+   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.

+-->

+  <body>

+    <p>

+      Contains the main API for using the dynamic linking facilities. A

+      scripting framework or a language runtime that does not define its own

+      linker but only uses linkers available in the system will only need to

+      use classes and interfaces from this package.

+    </p>

+    <p>

+      Languages that wish to define and use their own linkers will also need to

+      use the {@link jdk.internal.dynalink.linker} package.

+    </p>

+  </body>

diff --git a/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java
new file mode 100644
index 0000000..e51f6fe
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java
@@ -0,0 +1,185 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.util.Objects;
+import jdk.internal.dynalink.CallSiteDescriptor;
+
+/**
+ * A base class for call site descriptor implementations. Provides reconstruction of the name from the tokens, as well
+ * as a generally useful {@code equals} and {@code hashCode} methods.
+ * @author Attila Szegedi
+ */
+public abstract class AbstractCallSiteDescriptor implements CallSiteDescriptor {
+
+    @Override
+    public String getName() {
+        return appendName(new StringBuilder(getNameLength())).toString();
+    }
+
+   @Override
+   public Lookup getLookup() {
+       return MethodHandles.publicLookup();
+   }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof CallSiteDescriptor && equals((CallSiteDescriptor)obj);
+    }
+
+    /**
+     * Returns true if this call site descriptor is equal to the passed call site descriptor.
+     * @param csd the other call site descriptor.
+     * @return true if they are equal.
+     */
+    public boolean equals(CallSiteDescriptor csd) {
+        if(csd == null) {
+            return false;
+        }
+        if(csd == this) {
+            return true;
+        }
+        final int ntc = getNameTokenCount();
+        if(ntc != csd.getNameTokenCount()) {
+            return false;
+        }
+        for(int i = ntc; i-- > 0;) { // Reverse order as variability is higher at the end
+            if(!Objects.equals(getNameToken(i), csd.getNameToken(i))) {
+                return false;
+            }
+        }
+        if(!getMethodType().equals(csd.getMethodType())) {
+            return false;
+        }
+        return lookupsEqual(getLookup(), csd.getLookup());
+    }
+
+    @Override
+    public int hashCode() {
+        final int c = getNameTokenCount();
+        int h = 0;
+        for(int i = 0; i < c; ++i) {
+            h = h * 31 + getNameToken(i).hashCode();
+        }
+        return h * 31 + getMethodType().hashCode();
+    }
+
+    @Override
+    public String toString() {
+        final String mt = getMethodType().toString();
+        final String l = getLookup().toString();
+        final StringBuilder b = new StringBuilder(l.length() + 1 + mt.length() + getNameLength());
+        return appendName(b).append(mt).append("@").append(l).toString();
+    }
+
+    private int getNameLength() {
+        final int c = getNameTokenCount();
+        int l = 0;
+        for(int i = 0; i < c; ++i) {
+            l += getNameToken(i).length();
+        }
+        return l +  c - 1;
+    }
+
+    private StringBuilder appendName(StringBuilder b) {
+        b.append(getNameToken(0));
+        final int c = getNameTokenCount();
+        for(int i = 1; i < c; ++i) {
+            b.append(':').append(getNameToken(i));
+        }
+        return b;
+    }
+
+    private static boolean lookupsEqual(Lookup l1, Lookup l2) {
+        if(l1 == l2) {
+            return true;
+        }
+        if(l1.lookupClass() != l2.lookupClass()) {
+            return false;
+        }
+        return l1.lookupModes() == l2.lookupModes();
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java b/nashorn/src/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java
new file mode 100644
index 0000000..c05d35e
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java
@@ -0,0 +1,117 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MutableCallSite;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.RelinkableCallSite;
+
+/**
+ * A basic implementation of the {@link RelinkableCallSite} as a {@link MutableCallSite} subclass.
+ *
+ * @author Attila Szegedi
+ */
+public abstract class AbstractRelinkableCallSite extends MutableCallSite implements RelinkableCallSite {
+    private final CallSiteDescriptor descriptor;
+
+    /**
+     * Creates a new relinkable call site.
+     * @param descriptor the descriptor for this call site
+     */
+    protected AbstractRelinkableCallSite(CallSiteDescriptor descriptor) {
+        super(descriptor.getMethodType());
+        this.descriptor = descriptor;
+    }
+
+    @Override
+    public CallSiteDescriptor getDescriptor() {
+        return descriptor;
+    }
+
+    @Override
+    public void initialize(MethodHandle relinkAndInvoke) {
+        setTarget(relinkAndInvoke);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/AutoDiscovery.java b/nashorn/src/jdk/internal/dynalink/support/AutoDiscovery.java
new file mode 100644
index 0000000..2909365
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/AutoDiscovery.java
@@ -0,0 +1,133 @@
+/*
+ * 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.support;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ServiceLoader;
+import jdk.internal.dynalink.DynamicLinkerFactory;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+
+/**
+ * Provides methods for automatic discovery of all guarding dynamic linkers listed in the
+ * <tt>/META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker</tt> resources of all JAR files for a
+ * particular class loader. Ordinarily, you will not use this class directly, but you will use a
+ * {@link DynamicLinkerFactory} instead.
+ */
+public class AutoDiscovery {
+
+    private AutoDiscovery() {
+    }
+
+    /**
+     * Discovers all guarding dynamic linkers listed in JAR files of the context class loader of the current thread.
+     *
+     * @return a list of available linkers. Can be zero-length list but not null.
+     */
+    public static List<GuardingDynamicLinker> loadLinkers() {
+        return getLinkers(ServiceLoader.load(GuardingDynamicLinker.class));
+    }
+
+    /**
+     * Discovers all guarding dynamic linkers listed in JAR files of the specified class loader.
+     *
+     * @param cl the class loader to use
+     * @return a list of guarding dynamic linkers available through the specified class loader. Can be zero-length list
+     * but not null.
+     */
+    public static List<GuardingDynamicLinker> loadLinkers(ClassLoader cl) {
+        return getLinkers(ServiceLoader.load(GuardingDynamicLinker.class, cl));
+    }
+
+    /**
+     * I can't believe there's no Collections API for making a List given an Iterator...
+     */
+    private static <T> List<T> getLinkers(ServiceLoader<T> loader) {
+        final List<T> list = new LinkedList<>();
+        for(final T linker: loader) {
+            list.add(linker);
+        }
+        return list;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/Backport.java b/nashorn/src/jdk/internal/dynalink/support/Backport.java
new file mode 100644
index 0000000..1be7dc3
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/Backport.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandles;
+
+/**
+ * @author Attila Szegedi
+ */
+public class Backport {
+    /**
+     * True if Remi's JSR-292 backport agent is active; false if we're using native OpenJDK JSR-292 support.
+     */
+    public static final boolean inUse = MethodHandles.class.getName().startsWith("jsr292");
+
+    private Backport() {
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/BottomGuardingDynamicLinker.java b/nashorn/src/jdk/internal/dynalink/support/BottomGuardingDynamicLinker.java
new file mode 100644
index 0000000..7a2700e
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/BottomGuardingDynamicLinker.java
@@ -0,0 +1,116 @@
+/*
+ * 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.support;
+
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+
+/**
+ * A linker that can't link any call site. Only used internally by {@link CompositeTypeBasedGuardingDynamicLinker}. Can
+ * be used by other language runtimes if they need it though.
+ *
+ * @author Attila Szegedi
+ */
+public class BottomGuardingDynamicLinker implements TypeBasedGuardingDynamicLinker {
+
+    /**
+     * The sole instance of this stateless linker.
+     */
+    public static final BottomGuardingDynamicLinker INSTANCE = new BottomGuardingDynamicLinker();
+
+    private BottomGuardingDynamicLinker() {
+    }
+
+    @Override
+    public boolean canLinkType(Class<?> type) {
+        return false;
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) {
+        return null;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/CallSiteDescriptorFactory.java b/nashorn/src/jdk/internal/dynalink/support/CallSiteDescriptorFactory.java
new file mode 100644
index 0000000..b0039d2
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/CallSiteDescriptorFactory.java
@@ -0,0 +1,263 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.WeakHashMap;
+import jdk.internal.dynalink.CallSiteDescriptor;
+
+/**
+ * Usable as a default factory for call site descriptor implementations. It is weakly canonicalizing, meaning it will
+ * return the same immutable call site descriptor for identical inputs, i.e. repeated requests for a descriptor
+ * signifying public lookup for "dyn:getProp:color" of type "Object(Object)" will return the same object as long as
+ * a previously created, at least softly reachable one exists. It also uses several different implementations of the
+ * {@link CallSiteDescriptor} internally, and chooses the most space-efficient one based on the input.
+ * @author Attila Szegedi
+ */
+public class CallSiteDescriptorFactory {
+    private static final WeakHashMap<CallSiteDescriptor, WeakReference<CallSiteDescriptor>> publicDescs =
+            new WeakHashMap<>();
+
+
+    private CallSiteDescriptorFactory() {
+    }
+
+    /**
+     * Creates a new call site descriptor instance. The actual underlying class of the instance is dependent on the
+     * passed arguments to be space efficient; i.e. if you  only use the public lookup, you'll get back an
+     * implementation that doesn't waste space on storing the lookup object.
+     * @param lookup the lookup that determines access rights at the call site. If your language runtime doesn't have
+     * equivalents of Java access concepts, just use {@link MethodHandles#publicLookup()}. Must not be null.
+     * @param name the name of the method at the call site. Must not be null.
+     * @param methodType the type of the method at the call site. Must not be null.
+     * @return a call site descriptor representing the input. Note that although the method name is "create", it will
+     * in fact return a weakly-referenced canonical instance.
+     */
+    public static CallSiteDescriptor create(Lookup lookup, String name, MethodType methodType) {
+        name.getClass(); // NPE check
+        methodType.getClass(); // NPE check
+        lookup.getClass(); // NPE check
+        final String[] tokenizedName = tokenizeName(name);
+        if(isPublicLookup(lookup)) {
+            return getCanonicalPublicDescriptor(createPublicCallSiteDescriptor(tokenizedName, methodType));
+        }
+        return new LookupCallSiteDescriptor(tokenizedName, methodType, lookup);
+    }
+
+    static CallSiteDescriptor getCanonicalPublicDescriptor(final CallSiteDescriptor desc) {
+        synchronized(publicDescs) {
+            final WeakReference<CallSiteDescriptor> ref = publicDescs.get(desc);
+            if(ref != null) {
+                final CallSiteDescriptor canonical = ref.get();
+                if(canonical != null) {
+                    return canonical;
+                }
+            }
+            publicDescs.put(desc, new WeakReference<>(desc));
+        }
+        return desc;
+    }
+
+    private static CallSiteDescriptor createPublicCallSiteDescriptor(String[] tokenizedName, MethodType methodType) {
+        final int l = tokenizedName.length;
+        if(l > 0 && tokenizedName[0] == "dyn") {
+            if(l == 2) {
+                return new UnnamedDynCallSiteDescriptor(tokenizedName[1], methodType);
+            } if (l == 3) {
+                return new NamedDynCallSiteDescriptor(tokenizedName[1], tokenizedName[2], methodType);
+            }
+        }
+        return new DefaultCallSiteDescriptor(tokenizedName, methodType);
+    }
+
+    private static boolean isPublicLookup(Lookup lookup) {
+        return lookup == MethodHandles.publicLookup();
+    }
+
+    /**
+     * Tokenizes the composite name along colons, as well as {@link NameCodec#decode(String) demangles} and interns
+     * the tokens. The first two tokens are not demangled as they are supposed to be the naming scheme and the name of
+     * the operation which can be expected to consist of just alphabetical characters.
+     * @param name the composite name consisting of colon-separated, possibly mangled tokens.
+     * @return an array of tokens
+     */
+    public static String[] tokenizeName(String name) {
+        final StringTokenizer tok = new StringTokenizer(name, CallSiteDescriptor.TOKEN_DELIMITER);
+        final String[] tokens = new String[tok.countTokens()];
+        for(int i = 0; i < tokens.length; ++i) {
+            String token = tok.nextToken();
+            if(i > 1) {
+                token = NameCodec.decode(token);
+            }
+            tokens[i] = token.intern();
+        }
+        return tokens;
+    }
+
+    /**
+     * Tokenizes a composite operation name along pipe characters. I.e. if you have a "dyn:getElem|getProp|getMethod"
+     * operation, returns a list of ["getElem", "getProp", "getMethod"]. The tokens are not interned.
+     * @param desc the call site descriptor with the operation
+     * @return a list of tokens
+     */
+    public static List<String> tokenizeOperators(CallSiteDescriptor desc) {
+        final String ops = desc.getNameToken(CallSiteDescriptor.OPERATOR);
+        final StringTokenizer tok = new StringTokenizer(ops, CallSiteDescriptor.OPERATOR_DELIMITER);
+        final int count = tok.countTokens();
+        if(count == 1) {
+            return Collections.singletonList(ops);
+        }
+        final String[] tokens = new String[count];
+        for(int i = 0; i < count; ++i) {
+            tokens[i] = tok.nextToken();
+        }
+        return Arrays.asList(tokens);
+    }
+
+    /**
+     * Returns a new call site descriptor that is identical to the passed one, except that it has some parameter types
+     * removed from its method type.
+     * @param desc the original call site descriptor
+     * @param start index of the first parameter to remove
+     * @param end index of the first parameter to not remove
+     * @return a new call site descriptor with modified method type
+     */
+    public static CallSiteDescriptor dropParameterTypes(CallSiteDescriptor desc, int start, int end) {
+        return desc.changeMethodType(desc.getMethodType().dropParameterTypes(start, end));
+    }
+
+    /**
+     * Returns a new call site descriptor that is identical to the passed one, except that it has a single parameter
+     * type changed in its method type.
+     * @param desc the original call site descriptor
+     * @param num index of the parameter to change
+     * @param nptype the new parameter type
+     * @return a new call site descriptor with modified method type
+     */
+    public static CallSiteDescriptor changeParameterType(CallSiteDescriptor desc, int num, Class<?> nptype) {
+        return desc.changeMethodType(desc.getMethodType().changeParameterType(num, nptype));
+    }
+
+    /**
+     * Returns a new call site descriptor that is identical to the passed one, except that it has the return type
+     * changed in its method type.
+     * @param desc the original call site descriptor
+     * @param nrtype the new return type
+     * @return a new call site descriptor with modified method type
+     */
+    public static CallSiteDescriptor changeReturnType(CallSiteDescriptor desc, Class<?> nrtype) {
+        return desc.changeMethodType(desc.getMethodType().changeReturnType(nrtype));
+    }
+
+    /**
+     * Returns a new call site descriptor that is identical to the passed one, except that it has additional parameter
+     * types inserted into its method type.
+     * @param desc the original call site descriptor
+     * @param num index at which the new parameters are inserted
+     * @param ptypesToInsert the new types to insert
+     * @return a new call site descriptor with modified method type
+     */
+    public static CallSiteDescriptor insertParameterTypes(CallSiteDescriptor desc, int num, Class<?>... ptypesToInsert) {
+        return desc.changeMethodType(desc.getMethodType().insertParameterTypes(num, ptypesToInsert));
+    }
+
+    /**
+     * Returns a new call site descriptor that is identical to the passed one, except that it has additional parameter
+     * types inserted into its method type.
+     * @param desc the original call site descriptor
+     * @param num index at which the new parameters are inserted
+     * @param ptypesToInsert the new types to insert
+     * @return a new call site descriptor with modified method type
+     */
+    public static CallSiteDescriptor insertParameterTypes(CallSiteDescriptor desc, int num, List<Class<?>> ptypesToInsert) {
+        return desc.changeMethodType(desc.getMethodType().insertParameterTypes(num, ptypesToInsert));
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/ClassMap.java b/nashorn/src/jdk/internal/dynalink/support/ClassMap.java
new file mode 100644
index 0000000..7369d25
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/ClassMap.java
@@ -0,0 +1,177 @@
+/*
+ * 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.support;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A dual map that can either strongly or weakly reference a given class depending on whether the class is visible from
+ * a class loader or not.
+ *
+ * @author Attila Szegedi
+ * @param <T> the type of the values in the map
+ */
+public abstract class ClassMap<T> {
+    private final ConcurrentMap<Class<?>, T> map = new ConcurrentHashMap<>();
+    private final Map<Class<?>, Reference<T>> weakMap = new WeakHashMap<>();
+    private final ClassLoader classLoader;
+
+    /**
+     * Creates a new class map. It will use strong references for all keys and values where the key is a class visible
+     * from the class loader, and will use weak keys and soft values for all other classes.
+     *
+     * @param classLoader the classloader that determines strong referenceability.
+     */
+    protected ClassMap(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
+    /**
+     * Compute the value associated with the given class. It is possible that the method will be invoked several times
+     * (or even concurrently) for the same class parameter.
+     *
+     * @param clazz the class to compute the value for
+     * @return the return value. Must not be null.
+     */
+    protected abstract T computeValue(Class<?> clazz);
+
+    /**
+     * Returns the class loader that governs the strong referenceability of this class map.
+     *
+     * @return the class loader that governs the strong referenceability of this class map.
+     */
+    public ClassLoader getClassLoader() {
+        return classLoader;
+    }
+
+    /**
+     * Returns the value associated with the class
+     *
+     * @param clazz the class
+     * @return the value associated with the class
+     */
+    public T get(Class<?> clazz) {
+        // Check in fastest first - objects we're allowed to strongly reference
+        final T v = map.get(clazz);
+        if(v != null) {
+            return v;
+        }
+        // Check objects we're not allowed to strongly reference
+        Reference<T> ref;
+        synchronized(weakMap) {
+            ref = weakMap.get(clazz);
+        }
+        if(ref != null) {
+            final T refv = ref.get();
+            if(refv != null) {
+                return refv;
+            }
+        }
+        // Not found in either place; create a new value
+        final T newV = computeValue(clazz);
+        assert newV != null;
+        // If allowed to strongly reference, put it in the fast map
+        if(Guards.canReferenceDirectly(classLoader, clazz.getClassLoader())) {
+            final T oldV = map.putIfAbsent(clazz, newV);
+            return oldV != null ? oldV : newV;
+        }
+        // Otherwise, put it into the weak map
+        synchronized(weakMap) {
+            ref = weakMap.get(clazz);
+            if(ref != null) {
+                final T oldV = ref.get();
+                if(oldV != null) {
+                    return oldV;
+                }
+            }
+            weakMap.put(clazz, new SoftReference<>(newV));
+            return newV;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java b/nashorn/src/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java
new file mode 100644
index 0000000..44f5c4b
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java
@@ -0,0 +1,131 @@
+/*
+ * 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.support;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+
+/**
+ * A {@link GuardingDynamicLinker} that delegates sequentially to a list of other guarding dynamic linkers. The first
+ * value returned from a component linker other than null is returned. If no component linker returns an invocation,
+ * null is returned.
+ *
+ * @author Attila Szegedi
+ */
+public class CompositeGuardingDynamicLinker implements GuardingDynamicLinker, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final GuardingDynamicLinker[] linkers;
+
+    /**
+     * Creates a new composite linker.
+     *
+     * @param linkers a list of component linkers.
+     */
+    public CompositeGuardingDynamicLinker(Iterable<? extends GuardingDynamicLinker> linkers) {
+        final List<GuardingDynamicLinker> l = new LinkedList<>();
+        for(GuardingDynamicLinker linker: linkers) {
+            l.add(linker);
+        }
+        this.linkers = l.toArray(new GuardingDynamicLinker[l.size()]);
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, final LinkerServices linkerServices)
+            throws Exception {
+        for(final GuardingDynamicLinker linker: linkers) {
+            final GuardedInvocation invocation = linker.getGuardedInvocation(linkRequest, linkerServices);
+            if(invocation != null) {
+                return invocation;
+            }
+        }
+        return null;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java b/nashorn/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java
new file mode 100644
index 0000000..180ab0c
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java
@@ -0,0 +1,225 @@
+/*
+ * 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.support;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+
+/**
+ * A composite type-based guarding dynamic linker. When a receiver of a not yet seen class is encountered, all linkers
+ * are queried sequentially on their {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} method. The linkers
+ * returning true are then bound to the class, and next time a receiver of same type is encountered, the linking is
+ * delegated to those linkers only, speeding up dispatch.
+ *
+ * @author Attila Szegedi
+ */
+public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardingDynamicLinker, Serializable {
+    private static final long serialVersionUID = 1L;
+
+    // Using a separate static class instance so there's no strong reference from the class value back to the composite
+    // linker.
+    private static class ClassToLinker extends ClassValue<List<TypeBasedGuardingDynamicLinker>> {
+        private static final List<TypeBasedGuardingDynamicLinker> NO_LINKER = Collections.emptyList();
+        private final TypeBasedGuardingDynamicLinker[] linkers;
+        private final List<TypeBasedGuardingDynamicLinker>[] singletonLinkers;
+
+        @SuppressWarnings("unchecked")
+        ClassToLinker(TypeBasedGuardingDynamicLinker[] linkers) {
+            this.linkers = linkers;
+            singletonLinkers = new List[linkers.length];
+            for(int i = 0; i < linkers.length; ++i) {
+                singletonLinkers[i] = Collections.singletonList(linkers[i]);
+            }
+        }
+
+        @Override
+        protected List<TypeBasedGuardingDynamicLinker> computeValue(Class<?> clazz) {
+            List<TypeBasedGuardingDynamicLinker> list = NO_LINKER;
+            for(int i = 0; i < linkers.length; ++i) {
+                final TypeBasedGuardingDynamicLinker linker = linkers[i];
+                if(linker.canLinkType(clazz)) {
+                    switch(list.size()) {
+                        case 0: {
+                            list = singletonLinkers[i];
+                            break;
+                        }
+                        case 1: {
+                            list = new LinkedList<>(list);
+                        }
+                        //$FALL-THROUGH$
+                        default: {
+                            list.add(linker);
+                        }
+                    }
+                }
+            }
+            return list;
+        }
+    }
+
+    private final ClassValue<List<TypeBasedGuardingDynamicLinker>> classToLinker;
+
+    /**
+     * Creates a new composite type-based linker.
+     *
+     * @param linkers the component linkers
+     */
+    public CompositeTypeBasedGuardingDynamicLinker(Iterable<? extends TypeBasedGuardingDynamicLinker> linkers) {
+        final List<TypeBasedGuardingDynamicLinker> l = new LinkedList<>();
+        for(TypeBasedGuardingDynamicLinker linker: linkers) {
+            l.add(linker);
+        }
+        this.classToLinker = new ClassToLinker(l.toArray(new TypeBasedGuardingDynamicLinker[l.size()]));
+    }
+
+    @Override
+    public boolean canLinkType(Class<?> type) {
+        return !classToLinker.get(type).isEmpty();
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, final LinkerServices linkerServices)
+            throws Exception {
+        final Object obj = linkRequest.getReceiver();
+        if(obj == null) {
+            return null;
+        }
+        for(TypeBasedGuardingDynamicLinker linker: classToLinker.get(obj.getClass())) {
+            final GuardedInvocation invocation = linker.getGuardedInvocation(linkRequest, linkerServices);
+            if(invocation != null) {
+                return invocation;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Optimizes a list of type-based linkers. If a group of adjacent linkers in the list all implement
+     * {@link TypeBasedGuardingDynamicLinker}, they will be replaced with a single instance of
+     * {@link CompositeTypeBasedGuardingDynamicLinker} that contains them.
+     *
+     * @param linkers the list of linkers to optimize
+     * @return the optimized list
+     */
+    public static List<GuardingDynamicLinker> optimize(Iterable<? extends GuardingDynamicLinker> linkers) {
+        final List<GuardingDynamicLinker> llinkers = new LinkedList<>();
+        final List<TypeBasedGuardingDynamicLinker> tblinkers = new LinkedList<>();
+        for(GuardingDynamicLinker linker: linkers) {
+            if(linker instanceof TypeBasedGuardingDynamicLinker) {
+                tblinkers.add((TypeBasedGuardingDynamicLinker)linker);
+            } else {
+                addTypeBased(llinkers, tblinkers);
+                llinkers.add(linker);
+            }
+        }
+        addTypeBased(llinkers, tblinkers);
+        return llinkers;
+    }
+
+    private static void addTypeBased(List<GuardingDynamicLinker> llinkers,
+            List<TypeBasedGuardingDynamicLinker> tblinkers) {
+        switch(tblinkers.size()) {
+            case 0: {
+                break;
+            }
+            case 1: {
+                llinkers.addAll(tblinkers);
+                tblinkers.clear();
+                break;
+            }
+            default: {
+                llinkers.add(new CompositeTypeBasedGuardingDynamicLinker(tblinkers));
+                tblinkers.clear();
+                break;
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/DefaultCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/DefaultCallSiteDescriptor.java
new file mode 100644
index 0000000..46d4fc8
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/DefaultCallSiteDescriptor.java
@@ -0,0 +1,134 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+
+/**
+ * A default, fairly light implementation of a call site descriptor used for describing non-standard operations. It does
+ * not store {@link Lookup} objects but always returns the public lookup from its {@link #getLookup()} method. If you
+ * need to support non-public lookup, you can use {@link LookupCallSiteDescriptor}.
+ * @author Attila Szegedi
+ */
+class DefaultCallSiteDescriptor extends AbstractCallSiteDescriptor {
+
+    private final String[] tokenizedName;
+    private final MethodType methodType;
+
+    DefaultCallSiteDescriptor(String[] tokenizedName, MethodType methodType) {
+        this.tokenizedName = tokenizedName;
+        this.methodType = methodType;
+    }
+
+    @Override
+    public int getNameTokenCount() {
+        return tokenizedName.length;
+    }
+
+    @Override
+    public String getNameToken(int i) {
+        try {
+            return tokenizedName[i];
+        } catch(ArrayIndexOutOfBoundsException e) {
+            throw new IllegalArgumentException(e.getMessage());
+        }
+    }
+
+    String[] getTokenizedName() {
+        return tokenizedName;
+    }
+
+    @Override
+    public MethodType getMethodType() {
+        return methodType;
+    }
+
+    @Override
+    public CallSiteDescriptor changeMethodType(MethodType newMethodType) {
+        return CallSiteDescriptorFactory.getCanonicalPublicDescriptor(new DefaultCallSiteDescriptor(tokenizedName,
+                newMethodType));
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/Guards.java b/nashorn/src/jdk/internal/dynalink/support/Guards.java
new file mode 100644
index 0000000..bab6e1d
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/Guards.java
@@ -0,0 +1,359 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import jdk.internal.dynalink.linker.LinkerServices;
+
+/**
+ * Utility methods for creating typical guards. TODO: introduce reasonable caching of created guards.
+ *
+ * @author Attila Szegedi
+ */
+public class Guards {
+    private static final Logger LOG = Logger
+            .getLogger(Guards.class.getName(), "jdk.internal.dynalink.support.messages");
+
+    private Guards() {
+    }
+
+    /**
+     * Creates a guard method handle with arguments of a specified type, but with boolean return value. When invoked, it
+     * returns true if the first argument is of the specified class (exactly of it, not a subclass). The rest of the
+     * arguments will be ignored.
+     *
+     * @param clazz the class of the first argument to test for
+     * @param type the method type
+     * @return a method handle testing whether its first argument is of the specified class.
+     */
+    @SuppressWarnings("boxing")
+    public static MethodHandle isOfClass(Class<?> clazz, MethodType type) {
+        final Class<?> declaredType = type.parameterType(0);
+        if(clazz == declaredType) {
+            LOG.log(Level.WARNING, "isOfClassGuardAlwaysTrue", new Object[] { clazz.getName(), 0, type });
+            return constantTrue(type);
+        }
+        if(!declaredType.isAssignableFrom(clazz)) {
+            LOG.log(Level.WARNING, "isOfClassGuardAlwaysFalse", new Object[] { clazz.getName(), 0, type });
+            return constantFalse(type);
+        }
+        return getClassBoundArgumentTest(IS_OF_CLASS, clazz, 0, type);
+    }
+
+    /**
+     * Creates a method handle with arguments of a specified type, but with boolean return value. When invoked, it
+     * returns true if the first argument is instance of the specified class or its subclass). The rest of the arguments
+     * will be ignored.
+     *
+     * @param clazz the class of the first argument to test for
+     * @param type the method type
+     * @return a method handle testing whether its first argument is of the specified class or subclass.
+     */
+    public static MethodHandle isInstance(Class<?> clazz, MethodType type) {
+        return isInstance(clazz, 0, type);
+    }
+
+    /**
+     * Creates a method handle with arguments of a specified type, but with boolean return value. When invoked, it
+     * returns true if the n'th argument is instance of the specified class or its subclass). The rest of the arguments
+     * will be ignored.
+     *
+     * @param clazz the class of the first argument to test for
+     * @param pos the position on the argument list to test
+     * @param type the method type
+     * @return a method handle testing whether its first argument is of the specified class or subclass.
+     */
+    @SuppressWarnings("boxing")
+    public static MethodHandle isInstance(Class<?> clazz, int pos, MethodType type) {
+        final Class<?> declaredType = type.parameterType(pos);
+        if(clazz.isAssignableFrom(declaredType)) {
+            LOG.log(Level.WARNING, "isInstanceGuardAlwaysTrue", new Object[] { clazz.getName(), pos, type });
+            return constantTrue(type);
+        }
+        if(!declaredType.isAssignableFrom(clazz)) {
+            LOG.log(Level.WARNING, "isInstanceGuardAlwaysFalse", new Object[] { clazz.getName(), pos, type });
+            return constantFalse(type);
+        }
+        return getClassBoundArgumentTest(IS_INSTANCE, clazz, pos, type);
+    }
+
+    /**
+     * Creates a method handle that returns true if the argument in the specified position is a Java array.
+     *
+     * @param pos the position in the argument lit
+     * @param type the method type of the handle
+     * @return a method handle that returns true if the argument in the specified position is a Java array; the rest of
+     * the arguments are ignored.
+     */
+    @SuppressWarnings("boxing")
+    public static MethodHandle isArray(int pos, MethodType type) {
+        final Class<?> declaredType = type.parameterType(pos);
+        if(declaredType.isArray()) {
+            LOG.log(Level.WARNING, "isArrayGuardAlwaysTrue", new Object[] { pos, type });
+            return constantTrue(type);
+        }
+        if(!declaredType.isAssignableFrom(Object[].class)) {
+            LOG.log(Level.WARNING, "isArrayGuardAlwaysFalse", new Object[] { pos, type });
+            return constantFalse(type);
+        }
+        return asType(IS_ARRAY, pos, type);
+    }
+
+    /**
+     * Return true if it is safe to strongly reference a class from the referred class loader from a class associated
+     * with the referring class loader without risking a class loader memory leak.
+     *
+     * @param referrerLoader the referrer class loader
+     * @param referredLoader the referred class loader
+     * @return true if it is safe to strongly reference the class
+     */
+    public static boolean canReferenceDirectly(ClassLoader referrerLoader, final ClassLoader referredLoader) {
+        if(referredLoader == null) {
+            // Can always refer directly to a system class
+            return true;
+        }
+        if(referrerLoader == null) {
+            // System classes can't refer directly to any non-system class
+            return false;
+        }
+        // Otherwise, can only refer directly to classes residing in same or
+        // parent class loader.
+
+        ClassLoader referrer = referrerLoader;
+        do {
+            if(referrer == referredLoader) {
+                return true;
+            }
+            referrer = referrer.getParent();
+        } while(referrer != null);
+        return false;
+    }
+
+    private static MethodHandle getClassBoundArgumentTest(MethodHandle test, Class<?> clazz, int pos, MethodType type) {
+        // Bind the class to the first argument of the test
+        return asType(test.bindTo(clazz), pos, type);
+    }
+
+    /**
+     * Takes a guard-test method handle, and adapts it to the requested type, returning a boolean. Only applies
+     * conversions as per {@link MethodHandle#asType(MethodType)}.
+     * @param test the test method handle
+     * @param type the type to adapt the method handle to
+     * @return the adapted method handle
+     */
+    public static MethodHandle asType(MethodHandle test, MethodType type) {
+        return test.asType(getTestType(test, type));
+    }
+
+    /**
+     * Takes a guard-test method handle, and adapts it to the requested type, returning a boolean. Applies the passed
+     * {@link LinkerServices} object's {@link LinkerServices#asType(MethodHandle, MethodType)}.
+     * @param linkerServices the linker services to use for type conversions
+     * @param test the test method handle
+     * @param type the type to adapt the method handle to
+     * @return the adapted method handle
+     */
+    public static MethodHandle asType(LinkerServices linkerServices, MethodHandle test, MethodType type) {
+        return linkerServices.asType(test, getTestType(test, type));
+    }
+
+    private static MethodType getTestType(MethodHandle test, MethodType type) {
+        return type.dropParameterTypes(test.type().parameterCount(),
+                type.parameterCount()).changeReturnType(boolean.class);
+    }
+
+    private static MethodHandle asType(MethodHandle test, int pos, MethodType type) {
+        assert test != null;
+        assert type != null;
+        assert type.parameterCount() > 0;
+        assert pos >= 0 && pos < type.parameterCount();
+        assert test.type().parameterCount() == 1;
+        assert test.type().returnType() == Boolean.TYPE;
+        return MethodHandles.permuteArguments(test.asType(test.type().changeParameterType(0, type.parameterType(pos))),
+                type.changeReturnType(Boolean.TYPE), new int[] { pos });
+    }
+
+    private static final MethodHandle IS_OF_CLASS = new Lookup(MethodHandles.lookup()).findStatic(Guards.class,
+            "isOfClass", MethodType.methodType(Boolean.TYPE, Class.class, Object.class));
+
+    private static final MethodHandle IS_INSTANCE = Lookup.PUBLIC.findVirtual(Class.class, "isInstance",
+            MethodType.methodType(Boolean.TYPE, Object.class));
+
+    private static final MethodHandle IS_ARRAY = new Lookup(MethodHandles.lookup()).findStatic(Guards.class, "isArray",
+            MethodType.methodType(Boolean.TYPE, Object.class));
+
+    private static final MethodHandle IS_IDENTICAL = new Lookup(MethodHandles.lookup()).findStatic(Guards.class,
+            "isIdentical", MethodType.methodType(Boolean.TYPE, Object.class, Object.class));
+
+    private static final MethodHandle IS_NULL = new Lookup(MethodHandles.lookup()).findStatic(Guards.class,
+            "isNull", MethodType.methodType(Boolean.TYPE, Object.class));
+
+    private static final MethodHandle IS_NOT_NULL = new Lookup(MethodHandles.lookup()).findStatic(Guards.class,
+            "isNotNull", MethodType.methodType(Boolean.TYPE, Object.class));
+
+    /**
+     * Creates a guard method that tests its only argument for being of an exact particular class.
+     * @param clazz the class to test for.
+     * @return the desired guard method.
+     */
+    public static MethodHandle getClassGuard(Class<?> clazz) {
+        return IS_OF_CLASS.bindTo(clazz);
+    }
+
+    /**
+     * Creates a guard method that tests its only argument for being an instance of a particular class.
+     * @param clazz the class to test for.
+     * @return the desired guard method.
+     */
+    public static MethodHandle getInstanceOfGuard(Class<?> clazz) {
+        return IS_INSTANCE.bindTo(clazz);
+    }
+
+    /**
+     * Creates a guard method that tests its only argument for being referentially identical to another object
+     * @param obj the object used as referential identity test
+     * @return the desired guard method.
+     */
+    public static MethodHandle getIdentityGuard(Object obj) {
+        return IS_IDENTICAL.bindTo(obj);
+    }
+
+    /**
+     * Returns a guard that tests whether the first argument is null.
+     * @return a guard that tests whether the first argument is null.
+     */
+    public static MethodHandle isNull() {
+        return IS_NULL;
+    }
+
+    /**
+     * Returns a guard that tests whether the first argument is not null.
+     * @return a guard that tests whether the first argument is not null.
+     */
+    public static MethodHandle isNotNull() {
+        return IS_NOT_NULL;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isNull(Object obj) {
+        return obj == null;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isNotNull(Object obj) {
+        return obj != null;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isArray(Object o) {
+        return o != null && o.getClass().isArray();
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isOfClass(Class<?> c, Object o) {
+        return o != null && o.getClass() == c;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isIdentical(Object o1, Object o2) {
+        return o1 == o2;
+    }
+
+    private static MethodHandle constantTrue(MethodType type) {
+        return constantBoolean(Boolean.TRUE, type);
+    }
+
+    private static MethodHandle constantFalse(MethodType type) {
+        return constantBoolean(Boolean.FALSE, type);
+    }
+
+    private static MethodHandle constantBoolean(Boolean value, MethodType type) {
+        return MethodHandles.permuteArguments(MethodHandles.constant(Boolean.TYPE, value),
+                type.changeReturnType(Boolean.TYPE));
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/LinkRequestImpl.java b/nashorn/src/jdk/internal/dynalink/support/LinkRequestImpl.java
new file mode 100644
index 0000000..c2b0092
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/LinkRequestImpl.java
@@ -0,0 +1,143 @@
+/*
+ * 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.support;
+
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.LinkRequest;
+
+/**
+ * Default implementation of the {@link LinkRequest}, representing a link request to a call site that passes no language
+ * runtime specific native context arguments on the stack.
+ *
+ * @author Attila Szegedi
+ */
+public class LinkRequestImpl implements LinkRequest {
+
+    private final CallSiteDescriptor callSiteDescriptor;
+    private final Object[] arguments;
+    private final boolean callSiteUnstable;
+
+    /**
+     * Creates a new link request.
+     *
+     * @param callSiteDescriptor the descriptor for the call site being linked
+     * @param callSiteUnstable true if the call site being linked is considered unstable
+     * @param arguments the arguments for the invocation
+     */
+    public LinkRequestImpl(CallSiteDescriptor callSiteDescriptor, boolean callSiteUnstable, Object... arguments) {
+        this.callSiteDescriptor = callSiteDescriptor;
+        this.callSiteUnstable = callSiteUnstable;
+        this.arguments = arguments;
+    }
+
+    @Override
+    public Object[] getArguments() {
+        return arguments != null ? arguments.clone() : null;
+    }
+
+    @Override
+    public Object getReceiver() {
+        return arguments != null && arguments.length > 0 ? arguments[0] : null;
+    }
+
+    @Override
+    public CallSiteDescriptor getCallSiteDescriptor() {
+        return callSiteDescriptor;
+    }
+
+    @Override
+    public boolean isCallSiteUnstable() {
+        return callSiteUnstable;
+    }
+
+    @Override
+    public LinkRequest withoutRuntimeContext() {
+        return this;
+    }
+
+    @Override
+    public LinkRequest replaceArguments(CallSiteDescriptor newCallSiteDescriptor, Object[] newArguments) {
+        return new LinkRequestImpl(newCallSiteDescriptor, callSiteUnstable, newArguments);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/LinkerServicesImpl.java b/nashorn/src/jdk/internal/dynalink/support/LinkerServicesImpl.java
new file mode 100644
index 0000000..4eb0ca9
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/LinkerServicesImpl.java
@@ -0,0 +1,140 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+
+/**
+ * Default implementation of the {@link LinkerServices} interface.
+ *
+ * @author Attila Szegedi
+ */
+public class LinkerServicesImpl implements LinkerServices {
+
+    private final TypeConverterFactory typeConverterFactory;
+    private final GuardingDynamicLinker topLevelLinker;
+
+    /**
+     * Creates a new linker services object.
+     *
+     * @param typeConverterFactory the type converter factory exposed by the services.
+     * @param topLevelLinker the top level linker used by the services.
+     */
+    public LinkerServicesImpl(final TypeConverterFactory typeConverterFactory,
+            final GuardingDynamicLinker topLevelLinker) {
+        this.typeConverterFactory = typeConverterFactory;
+        this.topLevelLinker = topLevelLinker;
+    }
+
+    @Override
+    public boolean canConvert(Class<?> from, Class<?> to) {
+        return typeConverterFactory.canConvert(from, to);
+    }
+
+    @Override
+    public MethodHandle asType(MethodHandle handle, MethodType fromType) {
+        return typeConverterFactory.asType(handle, fromType);
+    }
+
+    @Override
+    public MethodHandle getTypeConverter(Class<?> sourceType, Class<?> targetType) {
+        return typeConverterFactory.getTypeConverter(sourceType, targetType);
+    }
+
+    @Override
+    public Comparison compareConversion(Class<?> sourceType, Class<?> targetType1, Class<?> targetType2) {
+        return typeConverterFactory.compareConversion(sourceType, targetType1, targetType2);
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest) throws Exception {
+        return topLevelLinker.getGuardedInvocation(linkRequest, this);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/Lookup.java b/nashorn/src/jdk/internal/dynalink/support/Lookup.java
new file mode 100644
index 0000000..52a6102
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/Lookup.java
@@ -0,0 +1,360 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * A wrapper around MethodHandles.Lookup that masks checked exceptions in those cases when you're looking up methods
+ * within your own codebase (therefore it is an error if they are not present).
+ *
+ * @author Attila Szegedi
+ */
+public class Lookup {
+    private final MethodHandles.Lookup lookup;
+
+    /**
+     * Creates a new instance, bound to an instance of {@link java.lang.invoke.MethodHandles.Lookup}.
+     *
+     * @param lookup the {@link java.lang.invoke.MethodHandles.Lookup} it delegates to.
+     */
+    public Lookup(MethodHandles.Lookup lookup) {
+        this.lookup = lookup;
+    }
+
+    /**
+     * A canonical Lookup object that wraps {@link MethodHandles#publicLookup()}.
+     */
+    public static final Lookup PUBLIC = new Lookup(MethodHandles.publicLookup());
+
+    /**
+     * 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.
+     */
+    public MethodHandle unreflect(Method m) {
+        try {
+            return lookup.unreflect(m);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect method " + m);
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+
+    /**
+     * 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.
+     */
+    public MethodHandle unreflectGetter(Field f) {
+        try {
+            return lookup.unreflectGetter(f);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect getter for field " + f);
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    /**
+     * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}, converting any
+     * encountered {@link IllegalAccessException} into an {@link IllegalAccessError} and {@link NoSuchFieldException}
+     * into a {@link NoSuchFieldError}.
+     *
+     * @param refc the class declaring the field
+     * @param name the name of the field
+     * @param type the type of the field
+     * @return the unreflected field getter handle.
+     * @throws IllegalAccessError if the field is inaccessible.
+     * @throws NoSuchFieldError if the field does not exist.
+     */
+    public MethodHandle findGetter(Class<?>refc, String name, Class<?> type) {
+        try {
+            return lookup.findGetter(refc, name, type);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to access getter for field " + refc.getName() +
+                    "." + name + " of type " + type.getName());
+            ee.initCause(e);
+            throw ee;
+        } catch(NoSuchFieldException e) {
+            final NoSuchFieldError ee = new NoSuchFieldError("Failed to find getter for field " + refc.getName() +
+                    "." + name + " of type " + type.getName());
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    /**
+     * 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.
+     */
+    public MethodHandle unreflectSetter(Field f) {
+        try {
+            return lookup.unreflectSetter(f);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect setter for field " + f);
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    /**
+     * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, 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) {
+        try {
+            return lookup.unreflectConstructor(c);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect constructor " + c);
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    /**
+     * Performs a findSpecial on the underlying lookup, except for the backport where it rather uses unreflect. Converts
+     * any encountered {@link IllegalAccessException} into an {@link IllegalAccessError} and a
+     * {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
+     *
+     * @param declaringClass class declaring the method
+     * @param name the name of the method
+     * @param type the type of the method
+     * @return a method handle for the method
+     * @throws IllegalAccessError if the method is inaccessible.
+     * @throws NoSuchMethodError if the method does not exist.
+     */
+    public MethodHandle findSpecial(Class<?> declaringClass, String name, MethodType type) {
+        try {
+            if(Backport.inUse) {
+                final Method m = declaringClass.getDeclaredMethod(name, type.parameterArray());
+                if(!Modifier.isPublic(declaringClass.getModifiers()) || !Modifier.isPublic(m.getModifiers())) {
+                    m.setAccessible(true);
+                }
+                return unreflect(m);
+            }
+            return lookup.findSpecial(declaringClass, name, type, declaringClass);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to access special method " + methodDescription(
+                    declaringClass, name, type));
+            ee.initCause(e);
+            throw ee;
+        } catch(NoSuchMethodException e) {
+            final NoSuchMethodError ee = new NoSuchMethodError("Failed to find special method " + methodDescription(
+                    declaringClass, name, type));
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    private static String methodDescription(Class<?> declaringClass, String name, MethodType type) {
+        return declaringClass.getName() + "#" + name + type;
+    }
+
+    /**
+     * Performs a findStatic on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an
+     * {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
+     *
+     * @param declaringClass class declaring the method
+     * @param name the name of the method
+     * @param type the type of the method
+     * @return a method handle for the method
+     * @throws IllegalAccessError if the method is inaccessible.
+     * @throws NoSuchMethodError if the method does not exist.
+     */
+    public MethodHandle findStatic(Class<?> declaringClass, String name, MethodType type) {
+        try {
+            return lookup.findStatic(declaringClass, name, type);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to access static method " + methodDescription(
+                    declaringClass, name, type));
+            ee.initCause(e);
+            throw ee;
+        } catch(NoSuchMethodException e) {
+            final NoSuchMethodError ee = new NoSuchMethodError("Failed to find static method " + methodDescription(
+                    declaringClass, name, type));
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    /**
+     * Performs a findVirtual on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an
+     * {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
+     *
+     * @param declaringClass class declaring the method
+     * @param name the name of the method
+     * @param type the type of the method
+     * @return a method handle for the method
+     * @throws IllegalAccessError if the method is inaccessible.
+     * @throws NoSuchMethodError if the method does not exist.
+     */
+    public MethodHandle findVirtual(Class<?> declaringClass, String name, MethodType type) {
+        try {
+            return lookup.findVirtual(declaringClass, name, type);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to access virtual method " + methodDescription(
+                    declaringClass, name, type));
+            ee.initCause(e);
+            throw ee;
+        } catch(NoSuchMethodException e) {
+            final NoSuchMethodError ee = new NoSuchMethodError("Failed to find virtual method " + methodDescription(
+                    declaringClass, name, type));
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    /**
+     * Given a lookup, finds using {@link #findSpecial(Class, String, MethodType)} a method on that lookup's class.
+     * Useful in classes' code for convenient linking to their own privates.
+     * @param lookup the lookup for the class
+     * @param name the name of the method
+     * @param rtype the return type of the method
+     * @param ptypes the parameter types of the method
+     * @return the method handle for the method
+     */
+    public static MethodHandle findOwnSpecial(MethodHandles.Lookup lookup, String name, Class<?> rtype, Class<?>... ptypes) {
+        return new Lookup(lookup).findOwnSpecial(name, rtype, ptypes);
+    }
+
+
+    /**
+     * Finds using {@link #findSpecial(Class, String, MethodType)} a method on that lookup's class. Useful in classes'
+     * code for convenient linking to their own privates. It's easier to use than {@code findSpecial} in that you can
+     * just list the parameter types, and don't have to specify lookup class.
+     * @param name the name of the method
+     * @param rtype the return type of the method
+     * @param ptypes the parameter types of the method
+     * @return the method handle for the method
+     */
+    public MethodHandle findOwnSpecial(String name, Class<?> rtype, Class<?>... ptypes) {
+        return findSpecial(lookup.lookupClass(), name, MethodType.methodType(rtype, ptypes));
+    }
+
+    /**
+     * Given a lookup, finds using {@link #findStatic(Class, String, MethodType)} a method on that lookup's class.
+     * Useful in classes' code for convenient linking to their own privates. It's easier to use than {@code findStatic}
+     * in that you can just list the parameter types, and don't have to specify lookup class.
+     * @param lookup the lookup for the class
+     * @param name the name of the method
+     * @param rtype the return type of the method
+     * @param ptypes the parameter types of the method
+     * @return the method handle for the method
+     */
+    public static MethodHandle findOwnStatic(MethodHandles.Lookup lookup, String name, Class<?> rtype, Class<?>... ptypes) {
+        return new Lookup(lookup).findOwnStatic(name, rtype, ptypes);
+    }
+
+    /**
+     * Finds using {@link #findStatic(Class, String, MethodType)} a method on that lookup's class. Useful in classes'
+     * code for convenient linking to their own privates. It's easier to use than {@code findStatic} in that you can
+     * just list the parameter types, and don't have to specify lookup class.
+     * @param name the name of the method
+     * @param rtype the return type of the method
+     * @param ptypes the parameter types of the method
+     * @return the method handle for the method
+     */
+    public MethodHandle findOwnStatic(String name, Class<?> rtype, Class<?>... ptypes) {
+        return findStatic(lookup.lookupClass(), name, MethodType.methodType(rtype, ptypes));
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/LookupCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/LookupCallSiteDescriptor.java
new file mode 100644
index 0000000..bc5521b
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/LookupCallSiteDescriptor.java
@@ -0,0 +1,117 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+
+/**
+ * A call site descriptor that stores a specific {@link Lookup}. It does not, however, store static bootstrap arguments.
+ * @author Attila Szegedi
+ */
+class LookupCallSiteDescriptor extends DefaultCallSiteDescriptor {
+    private Lookup lookup;
+
+    /**
+     * Create a new call site descriptor from explicit information.
+     * @param tokenizedName the name of the method
+     * @param methodType the method type
+     * @param lookup the lookup
+     */
+    LookupCallSiteDescriptor(String[] tokenizedName, MethodType methodType, Lookup lookup) {
+        super(tokenizedName, methodType);
+        this.lookup = lookup;
+    }
+
+    @Override
+    public Lookup getLookup() {
+        return lookup;
+    }
+
+    @Override
+    public CallSiteDescriptor changeMethodType(MethodType newMethodType) {
+        return new LookupCallSiteDescriptor(getTokenizedName(), newMethodType, lookup);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/NameCodec.java b/nashorn/src/jdk/internal/dynalink/support/NameCodec.java
new file mode 100644
index 0000000..1c7cd29
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/NameCodec.java
@@ -0,0 +1,218 @@
+/*
+ * 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.support;
+
+import jdk.internal.dynalink.CallSiteDescriptor;
+
+/**
+ * Implements the name mangling and demangling as specified by John Rose's
+ * <a href="https://blogs.oracle.com/jrose/entry/symbolic_freedom_in_the_vm" target="_blank">"Symbolic Freedom in the
+ * VM"</a> article. It is recommended that implementers of languages on the JVM uniformly adopt this for symbolic
+ * interoperability between languages. Normally, you would mangle the names as you're generating bytecode, and then
+ * demangle them when you're creating {@link CallSiteDescriptor} objects. Note that you are expected to mangle
+ * individual tokens, and not the whole name at the call site, i.e. the colon character normally separating the tokens
+ * is never mangled. I.e. you wouldn't mangle {@code dyn:getProp:color} into {@code dyn\!getProp\!color}, but you would
+ * mangle {@code dyn:getProp:color$} into {@code dyn:getProp:\=color\%} (only mangling the individual token containing
+ * the symbol {@code color$}). {@link CallSiteDescriptorFactory#tokenizeName(String)} (and by implication, all call site
+ * descriptors it creates) will automatically perform demangling on the passed names. If you use this factory, or you
+ * have your own way of creating call site descriptors, but you still delegate to this method of the default factory
+ * (it is recommended that you do), then you have demangling handled for you already, and only need to ensure that you
+ * mangle the names when you're emitting them in the bytecode.
+ *
+ * @author Attila Szegedi
+ */
+public class NameCodec {
+    private static final char ESCAPE_CHAR = '\\';
+    private static final char EMPTY_ESCAPE = '=';
+    private static final String EMPTY_NAME = new String(new char[] { ESCAPE_CHAR, EMPTY_ESCAPE });
+    private static final char EMPTY_CHAR = 0xFEFF;
+
+    private static final int MIN_ENCODING = '$';
+    private static final int MAX_ENCODING = ']';
+    private static final char[] ENCODING = new char[MAX_ENCODING - MIN_ENCODING + 1];
+    private static final int MIN_DECODING = '!';
+    private static final int MAX_DECODING = '}';
+    private static final char[] DECODING = new char[MAX_DECODING - MIN_DECODING + 1];
+
+    static {
+        addEncoding('/', '|');
+        addEncoding('.', ',');
+        addEncoding(';', '?');
+        addEncoding('$', '%');
+        addEncoding('<', '^');
+        addEncoding('>', '_');
+        addEncoding('[', '{');
+        addEncoding(']', '}');
+        addEncoding(':', '!');
+        addEncoding('\\', '-');
+        DECODING[EMPTY_ESCAPE - MIN_DECODING] = EMPTY_CHAR;
+    }
+
+    private NameCodec() {
+    }
+
+    /**
+     * Encodes ("mangles") an unencoded symbolic name.
+     * @param name the symbolic name to mangle
+     * @return the mangled form of the symbolic name.
+     */
+    public static String encode(String name) {
+        final int l = name.length();
+        if(l == 0) {
+            return EMPTY_NAME;
+        }
+        StringBuilder b = null;
+        int lastEscape = -1;
+        for(int i = 0; i < l; ++i) {
+            final int encodeIndex = name.charAt(i) - MIN_ENCODING;
+            if(encodeIndex >= 0 && encodeIndex < ENCODING.length) {
+                final char e = ENCODING[encodeIndex];
+                if(e != 0) {
+                    if(b == null) {
+                        b = new StringBuilder(name.length() + 3);
+                        if(name.charAt(0) != ESCAPE_CHAR && i > 0) {
+                            b.append(EMPTY_NAME);
+                        }
+                        b.append(name, 0, i);
+                    } else {
+                        b.append(name, lastEscape + 1, i);
+                    }
+                    b.append(ESCAPE_CHAR).append(e);
+                    lastEscape = i;
+                }
+            }
+        }
+        if(b == null) {
+            return name.toString();
+        }
+        assert lastEscape != -1;
+        b.append(name, lastEscape + 1, l);
+        return b.toString();
+    }
+
+    /**
+     * Decodes ("demangles") an encoded symbolic name.
+     * @param name the symbolic name to demangle
+     * @return the demangled form of the symbolic name.
+     */
+    public static String decode(String name) {
+        if(name.charAt(0) != ESCAPE_CHAR) {
+            return name;
+        }
+        final int l = name.length();
+        if(l == 2 && name.charAt(1) == EMPTY_CHAR) {
+            return "";
+        }
+        StringBuilder b = new StringBuilder(name.length());
+        int lastEscape = -2;
+        int lastBackslash = -1;
+        for(;;) {
+            int nextBackslash = name.indexOf(ESCAPE_CHAR, lastBackslash + 1);
+            if(nextBackslash == -1 || nextBackslash == l - 1) {
+                break;
+            }
+            final int decodeIndex = name.charAt(nextBackslash + 1) - MIN_DECODING;
+            if(decodeIndex >= 0 && decodeIndex < DECODING.length) {
+                final char d = DECODING[decodeIndex];
+                if(d == EMPTY_CHAR) {
+                    // "\=" is only valid at the beginning of a mangled string
+                    if(nextBackslash == 0) {
+                        lastEscape = 0;
+                    }
+                } else if(d != 0) {
+                    b.append(name, lastEscape + 2, nextBackslash).append(d);
+                    lastEscape = nextBackslash;
+                }
+            }
+            lastBackslash = nextBackslash;
+        }
+        b.append(name, lastEscape + 2, l);
+        return b.toString();
+    }
+
+    private static void addEncoding(char from, char to) {
+        ENCODING[from - MIN_ENCODING] = to;
+        DECODING[to - MIN_DECODING] = from;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/NamedDynCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/NamedDynCallSiteDescriptor.java
new file mode 100644
index 0000000..71cbb1d
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/NamedDynCallSiteDescriptor.java
@@ -0,0 +1,117 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+
+class NamedDynCallSiteDescriptor extends UnnamedDynCallSiteDescriptor {
+    private final String name;
+
+    NamedDynCallSiteDescriptor(String op, String name, MethodType methodType) {
+        super(op, methodType);
+        this.name = name;
+    }
+
+    @Override
+    public int getNameTokenCount() {
+        return 3;
+    }
+
+    @Override
+    public String getNameToken(int i) {
+        switch(i) {
+            case 0: return "dyn";
+            case 1: return getOp();
+            case 2: return name;
+            default: throw new IndexOutOfBoundsException(String.valueOf(i));
+        }
+    }
+
+    @Override
+    public CallSiteDescriptor changeMethodType(MethodType newMethodType) {
+        return CallSiteDescriptorFactory.getCanonicalPublicDescriptor(new NamedDynCallSiteDescriptor(getOp(), name,
+                newMethodType));
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/RuntimeContextLinkRequestImpl.java b/nashorn/src/jdk/internal/dynalink/support/RuntimeContextLinkRequestImpl.java
new file mode 100644
index 0000000..03309a7
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/RuntimeContextLinkRequestImpl.java
@@ -0,0 +1,142 @@
+/*
+ * 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.support;
+
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.LinkRequest;
+
+/**
+ * A link request implementation for call sites that pass language runtime specific context arguments on the stack. The
+ * context specific arguments should be the first "n" arguments.
+ *
+ * @author Attila Szegedi
+ */
+public class RuntimeContextLinkRequestImpl extends LinkRequestImpl {
+
+    private final int runtimeContextArgCount;
+    private LinkRequestImpl contextStrippedRequest;
+
+    /**
+     * Creates a new link request.
+     *
+     * @param callSiteDescriptor the descriptor for the call site being linked
+     * @param arguments the arguments for the invocation
+     * @param callSiteUnstable true if the call site being linked is considered unstable
+     * @param runtimeContextArgCount the number of the leading arguments on the stack that represent the language
+     * runtime specific context arguments.
+     * @throws IllegalArgumentException if runtimeContextArgCount is less than 1.
+     */
+    public RuntimeContextLinkRequestImpl(CallSiteDescriptor callSiteDescriptor, boolean callSiteUnstable,
+            Object[] arguments, int runtimeContextArgCount) {
+        super(callSiteDescriptor, callSiteUnstable, arguments);
+        if(runtimeContextArgCount < 1) {
+            throw new IllegalArgumentException("runtimeContextArgCount < 1");
+        }
+        this.runtimeContextArgCount = runtimeContextArgCount;
+    }
+
+    @Override
+    public LinkRequest withoutRuntimeContext() {
+        if(contextStrippedRequest == null) {
+            contextStrippedRequest =
+                    new LinkRequestImpl(CallSiteDescriptorFactory.dropParameterTypes(getCallSiteDescriptor(), 1,
+                            runtimeContextArgCount + 1), isCallSiteUnstable(), getTruncatedArguments());
+        }
+        return contextStrippedRequest;
+    }
+
+    @Override
+    public LinkRequest replaceArguments(CallSiteDescriptor callSiteDescriptor, Object[] arguments) {
+        return new RuntimeContextLinkRequestImpl(callSiteDescriptor, isCallSiteUnstable(), arguments,
+                runtimeContextArgCount);
+    }
+
+    private Object[] getTruncatedArguments() {
+        final Object[] args = getArguments();
+        final Object[] newargs = new Object[args.length - runtimeContextArgCount];
+        newargs[0] = args[0]; // "this" remains at the 0th position
+        System.arraycopy(args, runtimeContextArgCount + 1, newargs, 1, newargs.length - 1);
+        return newargs;
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java b/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java
new file mode 100644
index 0000000..71fb4eb
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java
@@ -0,0 +1,319 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.WrongMethodTypeException;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.internal.dynalink.linker.ConversionComparator;
+import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
+import jdk.internal.dynalink.linker.LinkerServices;
+
+/**
+ * A factory for type converters. This class is the main implementation behind the
+ * {@link LinkerServices#asType(MethodHandle, MethodType)}. It manages the known {@link GuardingTypeConverterFactory}
+ * instances and creates appropriate converters for method handles.
+ *
+ * @author Attila Szegedi
+ */
+public class TypeConverterFactory {
+
+    private final GuardingTypeConverterFactory[] factories;
+    private final ConversionComparator[] comparators;
+
+    private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<ClassMap<MethodHandle>>() {
+        @Override
+        protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
+            return new ClassMap<MethodHandle>(sourceType.getClassLoader()) {
+                @Override
+                protected MethodHandle computeValue(Class<?> targetType) {
+                    try {
+                        return createConverter(sourceType, targetType);
+                    } catch (RuntimeException e) {
+                        throw e;
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            };
+        }
+    };
+
+    private final ClassValue<ClassMap<MethodHandle>> converterIdentityMap = new ClassValue<ClassMap<MethodHandle>>() {
+        @Override
+        protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
+            return new ClassMap<MethodHandle>(sourceType.getClassLoader()) {
+                @Override
+                protected MethodHandle computeValue(Class<?> targetType) {
+                    if(!canAutoConvert(sourceType, targetType)) {
+                        final MethodHandle converter = getTypeConverterNull(sourceType, targetType);
+                        if(converter != null) {
+                            return converter;
+                        }
+                    }
+                    return IDENTITY_CONVERSION.asType(MethodType.methodType(targetType, sourceType));
+                }
+            };
+        }
+    };
+
+    /**
+     * Creates a new type converter factory from the available {@link GuardingTypeConverterFactory} instances.
+     *
+     * @param factories the {@link GuardingTypeConverterFactory} instances to compose.
+     */
+    public TypeConverterFactory(Iterable<? extends GuardingTypeConverterFactory> factories) {
+        final List<GuardingTypeConverterFactory> l = new LinkedList<>();
+        final List<ConversionComparator> c = new LinkedList<>();
+        for(GuardingTypeConverterFactory factory: factories) {
+            l.add(factory);
+            if(factory instanceof ConversionComparator) {
+                c.add((ConversionComparator)factory);
+            }
+        }
+        this.factories = l.toArray(new GuardingTypeConverterFactory[l.size()]);
+        this.comparators = c.toArray(new ConversionComparator[c.size()]);
+
+    }
+
+    /**
+     * Similar to {@link MethodHandle#asType(MethodType)} except it also hooks in method handles produced by
+     * {@link GuardingTypeConverterFactory} implementations, providing for language-specific type coercing of
+     * parameters. It will apply {@link MethodHandle#asType(MethodType)} for all primitive-to-primitive,
+     * wrapper-to-primitive, primitive-to-wrapper conversions as well as for all upcasts. For all other conversions,
+     * it'll insert {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with composite filters
+     * provided by {@link GuardingTypeConverterFactory} implementations.
+     *
+     * @param handle target method handle
+     * @param fromType the types of source arguments
+     * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)} and
+     * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with
+     * {@link GuardingTypeConverterFactory} produced type converters as filters.
+     */
+    public MethodHandle asType(MethodHandle handle, final MethodType fromType) {
+        MethodHandle newHandle = handle;
+        final MethodType toType = newHandle.type();
+        final int l = toType.parameterCount();
+        if(l != fromType.parameterCount()) {
+            throw new WrongMethodTypeException("Parameter counts differ: " + handle.type() + " vs. " + fromType);
+        }
+        int pos = 0;
+        final List<MethodHandle> converters = new LinkedList<>();
+        for(int i = 0; i < l; ++i) {
+            final Class<?> fromParamType = fromType.parameterType(i);
+            final Class<?> toParamType = toType.parameterType(i);
+            if(canAutoConvert(fromParamType, toParamType)) {
+                newHandle = applyConverters(newHandle, pos, converters);
+            } else {
+                final MethodHandle converter = getTypeConverterNull(fromParamType, toParamType);
+                if(converter != null) {
+                    if(converters.isEmpty()) {
+                        pos = i;
+                    }
+                    converters.add(converter);
+                } else {
+                    newHandle = applyConverters(newHandle, pos, converters);
+                }
+            }
+        }
+        newHandle = applyConverters(newHandle, pos, converters);
+
+        // Convert return type
+        final Class<?> fromRetType = fromType.returnType();
+        final Class<?> toRetType = toType.returnType();
+        if(fromRetType != Void.TYPE && toRetType != Void.TYPE) {
+            if(!canAutoConvert(toRetType, fromRetType)) {
+                final MethodHandle converter = getTypeConverterNull(toRetType, fromRetType);
+                if(converter != null) {
+                    newHandle = MethodHandles.filterReturnValue(newHandle, converter);
+                }
+            }
+        }
+
+        // Take care of automatic conversions
+        return newHandle.asType(fromType);
+    }
+
+    private static MethodHandle applyConverters(MethodHandle handle, int pos, List<MethodHandle> converters) {
+        if(converters.isEmpty()) {
+            return handle;
+        }
+        final MethodHandle newHandle =
+                MethodHandles.filterArguments(handle, pos, converters.toArray(new MethodHandle[converters.size()]));
+        converters.clear();
+        return newHandle;
+    }
+
+    /**
+     * Returns true if there might exist a conversion between the requested types (either an automatic JVM conversion,
+     * or one provided by any available {@link GuardingTypeConverterFactory}), or false if there definitely does not
+     * exist a conversion between the requested types. Note that returning true does not guarantee that the conversion
+     * will succeed at runtime (notably, if the "from" or "to" types are sufficiently generic), but returning false
+     * guarantees that it would fail.
+     *
+     * @param from the source type for the conversion
+     * @param to the target type for the conversion
+     * @return true if there can be a conversion, false if there can not.
+     */
+    public boolean canConvert(final Class<?> from, final Class<?> to) {
+        return canAutoConvert(from, to) || getTypeConverterNull(from, to) != null;
+    }
+
+    /**
+     * Determines which of the two type conversions from a source type to the two target types is preferred. This is
+     * used for dynamic overloaded method resolution. If the source type is convertible to exactly one target type with
+     * a method invocation conversion, it is chosen, otherwise available {@link ConversionComparator}s are consulted.
+     * @param sourceType the source type.
+     * @param targetType1 one potential target type
+     * @param targetType2 another potential target type.
+     * @return one of Comparison constants that establish which - if any - of the target types is preferable for the
+     * conversion.
+     */
+    public Comparison compareConversion(Class<?> sourceType, Class<?> targetType1, Class<?> targetType2) {
+        for(ConversionComparator comparator: comparators) {
+            final Comparison result = comparator.compareConversion(sourceType, targetType1, targetType2);
+            if(result != Comparison.INDETERMINATE) {
+                return result;
+            }
+        }
+        if(TypeUtilities.isMethodInvocationConvertible(sourceType, targetType1)) {
+            if(!TypeUtilities.isMethodInvocationConvertible(sourceType, targetType2)) {
+                return Comparison.TYPE_1_BETTER;
+            }
+        } else if(TypeUtilities.isMethodInvocationConvertible(sourceType, targetType2)) {
+            return Comparison.TYPE_2_BETTER;
+        }
+        return Comparison.INDETERMINATE;
+    }
+
+    /**
+     * Determines whether it's safe to perform an automatic conversion between the source and target class.
+     *
+     * @param fromType convert from this class
+     * @param toType convert to this class
+     * @return true if it's safe to let MethodHandles.convertArguments() to handle this conversion.
+     */
+    /*private*/ static boolean canAutoConvert(final Class<?> fromType, final Class<?> toType) {
+        return TypeUtilities.isMethodInvocationConvertible(fromType, toType);
+    }
+
+    /*private*/ MethodHandle getTypeConverterNull(Class<?> sourceType, Class<?> targetType) {
+        final MethodHandle converter = converterMap.get(sourceType).get(targetType);
+        return converter == IDENTITY_CONVERSION ? null : converter;
+    }
+
+    /**
+     * Given a source and target type, returns a method handle that converts between them. Never returns null; in worst
+     * case it will return an identity conversion (that might fail for some values at runtime). You can use this method
+     * if you have a piece of your program that is written in Java, and you need to reuse existing type conversion
+     * machinery in a non-invokedynamic context.
+     * @param sourceType the type to convert from
+     * @param targetType the type to convert to
+     * @return a method handle performing the conversion.
+     */
+    public MethodHandle getTypeConverter(Class<?> sourceType, Class<?> targetType) {
+        return converterIdentityMap.get(sourceType).get(targetType);
+    }
+
+    /*private*/ MethodHandle createConverter(Class<?> sourceType, Class<?> targetType) throws Exception {
+        final MethodType type = MethodType.methodType(targetType, sourceType);
+        final MethodHandle identity = IDENTITY_CONVERSION.asType(type);
+        MethodHandle last = identity;
+        for(int i = factories.length; i-- > 0;) {
+            final GuardedInvocation next = factories[i].convertToType(sourceType, targetType);
+            if(next != null) {
+                next.assertType(type);
+                last = next.compose(last);
+            }
+        }
+        return last == identity ? IDENTITY_CONVERSION : last;
+    }
+
+    /*private*/ static final MethodHandle IDENTITY_CONVERSION = MethodHandles.identity(Object.class);
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/TypeUtilities.java b/nashorn/src/jdk/internal/dynalink/support/TypeUtilities.java
new file mode 100644
index 0000000..57fea99
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/TypeUtilities.java
@@ -0,0 +1,442 @@
+/*
+ * 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.support;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Various static utility methods for testing type relationships.
+ *
+ * @author Attila Szegedi
+ */
+public class TypeUtilities {
+    static final Class<Object> OBJECT_CLASS = Object.class;
+
+    private TypeUtilities() {
+    }
+
+    /**
+     * Given two types represented by c1 and c2, returns a type that is their most specific common superclass or
+     * superinterface.
+     *
+     * @param c1 one type
+     * @param c2 another type
+     * @return their most common superclass or superinterface. If they have several unrelated superinterfaces as their
+     * most specific common type, or the types themselves are completely unrelated interfaces, {@link java.lang.Object}
+     * is returned.
+     */
+    public static Class<?> getMostSpecificCommonType(Class<?> c1, Class<?> c2) {
+        if(c1 == c2) {
+            return c1;
+        }
+        Class<?> c3 = c2;
+        if(c3.isPrimitive()) {
+            if(c3 == Byte.TYPE)
+                c3 = Byte.class;
+            else if(c3 == Short.TYPE)
+                c3 = Short.class;
+            else if(c3 == Character.TYPE)
+                c3 = Character.class;
+            else if(c3 == Integer.TYPE)
+                c3 = Integer.class;
+            else if(c3 == Float.TYPE)
+                c3 = Float.class;
+            else if(c3 == Long.TYPE)
+                c3 = Long.class;
+            else if(c3 == Double.TYPE)
+                c3 = Double.class;
+        }
+        Set<Class<?>> a1 = getAssignables(c1, c3);
+        Set<Class<?>> a2 = getAssignables(c3, c1);
+        a1.retainAll(a2);
+        if(a1.isEmpty()) {
+            // Can happen when at least one of the arguments is an interface,
+            // as they don't have Object at the root of their hierarchy.
+            return Object.class;
+        }
+        // Gather maximally specific elements. Yes, there can be more than one
+        // thank to interfaces. I.e., if you call this method for String.class
+        // and Number.class, you'll have Comparable, Serializable, and Object
+        // as maximal elements.
+        List<Class<?>> max = new ArrayList<>();
+        outer: for(Class<?> clazz: a1) {
+            for(Iterator<Class<?>> maxiter = max.iterator(); maxiter.hasNext();) {
+                Class<?> maxClazz = maxiter.next();
+                if(isSubtype(maxClazz, clazz)) {
+                    // It can't be maximal, if there's already a more specific
+                    // maximal than it.
+                    continue outer;
+                }
+                if(isSubtype(clazz, maxClazz)) {
+                    // If it's more specific than a currently maximal element,
+                    // that currently maximal is no longer a maximal.
+                    maxiter.remove();
+                }
+            }
+            // If we get here, no current maximal is more specific than the
+            // current class, so it is considered maximal as well
+            max.add(clazz);
+        }
+        if(max.size() > 1) {
+            return OBJECT_CLASS;
+        }
+        return max.get(0);
+    }
+
+    private static Set<Class<?>> getAssignables(Class<?> c1, Class<?> c2) {
+        Set<Class<?>> s = new HashSet<>();
+        collectAssignables(c1, c2, s);
+        return s;
+    }
+
+    private static void collectAssignables(Class<?> c1, Class<?> c2, Set<Class<?>> s) {
+        if(c1.isAssignableFrom(c2)) {
+            s.add(c1);
+        }
+        Class<?> sc = c1.getSuperclass();
+        if(sc != null) {
+            collectAssignables(sc, c2, s);
+        }
+        Class<?>[] itf = c1.getInterfaces();
+        for(int i = 0; i < itf.length; ++i) {
+            collectAssignables(itf[i], c2, s);
+        }
+    }
+
+    private static final Map<Class<?>, Class<?>> WRAPPER_TYPES = createWrapperTypes();
+    private static final Map<Class<?>, Class<?>> PRIMITIVE_TYPES = invertMap(WRAPPER_TYPES);
+    private static final Map<String, Class<?>> PRIMITIVE_TYPES_BY_NAME = createClassNameMapping(WRAPPER_TYPES.keySet());
+
+    private static Map<Class<?>, Class<?>> createWrapperTypes() {
+        final Map<Class<?>, Class<?>> wrapperTypes = new IdentityHashMap<>(8);
+        wrapperTypes.put(Boolean.TYPE, Boolean.class);
+        wrapperTypes.put(Byte.TYPE, Byte.class);
+        wrapperTypes.put(Character.TYPE, Character.class);
+        wrapperTypes.put(Short.TYPE, Short.class);
+        wrapperTypes.put(Integer.TYPE, Integer.class);
+        wrapperTypes.put(Long.TYPE, Long.class);
+        wrapperTypes.put(Float.TYPE, Float.class);
+        wrapperTypes.put(Double.TYPE, Double.class);
+        return Collections.unmodifiableMap(wrapperTypes);
+    }
+
+    private static Map<String, Class<?>> createClassNameMapping(Collection<Class<?>> classes) {
+        final Map<String, Class<?>> map = new HashMap<>();
+        for(Class<?> clazz: classes) {
+            map.put(clazz.getName(), clazz);
+        }
+        return map;
+    }
+
+    private static <K, V> Map<V, K> invertMap(Map<K, V> map) {
+        final Map<V, K> inverted = new IdentityHashMap<>(map.size());
+        for(Map.Entry<K, V> entry: map.entrySet()) {
+            inverted.put(entry.getValue(), entry.getKey());
+        }
+        return Collections.unmodifiableMap(inverted);
+    }
+
+    /**
+     * Determines whether one type can be converted to another type using a method invocation conversion, as per JLS 5.3
+     * "Method Invocation Conversion". This is basically all conversions allowed by subtyping (see
+     * {@link #isSubtype(Class, Class)}) as well as boxing conversion (JLS 5.1.7) optionally followed by widening
+     * reference conversion and unboxing conversion (JLS 5.1.8) optionally followed by widening primitive conversion.
+     *
+     * @param callSiteType the parameter type at the call site
+     * @param methodType the parameter type in the method declaration
+     * @return true if callSiteType is method invocation convertible to the methodType.
+     */
+    public static boolean isMethodInvocationConvertible(Class<?> callSiteType, Class<?> methodType) {
+        if(methodType.isAssignableFrom(callSiteType)) {
+            return true;
+        }
+        if(callSiteType.isPrimitive()) {
+            if(methodType.isPrimitive()) {
+                return isProperPrimitiveSubtype(callSiteType, methodType);
+            }
+            // Boxing + widening reference conversion
+            return methodType.isAssignableFrom(WRAPPER_TYPES.get(callSiteType));
+        }
+        if(methodType.isPrimitive()) {
+            final Class<?> unboxedCallSiteType = PRIMITIVE_TYPES.get(callSiteType);
+            return unboxedCallSiteType != null
+                    && (unboxedCallSiteType == methodType || isProperPrimitiveSubtype(unboxedCallSiteType, methodType));
+        }
+        return false;
+    }
+
+    /**
+     * Determines whether one type can be potentially converted to another type at runtime. Allows a conversion between
+     * any subtype and supertype in either direction, and also allows a conversion between any two primitive types, as
+     * well as between any primitive type and any reference type that can hold a boxed primitive.
+     *
+     * @param callSiteType the parameter type at the call site
+     * @param methodType the parameter type in the method declaration
+     * @return true if callSiteType is potentially convertible to the methodType.
+     */
+    public static boolean isPotentiallyConvertible(Class<?> callSiteType, Class<?> methodType) {
+        // Widening or narrowing reference conversion
+        if(methodType.isAssignableFrom(callSiteType) || callSiteType.isAssignableFrom(methodType)) {
+            return true;
+        }
+        if(callSiteType.isPrimitive()) {
+            // Allow any conversion among primitives, as well as from any
+            // primitive to any type that can receive a boxed primitive.
+            // TODO: narrow this a bit, i.e. allow, say, boolean to Character?
+            // MethodHandles.convertArguments() allows it, so we might need to
+            // too.
+            return methodType.isPrimitive() || isAssignableFromBoxedPrimitive(methodType);
+        }
+        if(methodType.isPrimitive()) {
+            // Allow conversion from any reference type that can contain a
+            // boxed primitive to any primitive.
+            // TODO: narrow this a bit too?
+            return isAssignableFromBoxedPrimitive(callSiteType);
+        }
+        return false;
+    }
+
+    /**
+     * Determines whether one type is a subtype of another type, as per JLS 4.10 "Subtyping". Note: this is not strict
+     * or proper subtype, therefore true is also returned for identical types; to be completely precise, it allows
+     * identity conversion (JLS 5.1.1), widening primitive conversion (JLS 5.1.2) and widening reference conversion (JLS
+     * 5.1.5).
+     *
+     * @param subType the supposed subtype
+     * @param superType the supposed supertype of the subtype
+     * @return true if subType can be converted by identity conversion, widening primitive conversion, or widening
+     * reference conversion to superType.
+     */
+    public static boolean isSubtype(Class<?> subType, Class<?> superType) {
+        // Covers both JLS 4.10.2 "Subtyping among Class and Interface Types"
+        // and JLS 4.10.3 "Subtyping among Array Types", as well as primitive
+        // type identity.
+        if(superType.isAssignableFrom(subType)) {
+            return true;
+        }
+        // JLS 4.10.1 "Subtyping among Primitive Types". Note we don't test for
+        // identity, as identical types were taken care of in the
+        // isAssignableFrom test. As per 4.10.1, the supertype relation is as
+        // follows:
+        // double > float
+        // float > long
+        // long > int
+        // int > short
+        // int > char
+        // short > byte
+        if(superType.isPrimitive() && subType.isPrimitive()) {
+            return isProperPrimitiveSubtype(subType, superType);
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if a supposed primitive subtype is a proper subtype ( meaning, subtype and not identical) of the
+     * supposed primitive supertype
+     *
+     * @param subType the supposed subtype
+     * @param superType the supposed supertype
+     * @return true if subType is a proper (not identical to) primitive subtype of the superType
+     */
+    private static boolean isProperPrimitiveSubtype(Class<?> subType, Class<?> superType) {
+        if(superType == boolean.class || subType == boolean.class) {
+            return false;
+        }
+        if(subType == byte.class) {
+            return superType != char.class;
+        }
+        if(subType == char.class) {
+            return superType != short.class && superType != byte.class;
+        }
+        if(subType == short.class) {
+            return superType != char.class && superType != byte.class;
+        }
+        if(subType == int.class) {
+            return superType == long.class || superType == float.class || superType == double.class;
+        }
+        if(subType == long.class) {
+            return superType == float.class || superType == double.class;
+        }
+        if(subType == float.class) {
+            return superType == double.class;
+        }
+        return false;
+    }
+
+    private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPES = createWrapperToPrimitiveTypes();
+
+    private static Map<Class<?>, Class<?>> createWrapperToPrimitiveTypes() {
+        final Map<Class<?>, Class<?>> classes = new IdentityHashMap<>();
+        classes.put(Void.class, Void.TYPE);
+        classes.put(Boolean.class, Boolean.TYPE);
+        classes.put(Byte.class, Byte.TYPE);
+        classes.put(Character.class, Character.TYPE);
+        classes.put(Short.class, Short.TYPE);
+        classes.put(Integer.class, Integer.TYPE);
+        classes.put(Long.class, Long.TYPE);
+        classes.put(Float.class, Float.TYPE);
+        classes.put(Double.class, Double.TYPE);
+        return classes;
+    }
+
+    private static final Set<Class<?>> PRIMITIVE_WRAPPER_TYPES = createPrimitiveWrapperTypes();
+
+    private static Set<Class<?>> createPrimitiveWrapperTypes() {
+        final Map<Class<?>, Class<?>> classes = new IdentityHashMap<>();
+        addClassHierarchy(classes, Boolean.class);
+        addClassHierarchy(classes, Byte.class);
+        addClassHierarchy(classes, Character.class);
+        addClassHierarchy(classes, Short.class);
+        addClassHierarchy(classes, Integer.class);
+        addClassHierarchy(classes, Long.class);
+        addClassHierarchy(classes, Float.class);
+        addClassHierarchy(classes, Double.class);
+        return classes.keySet();
+    }
+
+    private static void addClassHierarchy(Map<Class<?>, Class<?>> map, Class<?> clazz) {
+        if(clazz == null) {
+            return;
+        }
+        map.put(clazz, clazz);
+        addClassHierarchy(map, clazz.getSuperclass());
+        for(Class<?> itf: clazz.getInterfaces()) {
+            addClassHierarchy(map, itf);
+        }
+    }
+
+    /**
+     * Returns true if the class can be assigned from any boxed primitive.
+     *
+     * @param clazz the class
+     * @return true if the class can be assigned from any boxed primitive. Basically, it is true if the class is any
+     * primitive wrapper class, or a superclass or superinterface of any primitive wrapper class.
+     */
+    private static boolean isAssignableFromBoxedPrimitive(Class<?> clazz) {
+        return PRIMITIVE_WRAPPER_TYPES.contains(clazz);
+    }
+
+    /**
+     * Given a name of a primitive type (except "void"), returns the class representing it. I.e. when invoked with
+     * "int", returns {@link Integer#TYPE}.
+     * @param name the name of the primitive type
+     * @return the class representing the primitive type, or null if the name does not correspond to a primitive type
+     * or is "void".
+     */
+    public static Class<?> getPrimitiveTypeByName(String name) {
+        return PRIMITIVE_TYPES_BY_NAME.get(name);
+    }
+
+    /**
+     * When passed a class representing a wrapper for a primitive type, returns the class representing the corresponding
+     * primitive type. I.e. calling it with {@code Integer.class} will return {@code Integer.TYPE}. If passed a class
+     * that is not a wrapper for primitive type, returns null.
+     * @param wrapperType the class object representing a wrapper for a primitive type
+     * @return the class object representing the primitive type, or null if the passed class is not a primitive wrapper.
+     */
+    public static Class<?> getPrimitiveType(Class<?> wrapperType) {
+        return WRAPPER_TO_PRIMITIVE_TYPES.get(wrapperType);
+    }
+
+
+    /**
+     * When passed a class representing a primitive type, returns the class representing the corresponding
+     * wrapper type. I.e. calling it with {@code int.class} will return {@code Integer.class}. If passed a class
+     * that is not a primitive type, returns null.
+     * @param primitiveType the class object representing a primitive type
+     * @return the class object representing the wrapper type, or null if the passed class is not a primitive.
+     */
+    public static Class<?> getWrapperType(Class<?> primitiveType) {
+        return WRAPPER_TYPES.get(primitiveType);
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/UnnamedDynCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/UnnamedDynCallSiteDescriptor.java
new file mode 100644
index 0000000..da8c009
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/UnnamedDynCallSiteDescriptor.java
@@ -0,0 +1,126 @@
+/*
+ * 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.support;
+
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+
+class UnnamedDynCallSiteDescriptor extends AbstractCallSiteDescriptor {
+    private final MethodType methodType;
+    private final String op;
+
+    UnnamedDynCallSiteDescriptor(String op, MethodType methodType) {
+        this.op = op;
+        this.methodType = methodType;
+    }
+
+    @Override
+    public int getNameTokenCount() {
+        return 2;
+    }
+
+    String getOp() {
+        return op;
+    }
+
+    @Override
+    public String getNameToken(int i) {
+        switch(i) {
+            case 0: return "dyn";
+            case 1: return op;
+            default: throw new IndexOutOfBoundsException(String.valueOf(i));
+        }
+    }
+
+    @Override
+    public MethodType getMethodType() {
+        return methodType;
+    }
+
+    @Override
+    public CallSiteDescriptor changeMethodType(MethodType newMethodType) {
+        return CallSiteDescriptorFactory.getCanonicalPublicDescriptor(new UnnamedDynCallSiteDescriptor(op,
+                newMethodType));
+    }
+}
diff --git a/nashorn/src/jdk/internal/dynalink/support/messages.properties b/nashorn/src/jdk/internal/dynalink/support/messages.properties
new file mode 100644
index 0000000..eaf1f63
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/messages.properties
@@ -0,0 +1,86 @@
+#  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.
+
+isInstanceGuardAlwaysTrue=isInstance guard for {0} in position {1} in method type {2} will always return true
+isInstanceGuardAlwaysFalse=isInstance guard for {0} in position {1} in method type {2} will always return false
+
+isOfClassGuardAlwaysTrue=isOfClass guard for {0} in position {1} in method type {2} will always return true
+isOfClassGuardAlwaysFalse=isOfClass guard for {0} in position {1} in method type {2} will always return false
+
+isArrayGuardAlwaysTrue=isArray guard in position {0} in method type {1} will always return true
+isArrayGuardAlwaysFalse=isArray guard in position {0} in method type {1} will always return false
\ No newline at end of file
diff --git a/nashorn/src/jdk/internal/dynalink/support/package.html b/nashorn/src/jdk/internal/dynalink/support/package.html
new file mode 100644
index 0000000..7bf9efc
--- /dev/null
+++ b/nashorn/src/jdk/internal/dynalink/support/package.html
@@ -0,0 +1,89 @@
+<!--

+   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.

+-->

+  <body>

+    <p>

+      Contains supporting classes for other packages. There is no guarantee that

+      any of these classes or interfaces will not change in a manner that breaks

+      backwards compatibility; they are not considered to be part of the public

+      API.

+    </p>

+  </body>

diff --git a/nashorn/src/jdk/nashorn/api/scripting/Formatter.java b/nashorn/src/jdk/nashorn/api/scripting/Formatter.java
new file mode 100644
index 0000000..3b47d34
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/api/scripting/Formatter.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Formatter is a class to get the type conversion between javascript types and
+ * java types for the format (sprintf) method working.
+ *
+ * <p>In javascript the type for numbers can be different from the format type
+ * specifier. For format type '%d', '%o', '%x', '%X' double need to be
+ * converted to integer. For format type 'e', 'E', 'f', 'g', 'G', 'a', 'A'
+ * integer needs to be converted to double.
+ *
+ * <p>Format type "%c" and javascript string needs special handling.
+ *
+ * <p>The javascript date objects can be handled if they are type double (the
+ * related javascript code will convert with Date.getTime() to double). So
+ * double date types are converted to long.
+ *
+ * <p>Pattern and the logic for parameter position: java.util.Formatter
+ *
+ */
+public final class Formatter {
+
+    private Formatter() {
+    }
+
+    /**
+     * Method which converts javascript types to java types for the
+     * String.format method (jrunscript function sprintf).
+     *
+     * @param format a format string
+     * @param args arguments referenced by the format specifiers in format
+     * @return a formatted string
+     */
+    public static String format(final String format, final Object[] args) {
+        Matcher m = FS_PATTERN.matcher(format);
+        int positionalParameter = 1;
+
+        while (m.find()) {
+            int index = index(m.group(1));
+            boolean previous = isPreviousArgument(m.group(2));
+            char conversion = m.group(6).charAt(0);
+
+            // skip over some formats
+            if (index < 0 || previous
+                    || conversion == 'n' || conversion == '%') {
+                continue;
+            }
+
+            // index 0 here means take a positional parameter
+            if (index == 0) {
+                index = positionalParameter++;
+            }
+
+            // out of index, String.format will handle
+            if (index > args.length) {
+                continue;
+            }
+
+            // current argument
+            Object arg = args[index - 1];
+
+            // for date we convert double to long
+            if (m.group(5) != null) {
+                // convert double to long
+                if (arg instanceof Double) {
+                    args[index - 1] = ((Double) arg).longValue();
+                }
+            } else {
+                // we have to convert some types
+                switch (conversion) {
+                    case 'd':
+                    case 'o':
+                    case 'x':
+                    case 'X':
+                        if (arg instanceof Double) {
+                            // convert double to long
+                            args[index - 1] = ((Double) arg).longValue();
+                        } else if (arg instanceof String
+                                && ((String) arg).length() > 0) {
+                            // convert string (first character) to int
+                            args[index - 1] = (int) ((String) arg).charAt(0);
+                        }
+                        break;
+                    case 'e':
+                    case 'E':
+                    case 'f':
+                    case 'g':
+                    case 'G':
+                    case 'a':
+                    case 'A':
+                        if (arg instanceof Integer) {
+                            // convert integer to double
+                            args[index - 1] = ((Integer) arg).doubleValue();
+                        }
+                        break;
+                    case 'c':
+                        if (arg instanceof Double) {
+                            // convert double to integer
+                            args[index - 1] = ((Double) arg).intValue();
+                        } else if (arg instanceof String
+                                && ((String) arg).length() > 0) {
+                            // get the first character from string
+                            args[index - 1] = (int) ((String) arg).charAt(0);
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        return String.format(format, args);
+    }
+
+    /**
+     * Method to parse the integer of the argument index.
+     *
+     * @param s
+     * @return -1 if parsing failed, 0 if string is null, > 0 integer
+     */
+    private static int index(final String s) {
+        int index = -1;
+
+        if (s != null) {
+            try {
+                index = Integer.parseInt(s.substring(0, s.length() - 1));
+            } catch (final NumberFormatException e) {
+                //ignored
+            }
+        } else {
+            index = 0;
+        }
+
+        return index;
+    }
+
+    /**
+     * Method to check if a string contains '&lt;'. This is used to find out if
+     * previous parameter is used.
+     *
+     * @param s
+     * @return true if '&lt;' is in the string, else false
+     */
+    private static boolean isPreviousArgument(final String s) {
+        return (s != null && s.indexOf('<') >= 0) ? true : false;
+    }
+
+    // %[argument_index$][flags][width][.precision][t]conversion
+    private static final String formatSpecifier =
+            "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";
+    // compiled format string
+    private static final Pattern FS_PATTERN;
+
+    static {
+        FS_PATTERN = Pattern.compile(formatSpecifier);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java
new file mode 100644
index 0000000..d1d47b1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import jdk.nashorn.internal.runtime.ECMAErrors;
+
+/**
+ * This is base exception for all Nashorn exceptions. These originate from
+ * user's ECMAScript code. Example: script parse errors, exceptions thrown from
+ * scripts. Note that ScriptEngine methods like "eval", "invokeMethod",
+ * "invokeFunction" will wrap this as ScriptException and throw it. But, there
+ * are cases where user may need to access this exception (or implementation
+ * defined subtype of this). For example, if java interface is implemented by a
+ * script object or Java access to script object properties via java.util.Map
+ * interface. In these cases, user code will get an instance of this or
+ * implementation defined subclass.
+ */
+@SuppressWarnings("serial")
+public abstract class NashornException extends RuntimeException {
+    // script file name
+    private final String fileName;
+    // script line number
+    private final int line;
+    // script column number
+    private final int column;
+
+    /** script source name used for "engine.js" */
+    public static final String ENGINE_SCRIPT_SOURCE_NAME = "nashorn:engine/resources/engine.js";
+
+    /**
+     * Constructor
+     *
+     * @param msg       exception message
+     * @param fileName  file name
+     * @param line      line number
+     * @param column    column number
+     */
+    protected NashornException(final String msg, final String fileName, final int line, final int column) {
+        this(msg, null, fileName, line, column);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param msg       exception message
+     * @param cause     exception cause
+     * @param fileName  file name
+     * @param line      line number
+     * @param column    column number
+     */
+    protected NashornException(final String msg, final Throwable cause, final String fileName, final int line, final int column) {
+        super(msg, cause == null ? null : cause);
+        this.fileName = fileName;
+        this.line = line;
+        this.column = column;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param msg       exception message
+     * @param cause     exception cause
+     */
+    protected NashornException(final String msg, final Throwable cause) {
+        super(msg, cause == null ? null : cause);
+        // This is not so pretty - but it gets the job done. Note that the stack
+        // trace has been already filled by "fillInStackTrace" call from
+        // Throwable
+        // constructor and so we don't pay additional cost for it.
+
+        // Hard luck - no column number info
+        this.column = -1;
+
+        // Find the first JavaScript frame by walking and set file, line from it
+        // Usually, we should be able to find it in just few frames depth.
+        for (final StackTraceElement ste : getStackTrace()) {
+            if (ECMAErrors.isScriptFrame(ste)) {
+                // Whatever here is compiled from JavaScript code
+                this.fileName = ste.getFileName();
+                this.line = ste.getLineNumber();
+                return;
+            }
+        }
+
+        this.fileName = null;
+        this.line = 0;
+    }
+
+    /**
+     * Get the source file name for this {@code NashornException}
+     *
+     * @return the file name
+     */
+    public final String getFileName() {
+        return fileName;
+    }
+
+    /**
+     * Get the line number for this {@code NashornException}
+     *
+     * @return the line number
+     */
+    public final int getLineNumber() {
+        return line;
+    }
+
+    /**
+     * Get the column for this {@code NashornException}
+     *
+     * @return the column
+     */
+    public final int getColumnNumber() {
+        return column;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
new file mode 100644
index 0000000..ce16a7e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
@@ -0,0 +1,488 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import javax.script.AbstractScriptEngine;
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.Invocable;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.GlobalObject;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * JSR-223 compliant script engine for Nashorn. Instances are not created directly, but rather returned through
+ * {@link NashornScriptEngineFactory#getScriptEngine()}. Note that this engine implements the {@link Compilable} and
+ * {@link Invocable} interfaces, allowing for efficient precompilation and repeated execution of scripts.
+ * @see NashornScriptEngineFactory
+ */
+
+public final class NashornScriptEngine extends AbstractScriptEngine implements Compilable, Invocable {
+
+    private final ScriptEngineFactory factory;
+    private final Context             nashornContext;
+    private final ScriptObject        global;
+
+    // default options passed to Nashorn Options object
+    private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-af", "-doe" };
+
+    NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) {
+        this(factory, DEFAULT_OPTIONS, appLoader);
+    }
+
+    @SuppressWarnings("LeakingThisInConstructor")
+    NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader) {
+        this.factory = factory;
+        final Options options = new Options("nashorn");
+        options.process(args);
+
+        // throw ParseException on first error from script
+        final ErrorManager errMgr = new Context.ThrowErrorManager();
+        // create new Nashorn Context
+        this.nashornContext = AccessController.doPrivileged(new PrivilegedAction<Context>() {
+            @Override
+            public Context run() {
+                try {
+                    return new Context(options, errMgr, appLoader);
+                } catch (final RuntimeException e) {
+                    if (Context.DEBUG) {
+                        e.printStackTrace();
+                    }
+                    throw e;
+                }
+            }
+        });
+
+        // create new global object
+        this.global =  createNashornGlobal();
+        // set the default engine scope for the default context
+        context.setBindings(new ScriptObjectMirror(global, global), ScriptContext.ENGINE_SCOPE);
+
+        // evaluate engine initial script
+        try {
+            evalEngineScript();
+        } catch (final ScriptException e) {
+            if (Context.DEBUG) {
+                e.printStackTrace();
+            }
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public Object eval(final Reader reader, final ScriptContext ctxt) throws ScriptException {
+        try {
+            if (reader instanceof URLReader) {
+                final URL url = ((URLReader)reader).getURL();
+                return evalImpl(compileImpl(new Source(url.toString(), url), ctxt), ctxt);
+            }
+            return evalImpl(Source.readFully(reader), ctxt);
+        } catch (final IOException e) {
+            throw new ScriptException(e);
+        }
+    }
+
+    @Override
+    public Object eval(final String script, final ScriptContext ctxt) throws ScriptException {
+        return evalImpl(script.toCharArray(), ctxt);
+    }
+
+    @Override
+    public ScriptEngineFactory getFactory() {
+        return factory;
+    }
+
+    @Override
+    public Bindings createBindings() {
+        final ScriptObject newGlobal = createNashornGlobal();
+        return new ScriptObjectMirror(newGlobal, newGlobal);
+    }
+
+    // Compilable methods
+
+    @Override
+    public CompiledScript compile(final Reader reader) throws ScriptException {
+        try {
+            return asCompiledScript(compileImpl(Source.readFully(reader), context));
+        } catch (final IOException e) {
+            throw new ScriptException(e);
+        }
+    }
+
+    @Override
+    public CompiledScript compile(final String str) throws ScriptException {
+        return asCompiledScript(compileImpl(str.toCharArray(), context));
+    }
+
+    // Invocable methods
+
+    @Override
+    public Object invokeFunction(final String name, final Object... args)
+            throws ScriptException, NoSuchMethodException {
+        return invokeImpl(null, name, args);
+    }
+
+    @Override
+    public Object invokeMethod(final Object self, final String name, final Object... args)
+            throws ScriptException, NoSuchMethodException {
+        if (self == null) {
+            throw new IllegalArgumentException("script object can not be null");
+        }
+        return invokeImpl(self, name, args);
+    }
+
+    private <T> T getInterfaceInner(final Object self, final Class<T> clazz) {
+        final Object realSelf;
+        final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
+        if(self == null) {
+            realSelf = ctxtGlobal;
+        } else if (!(self instanceof ScriptObject)) {
+            realSelf = ScriptObjectMirror.unwrap(self, ctxtGlobal);
+        } else {
+            realSelf = self;
+        }
+        try {
+            final ScriptObject oldGlobal = getNashornGlobal();
+            try {
+                if(oldGlobal != ctxtGlobal) {
+                    setNashornGlobal(ctxtGlobal);
+                }
+                return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz).invoke(realSelf));
+            } finally {
+                if(oldGlobal != ctxtGlobal) {
+                    setNashornGlobal(oldGlobal);
+                }
+            }
+        } catch(final RuntimeException|Error e) {
+            throw e;
+        } catch(final Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    @Override
+    public <T> T getInterface(final Class<T> clazz) {
+        return getInterfaceInner(null, clazz);
+    }
+
+    @Override
+    public <T> T getInterface(final Object self, final Class<T> clazz) {
+        if (self == null) {
+            throw new IllegalArgumentException("script object can not be null");
+        }
+        return getInterfaceInner(self, clazz);
+    }
+
+    // These are called from the "engine.js" script
+
+    /**
+     * This hook is used to search js global variables exposed from Java code.
+     *
+     * @param self 'this' passed from the script
+     * @param ctxt current ScriptContext in which name is searched
+     * @param name name of the variable searched
+     * @return the value of the named variable
+     */
+    public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
+        final int scope = ctxt.getAttributesScope(name);
+        final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
+        if (scope != -1) {
+            return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
+        }
+
+        if (self == UNDEFINED) {
+            // scope access and so throw ReferenceError
+            throw referenceError(ctxtGlobal, "not.defined", name);
+        }
+
+        return UNDEFINED;
+    }
+
+    private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
+        final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
+        if (bindings instanceof ScriptObjectMirror) {
+             ScriptObject sobj = ((ScriptObjectMirror)bindings).getScriptObject();
+             if (sobj instanceof GlobalObject) {
+                 return sobj;
+             }
+        }
+
+        // didn't find global object from context given - return the engine-wide global
+        return global;
+    }
+
+    private ScriptObject createNashornGlobal() {
+        final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
+            @Override
+            public ScriptObject run() {
+                try {
+                    return nashornContext.newGlobal();
+                } catch (final RuntimeException e) {
+                    if (Context.DEBUG) {
+                        e.printStackTrace();
+                    }
+                    throw e;
+                }
+            }
+        });
+
+        nashornContext.initGlobal(newGlobal);
+
+        // current ScriptContext exposed as "context"
+        newGlobal.addOwnProperty("context", Property.NOT_ENUMERABLE, UNDEFINED);
+        // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as
+        // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property
+        // in the Global of a Context we just created - both the Context and the Global were just created and can not be
+        // seen from another thread outside of this constructor.
+        newGlobal.addOwnProperty("engine", Property.NOT_ENUMERABLE, this);
+        // global script arguments with undefined value
+        newGlobal.addOwnProperty("arguments", Property.NOT_ENUMERABLE, UNDEFINED);
+        // file name default is null
+        newGlobal.addOwnProperty(ScriptEngine.FILENAME, Property.NOT_ENUMERABLE, null);
+        return newGlobal;
+    }
+
+    private void evalEngineScript() throws ScriptException {
+        evalSupportScript("resources/engine.js", NashornException.ENGINE_SCRIPT_SOURCE_NAME);
+    }
+
+    private void evalSupportScript(final String script, final String name) throws ScriptException {
+        try {
+            final InputStream is = AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<InputStream>() {
+                        @Override
+                        public InputStream run() throws Exception {
+                            final URL url = NashornScriptEngine.class.getResource(script);
+                            return url.openStream();
+                        }
+                    });
+            put(ScriptEngine.FILENAME, name);
+            try (final InputStreamReader isr = new InputStreamReader(is)) {
+                eval(isr);
+            }
+        } catch (final PrivilegedActionException | IOException e) {
+            throw new ScriptException(e);
+        } finally {
+            put(ScriptEngine.FILENAME, null);
+        }
+    }
+
+    // scripts should see "context" and "engine" as variables
+    private void setContextVariables(final ScriptContext ctxt) {
+        ctxt.setAttribute("context", ctxt, ScriptContext.ENGINE_SCOPE);
+        final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
+        ctxtGlobal.set("context", ctxt, false);
+        Object args = ScriptObjectMirror.unwrap(ctxt.getAttribute("arguments"), ctxtGlobal);
+        if (args == null || args == UNDEFINED) {
+            args = ScriptRuntime.EMPTY_ARRAY;
+        }
+        // if no arguments passed, expose it
+        args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
+        ctxtGlobal.set("arguments", args, false);
+    }
+
+    private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
+        final ScriptObject oldGlobal     = getNashornGlobal();
+        final ScriptObject ctxtGlobal    = getNashornGlobalFrom(context);
+        final boolean globalChanged = (oldGlobal != ctxtGlobal);
+
+        Object self = globalChanged? ScriptObjectMirror.wrap(selfObject, oldGlobal) : selfObject;
+
+        try {
+            if (globalChanged) {
+                setNashornGlobal(ctxtGlobal);
+            }
+
+            ScriptObject sobj;
+            Object       value = null;
+
+            self = ScriptObjectMirror.unwrap(self, ctxtGlobal);
+
+            // FIXME: should convert when self is not ScriptObject
+            if (self instanceof ScriptObject) {
+                sobj = (ScriptObject)self;
+                value = sobj.get(name);
+            } else if (self == null) {
+                self  = ctxtGlobal;
+                sobj  = ctxtGlobal;
+                value = sobj.get(name);
+            }
+
+            if (value instanceof ScriptFunction) {
+                final Object res;
+                try {
+                    final Object[] modArgs = globalChanged? ScriptObjectMirror.wrapArray(args, oldGlobal) : args;
+                    res = ScriptRuntime.checkAndApply((ScriptFunction)value, self, ScriptObjectMirror.unwrapArray(modArgs, ctxtGlobal));
+                } catch (final Exception e) {
+                    throwAsScriptException(e);
+                    throw new AssertionError("should not reach here");
+                }
+                return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(res, ctxtGlobal));
+            }
+
+            throw new NoSuchMethodException(name);
+        } finally {
+            if (globalChanged) {
+                setNashornGlobal(oldGlobal);
+            }
+        }
+    }
+
+    private Object evalImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException {
+        return evalImpl(compileImpl(buf, ctxt), ctxt);
+    }
+
+    private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException {
+        if (script == null) {
+            return null;
+        }
+        final ScriptObject oldGlobal = getNashornGlobal();
+        final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
+        final boolean globalChanged = (oldGlobal != ctxtGlobal);
+        try {
+            if (globalChanged) {
+                setNashornGlobal(ctxtGlobal);
+            }
+
+            setContextVariables(ctxt);
+            final Object val = ctxt.getAttribute(ScriptEngine.FILENAME);
+            final String fileName = (val != null) ? val.toString() : "<eval>";
+
+            // NOTE: FIXME: If this is jrunscript's init.js, we want to run the replacement.
+            // This should go away once we fix jrunscript's copy of init.js.
+            if ("<system-init>".equals(fileName)) {
+                evalSupportScript("resources/init.js", "nashorn:engine/resources/init.js");
+                return null;
+            }
+
+            Object res = ScriptRuntime.apply(script, ctxtGlobal);
+            return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(res, ctxtGlobal));
+        } catch (final Exception e) {
+            throwAsScriptException(e);
+            throw new AssertionError("should not reach here");
+        } finally {
+            if (globalChanged) {
+                setNashornGlobal(oldGlobal);
+            }
+        }
+    }
+
+    private static void throwAsScriptException(final Exception e) throws ScriptException {
+        if (e instanceof ScriptException) {
+            throw (ScriptException)e;
+        } else if (e instanceof NashornException) {
+            final NashornException ne = (NashornException)e;
+            final ScriptException se = new ScriptException(
+                ne.getMessage(), ne.getFileName(),
+                ne.getLineNumber(), ne.getColumnNumber());
+            se.initCause(e);
+            throw se;
+        } else if (e instanceof RuntimeException) {
+            throw (RuntimeException)e;
+        } else {
+            // wrap any other exception as ScriptException
+            throw new ScriptException(e);
+        }
+    }
+
+    private CompiledScript asCompiledScript(final ScriptFunction script) {
+        return new CompiledScript() {
+            @Override
+            public Object eval(final ScriptContext ctxt) throws ScriptException {
+                return evalImpl(script, ctxt);
+            }
+            @Override
+            public ScriptEngine getEngine() {
+                return NashornScriptEngine.this;
+            }
+        };
+    }
+
+    private ScriptFunction compileImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException {
+        final Object val = ctxt.getAttribute(ScriptEngine.FILENAME);
+        final String fileName = (val != null) ? val.toString() : "<eval>";
+        return compileImpl(new Source(fileName, buf), ctxt);
+    }
+
+    private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException {
+        final ScriptObject oldGlobal = getNashornGlobal();
+        final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
+        final boolean globalChanged = (oldGlobal != ctxtGlobal);
+        try {
+            if (globalChanged) {
+                setNashornGlobal(ctxtGlobal);
+            }
+
+            return nashornContext.compileScript(source, ctxtGlobal);
+        } catch (final Exception e) {
+            throwAsScriptException(e);
+            throw new AssertionError("should not reach here");
+        } finally {
+            if (globalChanged) {
+                setNashornGlobal(oldGlobal);
+            }
+        }
+    }
+
+    // don't make this public!!
+    static ScriptObject getNashornGlobal() {
+        return Context.getGlobal();
+    }
+
+    static void setNashornGlobal(final ScriptObject newGlobal) {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override
+            public Void run() {
+               Context.setGlobal(newGlobal);
+               return null;
+            }
+        });
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
new file mode 100644
index 0000000..47a0c59
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import jdk.nashorn.internal.runtime.Version;
+import sun.reflect.Reflection;
+
+/**
+ * JSR-223 compliant script engine factory for Nashorn. The engine answers for:
+ * <ul>
+ * <li>names {@code "nashorn"}, {@code "Nashorn"}, {@code "js"}, {@code "JS"}, {@code "JavaScript"},
+ * {@code "javascript"}, {@code "ECMAScript"}, and {@code "ecmascript"};</li>
+ * <li>MIME types {@code "application/javascript"}, {@code "application/ecmascript"}, {@code "text/javascript"}, and
+ * {@code "text/ecmascript"};</li>
+ * <li>as well as for the extension {@code "js"}.</li>
+ * </ul>
+ * Programs executing in engines created using {@link #getScriptEngine(String[])} will have the passed arguments
+ * accessible as a global variable named {@code "arguments"}.
+ */
+public final class NashornScriptEngineFactory implements ScriptEngineFactory {
+    @Override
+    public String getEngineName() {
+        return (String) getParameter(ScriptEngine.ENGINE);
+    }
+
+    @Override
+    public String getEngineVersion() {
+        return (String) getParameter(ScriptEngine.ENGINE_VERSION);
+    }
+
+    @Override
+    public List<String> getExtensions() {
+        return Collections.unmodifiableList(extensions);
+    }
+
+    @Override
+    public String getLanguageName() {
+        return (String) getParameter(ScriptEngine.LANGUAGE);
+    }
+
+    @Override
+    public String getLanguageVersion() {
+        return (String) getParameter(ScriptEngine.LANGUAGE_VERSION);
+    }
+
+    @Override
+    public String getMethodCallSyntax(final String obj, final String method, final String... args) {
+        final StringBuilder sb = new StringBuilder().append(obj).append('.').append(method).append('(');
+        final int len = args.length;
+
+        if (len > 0) {
+            sb.append(args[0]);
+        }
+        for (int i = 1; i < len; i++) {
+            sb.append(',').append(args[i]);
+        }
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    @Override
+    public List<String> getMimeTypes() {
+        return Collections.unmodifiableList(mimeTypes);
+    }
+
+    @Override
+    public List<String> getNames() {
+        return Collections.unmodifiableList(names);
+    }
+
+    @Override
+    public String getOutputStatement(final String toDisplay) {
+        return "print(" + toDisplay + ")";
+    }
+
+    @Override
+    public Object getParameter(final String key) {
+        switch (key) {
+        case ScriptEngine.NAME:
+            return "javascript";
+        case ScriptEngine.ENGINE:
+            return "Oracle Nashorn";
+        case ScriptEngine.ENGINE_VERSION:
+            return Version.version();
+        case ScriptEngine.LANGUAGE:
+            return "ECMAScript";
+        case ScriptEngine.LANGUAGE_VERSION:
+            return "ECMA - 262 Edition 5.1";
+        case "THREADING":
+            // The engine implementation is not thread-safe. Can't be
+            // used to execute scripts concurrently on multiple threads.
+            return null;
+        default:
+            throw new IllegalArgumentException("Invalid key");
+        }
+    }
+
+    @Override
+    public String getProgram(final String... statements) {
+        final StringBuilder sb = new StringBuilder();
+
+        for (final String statement : statements) {
+            sb.append(statement).append(';');
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public ScriptEngine getScriptEngine() {
+        return new NashornScriptEngine(this, getAppClassLoader());
+    }
+
+    /**
+     * Create a new Script engine initialized by given class loader.
+     *
+     * @param appLoader class loader to be used as script "app" class loader.
+     * @return newly created script engine.
+     */
+    public ScriptEngine getScriptEngine(final ClassLoader appLoader) {
+        return new NashornScriptEngine(this, appLoader);
+    }
+
+    /**
+     * Create a new Script engine initialized by given arguments.
+     *
+     * @param args arguments array passed to script engine.
+     * @return newly created script engine.
+     */
+    public ScriptEngine getScriptEngine(final String[] args) {
+        return new NashornScriptEngine(this, args, getAppClassLoader());
+    }
+
+    /**
+     * Create a new Script engine initialized by given arguments.
+     *
+     * @param args arguments array passed to script engine.
+     * @param appLoader class loader to be used as script "app" class loader.
+     * @return newly created script engine.
+     */
+    public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) {
+        return new NashornScriptEngine(this, args, appLoader);
+    }
+
+    // -- Internals only below this point
+
+    private static final List<String> names;
+    private static final List<String> mimeTypes;
+    private static final List<String> extensions;
+
+    static {
+        names = immutableList(
+                    "nashorn", "Nashorn",
+                    "js", "JS",
+                    "JavaScript", "javascript",
+                    "ECMAScript", "ecmascript"
+                );
+
+        mimeTypes = immutableList(
+                        "application/javascript",
+                        "application/ecmascript",
+                        "text/javascript",
+                        "text/ecmascript"
+                    );
+
+        extensions = immutableList("js");
+    }
+
+    private static List<String> immutableList(final String... elements) {
+        return Collections.unmodifiableList(Arrays.asList(elements));
+    }
+
+    private static ClassLoader getAppClassLoader() {
+        if (System.getSecurityManager() == null) {
+            return Thread.currentThread().getContextClassLoader();
+        }
+
+        // Try to determine the caller class loader. Use that if it can be
+        // found. If not, use the class loader of nashorn itself as the
+        // "application" class loader for scripts.
+
+        // User could have called ScriptEngineFactory.getScriptEngine()
+        //
+        // <caller>
+        //  <factory.getScriptEngine()>
+        //   <factory.getAppClassLoader()>
+        //    <Reflection.getCallerClass()>
+        //
+        // or used one of the getEngineByABC methods of ScriptEngineManager.
+        //
+        // <caller>
+        //  <ScriptEngineManager.getEngineByName()>
+        //   <factory.getScriptEngine()>
+        //    <factory.getAppClassLoader()>
+        //     <Reflection.getCallerClass()>
+
+        // So, stack depth is 3 or 4 (recall it is zero based). We try
+        // stack depths 3, 4 and look for non-bootstrap caller.
+        Class<?> caller = null;
+        for (int depth = 3; depth < 5; depth++) {
+            caller = Reflection.getCallerClass(depth);
+            if (caller != null && caller.getClassLoader() != null) {
+                // found a non-bootstrap caller
+                break;
+            }
+        }
+
+        final ClassLoader ccl = (caller == null)? null : caller.getClassLoader();
+        // if caller loader is null, then use nashorn's own loader
+        return (ccl == null)? NashornScriptEngineFactory.class.getClassLoader() : ccl;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
new file mode 100644
index 0000000..266ce87
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import javax.script.Bindings;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import netscape.javascript.JSObject;
+
+/**
+ * Mirror object that wraps a given ScriptObject instance. User can
+ * access ScriptObject via the javax.script.Bindings interface or
+ * netscape.javascript.JSObject interface.
+ */
+final class ScriptObjectMirror extends JSObject implements Bindings {
+    private final ScriptObject sobj;
+    private final ScriptObject global;
+
+    ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) {
+        this.sobj = sobj;
+        this.global = global;
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other instanceof ScriptObjectMirror) {
+            return sobj.equals(((ScriptObjectMirror)other).sobj);
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return sobj.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return inGlobal(new Callable<String>() {
+            @Override
+            public String call() {
+                return ScriptRuntime.safeToString(sobj);
+            }
+        });
+    }
+
+    private <V> V inGlobal(final Callable<V> callable) {
+        final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
+        final boolean globalChanged = (oldGlobal != global);
+        if (globalChanged) {
+            NashornScriptEngine.setNashornGlobal(global);
+        }
+        try {
+            return callable.call();
+        } catch (final RuntimeException e) {
+            throw e;
+        } catch (final Exception e) {
+            throw new AssertionError("Cannot happen", e);
+        } finally {
+            if (globalChanged) {
+                NashornScriptEngine.setNashornGlobal(oldGlobal);
+            }
+        }
+    }
+
+    // JSObject methods
+    @Override
+    public Object call(final String methodName, final Object args[]) {
+        final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
+        final boolean globalChanged = (oldGlobal != global);
+
+        try {
+            if (globalChanged) {
+                NashornScriptEngine.setNashornGlobal(global);
+            }
+
+            final Object val = sobj.get(methodName);
+            if (! (val instanceof ScriptFunction)) {
+                throw new RuntimeException("No such method: " + methodName);
+            }
+
+            final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
+            return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global);
+        } catch (final RuntimeException | Error e) {
+            throw e;
+        } catch (final Throwable t) {
+            throw new RuntimeException(t);
+        } finally {
+            if (globalChanged) {
+                NashornScriptEngine.setNashornGlobal(oldGlobal);
+            }
+        }
+    }
+
+    @Override
+    public Object eval(final String s) {
+        return inGlobal(new Callable<Object>() {
+            @Override
+            public Object call() {
+                final Context context = AccessController.doPrivileged(
+                        new PrivilegedAction<Context>() {
+                            @Override
+                            public Context run() {
+                                return Context.getContext();
+                            }
+                        });
+                return wrap(context.eval(global, s, null, null, false), global);
+            }
+        });
+    }
+
+    @Override
+    public Object getMember(final String name) {
+        return inGlobal(new Callable<Object>() {
+            @Override public Object call() {
+                return wrap(sobj.get(name), global);
+            }
+        });
+    }
+
+    @Override
+    public Object getSlot(final int index) {
+        return inGlobal(new Callable<Object>() {
+            @Override public Object call() {
+                return wrap(sobj.get(index), global);
+            }
+        });
+    }
+
+    @Override
+    public void removeMember(final String name) {
+        remove(name);
+    }
+
+    @Override
+    public void setMember(final String name, final Object value) {
+        put(name, value);
+    }
+
+    @Override
+    public void setSlot(final int index, final Object value) {
+        inGlobal(new Callable<Void>() {
+            @Override public Void call() {
+                sobj.set(index, unwrap(value, global), global.isStrictContext());
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public void clear() {
+        inGlobal(new Callable<Object>() {
+            @Override public Object call() {
+                sobj.clear();
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public boolean containsKey(final Object key) {
+        return inGlobal(new Callable<Boolean>() {
+            @Override public Boolean call() {
+                return sobj.containsKey(unwrap(key, global));
+            }
+        });
+    }
+
+    @Override
+    public boolean containsValue(final Object value) {
+        return inGlobal(new Callable<Boolean>() {
+            @Override public Boolean call() {
+                return sobj.containsValue(unwrap(value, global));
+            }
+        });
+    }
+
+    @Override
+    public Set<Map.Entry<String, Object>> entrySet() {
+        return inGlobal(new Callable<Set<Map.Entry<String, Object>>>() {
+            @Override public Set<Map.Entry<String, Object>> call() {
+                final Iterator<String>               iter    = sobj.propertyIterator();
+                final Set<Map.Entry<String, Object>> entries = new HashSet<>();
+
+                while (iter.hasNext()) {
+                    final String key   = iter.next();
+                    final Object value = translateUndefined(wrap(sobj.get(key), global));
+                    entries.add(new AbstractMap.SimpleImmutableEntry<>(key, value));
+                }
+
+                return Collections.unmodifiableSet(entries);
+            }
+        });
+    }
+
+    @Override
+    public Object get(final Object key) {
+        return inGlobal(new Callable<Object>() {
+            @Override public Object call() {
+                return translateUndefined(wrap(sobj.get(key), global));
+            }
+        });
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return inGlobal(new Callable<Boolean>() {
+            @Override public Boolean call() {
+                return sobj.isEmpty();
+            }
+        });
+    }
+
+    @Override
+    public Set<String> keySet() {
+        return inGlobal(new Callable<Set<String>>() {
+            @Override public Set<String> call() {
+                final Iterator<String> iter   = sobj.propertyIterator();
+                final Set<String>      keySet = new HashSet<>();
+
+                while (iter.hasNext()) {
+                    keySet.add(iter.next());
+                }
+
+                return Collections.unmodifiableSet(keySet);
+            }
+        });
+    }
+
+    @Override
+    public Object put(final String key, final Object value) {
+        final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
+        final boolean globalChanged = (oldGlobal != global);
+        return inGlobal(new Callable<Object>() {
+            @Override public Object call() {
+                final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
+                return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global)), global));
+            }
+        });
+    }
+
+    @Override
+    public void putAll(final Map<? extends String, ? extends Object> map) {
+        final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
+        final boolean globalChanged = (oldGlobal != global);
+        final boolean strict = sobj.isStrictContext();
+        inGlobal(new Callable<Object>() {
+            @Override public Object call() {
+                for (final Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
+                    final Object value = entry.getValue();
+                    final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
+                    sobj.set(entry.getKey(), unwrap(modValue, global), strict);
+                }
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public Object remove(final Object key) {
+        return inGlobal(new Callable<Object>() {
+            @Override public Object call() {
+                return wrap(sobj.remove(unwrap(key, global)), global);
+            }
+        });
+    }
+
+    @Override
+    public int size() {
+        return inGlobal(new Callable<Integer>() {
+            @Override public Integer call() {
+                return sobj.size();
+            }
+        });
+    }
+
+    @Override
+    public Collection<Object> values() {
+        return inGlobal(new Callable<Collection<Object>>() {
+            @Override public Collection<Object> call() {
+                final List<Object>     values = new ArrayList<>(size());
+                final Iterator<Object> iter   = sobj.valueIterator();
+
+                while (iter.hasNext()) {
+                    values.add(translateUndefined(wrap(iter.next(), global)));
+                }
+
+                return Collections.unmodifiableList(values);
+            }
+        });
+    }
+
+    // package-privates below this.
+    ScriptObject getScriptObject() {
+        return sobj;
+    }
+
+    static Object translateUndefined(Object obj) {
+        return (obj == ScriptRuntime.UNDEFINED)? null : obj;
+    }
+
+    static Object wrap(final Object obj, final ScriptObject homeGlobal) {
+        return (obj instanceof ScriptObject) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj;
+    }
+
+    static Object unwrap(final Object obj, final ScriptObject homeGlobal) {
+        if (obj instanceof ScriptObjectMirror) {
+            final ScriptObjectMirror mirror = (ScriptObjectMirror)obj;
+            return (mirror.global == homeGlobal)? mirror.sobj : obj;
+        }
+
+        return obj;
+    }
+
+    static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) {
+        if (args == null || args.length == 0) {
+            return args;
+        }
+
+        final Object[] newArgs = new Object[args.length];
+        int index = 0;
+        for (final Object obj : args) {
+            newArgs[index] = wrap(obj, homeGlobal);
+            index++;
+        }
+        return newArgs;
+    }
+
+    static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) {
+        if (args == null || args.length == 0) {
+            return args;
+        }
+
+        final Object[] newArgs = new Object[args.length];
+        int index = 0;
+        for (final Object obj : args) {
+            newArgs[index] = unwrap(obj, homeGlobal);
+            index++;
+        }
+        return newArgs;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/api/scripting/URLReader.java b/nashorn/src/jdk/nashorn/api/scripting/URLReader.java
new file mode 100644
index 0000000..d21d626
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/api/scripting/URLReader.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+
+/**
+ * A Reader that reads from a URL. Used to make sure that the reader
+ * reads content from given URL and can be trusted to do so.
+ */
+public final class URLReader extends Reader {
+    // underlying URL
+    private URL url;
+    // lazily initialized underlying reader for URL
+    private Reader reader;
+
+    /**
+     * Constructor
+     *
+     * @param url URL for this URLReader
+     */
+    public URLReader(final URL url) {
+        this.url = url;
+    }
+
+    @Override
+    public int read(char cbuf[], int off, int len) throws IOException {
+        return getReader().read(cbuf, off, len);
+    }
+
+    @Override
+    public void close() throws IOException {
+        getReader().close();
+    }
+
+    /**
+     * URL of this reader
+     * @return the URL from which this reader reads.
+     */
+    public URL getURL() {
+        return url;
+    }
+
+    // lazily initialize char array reader using URL content
+    private Reader getReader() throws IOException {
+        synchronized (lock) {
+            if (reader == null) {
+                reader = new InputStreamReader(url.openStream());
+            }
+        }
+
+        return reader;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/api/scripting/package-info.java b/nashorn/src/jdk/nashorn/api/scripting/package-info.java
new file mode 100644
index 0000000..6876151
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/api/scripting/package-info.java
@@ -0,0 +1,38 @@
+/*
+ * 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 package provides the {@code javax.script} integration, which is the preferred way to use Nashorn.
+ * You will ordinarily do this to obtain an instance of a Nashorn script engine:
+ * <pre>
+ * import javax.script.*;
+ * ...
+ * ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("Nashorn");
+ * </pre>
+ * <p>Nashorn script engines implement the optional {@link javax.script.Invocable} and {@link javax.script.Compilable}
+ * interfaces, allowing for efficient pre-compilation and repeated execution of scripts. See
+ * {@link jdk.nashorn.api.scripting.NashornScriptEngineFactory} for further details.
+ */
+package jdk.nashorn.api.scripting;
diff --git a/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js
new file mode 100644
index 0000000..65b82df
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * This script file is executed by script engine at the construction
+ * of the engine. The functions here assume global variables "context"
+ * of type javax.script.ScriptContext and "engine" of the type
+ * jdk.nashorn.api.scripting.NashornScriptEngine.
+ *
+ **/
+
+Object.defineProperty(this, "__noSuchProperty__", {
+    configurable: true,
+    enumerable: false,
+    writable: true,
+    value: function (name) {
+        'use strict';
+        return engine.__noSuchProperty__(this, context, name);
+    }
+});
+
+function print(str) {
+    var writer = context.getWriter();
+    if (! (writer instanceof java.io.PrintWriter)) {
+        writer = new java.io.PrintWriter(writer);
+    }
+    writer.println(String(str));
+}
diff --git a/nashorn/src/jdk/nashorn/api/scripting/resources/init.js b/nashorn/src/jdk/nashorn/api/scripting/resources/init.js
new file mode 100644
index 0000000..18cde92
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/api/scripting/resources/init.js
@@ -0,0 +1,939 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/**
+ * jrunscript JavaScript built-in functions and objects.
+ */
+
+/**
+ * Creates an object that delegates all method calls on
+ * it to the 'invoke' method on the given delegate object.<br>
+ *
+ * Example:
+ * <pre>
+ * <code>
+ *     var x  = { invoke: function(name, args) { //code...}
+ *     var y = new JSInvoker(x);
+ *     y.func(3, 3); // calls x.invoke('func', args); where args is array of arguments
+ * </code>
+ * </pre>
+ * @param obj object to be wrapped by JSInvoker
+ * @constructor
+ */
+function JSInvoker(obj) {
+    return new JSAdapter({
+        __get__ : function(name) {
+            return function() {
+                return obj.invoke(name, arguments);
+            }
+        }
+    });
+}
+
+/**
+ * This variable represents OS environment. Environment
+ * variables can be accessed as fields of this object. For
+ * example, env.PATH will return PATH value configured.
+ */
+var env = new JSAdapter({
+    __get__ : function (name) {
+        return java.lang.System.getenv(name);
+    },
+    __has__ : function (name) {
+        return java.lang.System.getenv().containsKey(name);
+    },
+    __getIds__ : function() {
+        return java.lang.System.getenv().keySet().toArray();
+    },
+    __delete__ : function(name) {
+        println("can't delete env item");
+    },
+    __put__ : function (name, value) {
+        println("can't change env item");
+    },
+    toString: function() {
+        return java.lang.System.getenv().toString();
+    }
+});
+
+/**
+ * Creates a convenient script object to deal with java.util.Map instances.
+ * The result script object's field names are keys of the Map. For example,
+ * scriptObj.keyName can be used to access value associated with given key.<br>
+ * Example:
+ * <pre>
+ * <code>
+ *     var x = java.lang.SystemProperties();
+ *     var y = jmap(x);
+ *     println(y['java.class.path']); // prints java.class.path System property
+ *     delete y['java.class.path']; // remove java.class.path System property
+ * </code>
+ * </pre>
+ *
+ * @param map java.util.Map instance that will be wrapped
+ * @constructor
+ */
+function jmap(map) {
+    return new JSAdapter({
+        __get__ : function(name) {
+            if (map.containsKey(name)) {
+                return map.get(name);
+            } else {
+                return undefined;
+            }
+        },
+        __has__ :  function(name) {
+            return map.containsKey(name);
+        },
+
+        __delete__ : function (name) {
+            return map.remove(name);
+        },
+        __put__ : function(name, value) {
+            map.put(name, value);
+        },
+        __getIds__ : function() {
+            return map.keySet().toArray();
+        },
+        toString: function() {
+            return map.toString();
+        }
+    });
+}
+
+/**
+ * Creates a convenient script object to deal with java.util.List instances.
+ * The result script object behaves like an array. For example,
+ * scriptObj[index] syntax can be used to access values in the List instance.
+ * 'length' field gives size of the List. <br>
+ *
+ * Example:
+ * <pre>
+ * <code>
+ *    var x = new java.util.ArrayList(4);
+ *    x.add('Java');
+ *    x.add('JavaScript');
+ *    x.add('SQL');
+ *    x.add('XML');
+ *
+ *    var y = jlist(x);
+ *    println(y[2]); // prints third element of list
+ *    println(y.length); // prints size of the list
+ *
+ * @param map java.util.List instance that will be wrapped
+ * @constructor
+ */
+function jlist(list) {
+    function isValid(index) {
+        return typeof(index) == 'number' &&
+            index > -1 && index < list.size();
+    }
+    return new JSAdapter({
+        __get__ :  function(name) {
+            if (isValid(name)) {
+                return list.get(name);
+            } else if (name == 'length') {
+                return list.size();
+            } else {
+                return undefined;
+            }
+        },
+        __has__ : function (name) {
+            return isValid(name) || name == 'length';
+        },
+        __delete__ : function(name) {
+            if (isValid(name)) {
+                list.remove(name);
+            }
+        },
+        __put__ : function(name, value) {
+            if (isValid(name)) {
+                list.set(name, value);
+            }
+        },
+        __getIds__: function() {
+            var res = new Array(list.size());
+            for (var i = 0; i < res.length; i++) {
+                res[i] = i;
+            }
+            return res;
+        },
+        toString: function() {
+            return list.toString();
+        }
+    });
+}
+
+/**
+ * This is java.lang.System properties wrapped by JSAdapter.
+ * For eg. to access java.class.path property, you can use
+ * the syntax sysProps["java.class.path"]
+ */
+var sysProps = new JSAdapter({
+    __get__ : function (name) {
+        return java.lang.System.getProperty(name);
+    },
+    __has__ : function (name) {
+        return java.lang.System.getProperty(name) != null;
+    },
+    __getIds__ : function() {
+        return java.lang.System.getProperties().keySet().toArray();
+    },
+    __delete__ : function(name) {
+        java.lang.System.clearProperty(name);
+        return true;
+    },
+    __put__ : function (name, value) {
+        java.lang.System.setProperty(name, value);
+    },
+    toString: function() {
+        return "<system properties>";
+    }
+});
+
+// stdout, stderr & stdin
+var out = java.lang.System.out;
+var err = java.lang.System.err;
+// can't use 'in' because it is a JavaScript keyword :-(
+var inp = java.lang.System["in"];
+
+var BufferedInputStream = java.io.BufferedInputStream;
+var BufferedOutputStream = java.io.BufferedOutputStream;
+var BufferedReader = java.io.BufferedReader;
+var DataInputStream = java.io.DataInputStream;
+var File = java.io.File;
+var FileInputStream = java.io.FileInputStream;
+var FileOutputStream = java.io.FileOutputStream;
+var InputStream = java.io.InputStream;
+var InputStreamReader = java.io.InputStreamReader;
+var OutputStream = java.io.OutputStream;
+var Reader = java.io.Reader;
+var URL = java.net.URL;
+
+/**
+ * Generic any object to input stream mapper
+ * @param str input file name, URL or InputStream
+ * @return InputStream object
+ * @private
+ */
+function inStream(str) {
+    if (typeof(str) == "string") {
+        // '-' means standard input
+        if (str == '-') {
+            return java.lang.System["in"];
+        }
+        // try file first
+        var file = null;
+        try {
+            file = pathToFile(str);
+        } catch (e) {
+        }
+        if (file && file.exists()) {
+            return new FileInputStream(file);
+        } else {
+            try {
+                // treat the string as URL
+                return new URL(str).openStream();
+            } catch (e) {
+                throw 'file or URL ' + str + ' not found';
+            }
+        }
+    } else {
+        if (str instanceof InputStream) {
+            return str;
+        } else if (str instanceof URL) {
+            return str.openStream();
+        } else if (str instanceof File) {
+            return new FileInputStream(str);
+        }
+    }
+    // everything failed, just give input stream
+    return java.lang.System["in"];
+}
+
+/**
+ * Generic any object to output stream mapper
+ *
+ * @param out output file name or stream
+ * @return OutputStream object
+ * @private
+ */
+function outStream(out) {
+    if (typeof(out) == "string") {
+        if (out == '>') {
+            return java.lang.System.out;
+        } else {
+            // treat it as file
+            return new FileOutputStream(pathToFile(out));
+        }
+    } else {
+        if (out instanceof OutputStream) {
+            return out;
+        } else if (out instanceof File) {
+            return new FileOutputStream(out);
+        }
+    }
+
+    // everything failed, just return System.out
+    return java.lang.System.out;
+}
+
+/**
+ * stream close takes care not to close stdin, out & err.
+ * @private
+ */
+function streamClose(stream) {
+    if (stream) {
+        if (stream != java.lang.System["in"] &&
+            stream != java.lang.System.out &&
+            stream != java.lang.System.err) {
+            try {
+                stream.close();
+            } catch (e) {
+                println(e);
+            }
+        }
+    }
+}
+
+/**
+ * Loads and evaluates JavaScript code from a stream or file or URL<br>
+ *
+ * Examples:
+ * <pre>
+ * <code>
+ *    load('test.js'); // load script file 'test.js'
+ *    load('http://java.sun.com/foo.js'); // load from a URL
+ * </code>
+ * </pre>
+ *
+ * @param str input from which script is loaded and evaluated
+ */
+if (typeof(load) == 'undefined') {
+    var load = function(str) {
+        var stream = inStream(str);
+        var bstream = new BufferedInputStream(stream);
+        var reader = new BufferedReader(new InputStreamReader(bstream));
+        var oldFilename = engine.get(engine.FILENAME);
+        engine.put(engine.FILENAME, str);
+        try {
+            engine.eval(reader);
+        } finally {
+            engine.put(engine.FILENAME, oldFilename);
+            streamClose(stream);
+        }
+    }
+}
+
+// file system utilities
+
+/**
+ * Creates a Java byte[] of given length
+ * @param len size of the array to create
+ * @private
+ */
+function javaByteArray(len) {
+    return java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, len);
+}
+
+var curDir = new File('.');
+
+/**
+ * Print present working directory
+ */
+function pwd() {
+    println(curDir.getAbsolutePath());
+}
+
+/**
+ * Changes present working directory to given directory
+ * @param target directory to change to. optional, defaults to user's HOME
+ */
+function cd(target) {
+    if (target == undefined) {
+        target = sysProps["user.home"];
+    }
+    if (!(target instanceof File)) {
+        target = pathToFile(target);
+    }
+    if (target.exists() && target.isDirectory()) {
+        curDir = target;
+    } else {
+        println(target + " is not a directory");
+    }
+}
+
+/**
+ * Converts path to java.io.File taking care of shell present working dir
+ *
+ * @param pathname file path to be converted
+ * @private
+ */
+function pathToFile(pathname) {
+    var tmp = pathname;
+    if (!(tmp instanceof File)) {
+        tmp = new File(tmp);
+    }
+    if (!tmp.isAbsolute()) {
+        return new File(curDir, pathname);
+    } else {
+        return tmp;
+    }
+}
+
+/**
+ * Copies a file or URL or stream to another file or stream
+ *
+ * @param from input file or URL or stream
+ * @param to output stream or file
+ */
+function cp(from, to) {
+    if (from == to) {
+        println("file " + from + " cannot be copied onto itself!");
+        return;
+    }
+    var inp = inStream(from);
+    var out = outStream(to);
+    var binp = new BufferedInputStream(inp);
+    var bout = new BufferedOutputStream(out);
+    var buff = javaByteArray(1024);
+    var len;
+    while ((len = binp.read(buff)) > 0 )
+        bout.write(buff, 0, len);
+
+    bout.flush();
+    streamClose(inp);
+    streamClose(out);
+}
+
+/**
+ * Shows the content of a file or URL or any InputStream<br>
+ * Examples:
+ * <pre>
+ * <code>
+ *    cat('test.txt'); // show test.txt file contents
+ *    cat('http://java.net'); // show the contents from the URL http://java.net
+ * </code>
+ * </pre>
+ * @param obj input to show
+ * @param pattern optional. show only the lines matching the pattern
+ */
+function cat(obj, pattern) {
+    if (obj instanceof File && obj.isDirectory()) {
+        ls(obj);
+        return;
+    }
+
+    var inp = null;
+    if (!(obj instanceof Reader)) {
+        inp = inStream(obj);
+        obj = new BufferedReader(new InputStreamReader(inp));
+    }
+    var line;
+    if (pattern) {
+        var count = 1;
+        while ((line=obj.readLine()) != null) {
+            if (line.match(pattern)) {
+                println(count + "\t: " + line);
+            }
+            count++;
+        }
+    } else {
+        while ((line=obj.readLine()) != null) {
+            println(line);
+        }
+    }
+}
+
+/**
+ * Returns directory part of a filename
+ *
+ * @param pathname input path name
+ * @return directory part of the given file name
+ */
+function dirname(pathname) {
+    var dirName = ".";
+    // Normalize '/' to local file separator before work.
+    var i = pathname.replace('/', File.separatorChar ).lastIndexOf(
+        File.separator );
+    if ( i != -1 )
+        dirName = pathname.substring(0, i);
+    return dirName;
+}
+
+/**
+ * Creates a new dir of given name
+ *
+ * @param dir name of the new directory
+ */
+function mkdir(dir) {
+    dir = pathToFile(dir);
+    println(dir.mkdir()? "created" : "can not create dir");
+}
+
+/**
+ * Creates the directory named by given pathname, including
+ * any necessary but nonexistent parent directories.
+ *
+ * @param dir input path name
+ */
+function mkdirs(dir) {
+    dir = pathToFile(dir);
+    println(dir.mkdirs()? "created" : "can not create dirs");
+}
+
+/**
+ * Removes a given file
+ *
+ * @param pathname name of the file
+ */
+function rm(pathname) {
+    var file = pathToFile(pathname);
+    if (!file.exists()) {
+        println("file not found: " + pathname);
+        return false;
+    }
+    // note that delete is a keyword in JavaScript!
+    println(file["delete"]()? "deleted" : "can not delete");
+}
+
+/**
+ * Removes a given directory
+ *
+ * @param pathname name of the directory
+ */
+function rmdir(pathname) {
+    rm(pathname);
+}
+
+/**
+ * Synonym for 'rm'
+ */
+function del(pathname) {
+    rm(pathname);
+}
+
+/**
+ * Moves a file to another
+ *
+ * @param from original name of the file
+ * @param to new name for the file
+ */
+function mv(from, to) {
+    println(pathToFile(from).renameTo(pathToFile(to))?
+        "moved" : "can not move");
+}
+
+/**
+ * Synonym for 'mv'.
+ */
+function ren(from, to) {
+    mv(from, to);
+}
+
+var months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
+
+/**
+ * Helper function called by ls
+ * @private
+ */
+function printFile(f) {
+    var sb = new java.lang.StringBuffer();
+    sb.append(f.isDirectory()? "d" : "-");
+    sb.append(f.canRead() ? "r": "-" );
+    sb.append(f.canWrite() ? "w": "-" );
+    sb.append(" ");
+
+    var d = new java.util.Date(f.lastModified());
+    var c = new java.util.GregorianCalendar();
+    c.setTime(d);
+    var day    = c.get(java.util.Calendar.DAY_OF_MONTH);
+    sb.append(months[c.get(java.util.Calendar.MONTH)]
+         + " " + day );
+    if (day < 10) {
+        sb.append(" ");
+    }
+
+    // to get fixed length 'length' field
+    var fieldlen = 8;
+    var len = new java.lang.StringBuffer();
+    for(var j=0; j<fieldlen; j++)
+        len.append(" ");
+    len.insert(0, java.lang.Long.toString(f.length()));
+    len.setLength(fieldlen);
+    // move the spaces to the front
+    var si = len.toString().indexOf(" ");
+    if ( si != -1 ) {
+        var pad = len.toString().substring(si);
+        len.setLength(si);
+        len.insert(0, pad);
+    }
+    sb.append(len.toString());
+    sb.append(" ");
+    sb.append(f.getName());
+    if (f.isDirectory()) {
+        sb.append('/');
+    }
+    println(sb.toString());
+}
+
+/**
+ * Lists the files in a directory
+ *
+ * @param dir directory from which to list the files. optional, default to pwd
+ * @param filter pattern to filter the files listed. optional, default is '.'.
+ */
+function ls(dir, filter) {
+    if (dir) {
+        dir = pathToFile(dir);
+    } else {
+        dir = curDir;
+    }
+    if (dir.isDirectory()) {
+        var files = dir.listFiles();
+        for (var i in files) {
+            var f = files[i];
+            if (filter) {
+                if(!f.getName().match(filter)) {
+                    continue;
+                }
+            }
+            printFile(f);
+        }
+    } else {
+        printFile(dir);
+    }
+}
+
+/**
+ * Synonym for 'ls'.
+ */
+function dir(d, filter) {
+    ls(d, filter);
+}
+
+/**
+ * Unix-like grep, but accepts JavaScript regex patterns
+ *
+ * @param pattern to search in files
+ * @param files one or more files
+ */
+function grep(pattern, files /*, one or more files */) {
+    if (arguments.length < 2) return;
+    for (var i = 1; i < arguments.length; i++) {
+        println(arguments[i] + ":");
+        cat(arguments[i], pattern);
+    }
+}
+
+/**
+ * Find in files. Calls arbitrary callback function
+ * for each matching file.<br>
+ *
+ * Examples:
+ * <pre>
+ * <code>
+ *    find('.')
+ *    find('.', '.*\.class', rm);  // remove all .class files
+ *    find('.', '.*\.java');       // print fullpath of each .java file
+ *    find('.', '.*\.java', cat);  // print all .java files
+ * </code>
+ * </pre>
+ *
+ * @param dir directory to search files
+ * @param pattern to search in the files
+ * @param callback function to call for matching files
+ */
+function find(dir, pattern, callback) {
+    dir = pathToFile(dir);
+    if (!callback) callback = print;
+    var files = dir.listFiles();
+    for (var f in files) {
+        var file = files[f];
+        if (file.isDirectory()) {
+            find(file, pattern, callback);
+        } else {
+            if (pattern) {
+                if (file.getName().match(pattern)) {
+                    callback(file);
+                }
+            } else {
+                callback(file);
+            }
+        }
+    }
+}
+
+// process utilities
+
+/**
+ * Exec's a child process, waits for completion &amp; returns exit code
+ *
+ * @param cmd command to execute in child process
+ */
+function exec(cmd) {
+    var process = java.lang.Runtime.getRuntime().exec(cmd);
+    var inp = new DataInputStream(process.getInputStream());
+    var line = null;
+    while ((line = inp.readLine()) != null) {
+        println(line);
+    }
+    process.waitFor();
+    $exit = process.exitValue();
+}
+
+// XML utilities
+
+/**
+ * Converts input to DOM Document object
+ *
+ * @param inp file or reader. optional, without this param,
+ * this function returns a new DOM Document.
+ * @return returns a DOM Document object
+ */
+function XMLDocument(inp) {
+    var factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
+    var builder = factory.newDocumentBuilder();
+    if (inp) {
+        if (typeof(inp) == "string") {
+            return builder.parse(pathToFile(inp));
+        } else {
+            return builder.parse(inp);
+        }
+    } else {
+        return builder.newDocument();
+    }
+}
+
+/**
+ * Converts arbitrary stream, file, URL to XMLSource
+ *
+ * @param inp input stream or file or URL
+ * @return XMLSource object
+ */
+function XMLSource(inp) {
+    if (inp instanceof javax.xml.transform.Source) {
+        return inp;
+    } else if (inp instanceof Packages.org.w3c.dom.Document) {
+        return new javax.xml.transform.dom.DOMSource(inp);
+    } else {
+        inp = new BufferedInputStream(inStream(inp));
+        return new javax.xml.transform.stream.StreamSource(inp);
+    }
+}
+
+/**
+ * Converts arbitrary stream, file to XMLResult
+ *
+ * @param inp output stream or file
+ * @return XMLResult object
+ */
+function XMLResult(out) {
+    if (out instanceof javax.xml.transform.Result) {
+        return out;
+    } else if (out instanceof Packages.org.w3c.dom.Document) {
+        return new javax.xml.transform.dom.DOMResult(out);
+    } else {
+        out = new BufferedOutputStream(outStream(out));
+        return new javax.xml.transform.stream.StreamResult(out);
+    }
+}
+
+/**
+ * Perform XSLT transform
+ *
+ * @param inp Input XML to transform (URL, File or InputStream)
+ * @param style XSL Stylesheet to be used (URL, File or InputStream). optional.
+ * @param out Output XML (File or OutputStream
+ */
+function XSLTransform(inp, style, out) {
+    switch (arguments.length) {
+    case 2:
+        inp = arguments[0];
+        out = arguments[1];
+        break;
+    case 3:
+        inp = arguments[0];
+        style = arguments[1];
+        out = arguments[2];
+        break;
+    default:
+        println("XSL tranform requires 2 or 3 arguments");
+        return;
+    }
+
+    var factory = javax.xml.transform.TransformerFactory.newInstance();
+    var transformer;
+    if (style) {
+        transformer = factory.newTransformer(XMLSource(style));
+    } else {
+        transformer = factory.newTransformer();
+    }
+    var source = XMLSource(inp);
+    var result = XMLResult(out);
+    transformer.transform(source, result);
+    if (source.getInputStream) {
+        streamClose(source.getInputStream());
+    }
+    if (result.getOutputStream) {
+        streamClose(result.getOutputStream());
+    }
+}
+
+// miscellaneous utilities
+
+/**
+ * Prints which command is selected from PATH
+ *
+ * @param cmd name of the command searched from PATH
+ */
+function which(cmd) {
+    var st = new java.util.StringTokenizer(env.PATH, File.pathSeparator);
+    while (st.hasMoreTokens()) {
+        var file = new File(st.nextToken(), cmd);
+        if (file.exists()) {
+            println(file.getAbsolutePath());
+            return;
+        }
+    }
+}
+
+/**
+ * Prints IP addresses of given domain name
+ *
+ * @param name domain name
+ */
+function ip(name) {
+    var addrs = InetAddress.getAllByName(name);
+    for (var i in addrs) {
+        println(addrs[i]);
+    }
+}
+
+/**
+ * Prints current date in current locale
+ */
+function date() {
+    println(new Date().toLocaleString());
+}
+
+/**
+ * Echoes the given string arguments
+ */
+function echo(x) {
+    for (var i = 0; i < arguments.length; i++) {
+        println(arguments[i]);
+    }
+}
+
+/**
+ * Reads one or more lines from stdin after printing prompt
+ *
+ * @param prompt optional, default is '>'
+ * @param multiline to tell whether to read single line or multiple lines
+ */
+function read(prompt, multiline) {
+    if (!prompt) {
+        prompt = '>';
+    }
+    var inp = java.lang.System["in"];
+    var reader = new BufferedReader(new InputStreamReader(inp));
+    if (multiline) {
+        var line = '';
+        while (true) {
+            java.lang.System.err.print(prompt);
+            java.lang.System.err.flush();
+            var tmp = reader.readLine();
+            if (tmp == '' || tmp == null) break;
+            line += tmp + '\n';
+        }
+        return line;
+    } else {
+        java.lang.System.err.print(prompt);
+        java.lang.System.err.flush();
+        return reader.readLine();
+    }
+}
+
+if (typeof(println) == 'undefined') {
+    var print = function(str, newline) {
+        if (typeof(str) == 'undefined') {
+            str = 'undefined';
+        } else if (str == null) {
+            str = 'null';
+        }
+
+        if (!(out instanceof java.io.PrintWriter)) {
+            out = new java.io.PrintWriter(out);
+        }
+
+        out.print(String(str));
+        if (newline) {
+            out.print('\n');
+        }
+        out.flush();
+    }
+
+    var println = function(str) {
+        print(str, true);
+    };
+}
+
+/**
+ * This is C-like printf
+ *
+ * @param format string to format the rest of the print items
+ * @param args variadic argument list
+ */
+function printf(format, args/*, more args*/) {
+    print(sprintf.apply(this, arguments));
+}
+
+/**
+ * This is C-like sprintf
+ *
+ * @param format string to format the rest of the print items
+ * @param args variadic argument list
+ */
+function sprintf(format, args/*, more args*/) {
+    var len = arguments.length - 1;
+    var array = [];
+
+    if (len < 0) {
+        return "";
+    }
+
+    for (var i = 0; i < len; i++) {
+        if (arguments[i+1] instanceof Date) {
+            array[i] = arguments[i+1].getTime();
+        } else {
+            array[i] = arguments[i+1];
+        }
+    }
+
+    array = Java.toJavaArray(array);
+    return Packages.jdk.nashorn.api.scripting.Formatter.format(format, array);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
new file mode 100644
index 0000000..211140e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
@@ -0,0 +1,1609 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SCRIPT_RETURN;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SWITCH_TAG_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
+import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL;
+import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
+import static jdk.nashorn.internal.ir.Symbol.IS_LET;
+import static jdk.nashorn.internal.ir.Symbol.IS_PARAM;
+import static jdk.nashorn.internal.ir.Symbol.IS_THIS;
+import static jdk.nashorn.internal.ir.Symbol.IS_VAR;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.CallNode.EvalArgs;
+import jdk.nashorn.internal.ir.CaseNode;
+import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.IndexNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
+import jdk.nashorn.internal.ir.PropertyNode;
+import jdk.nashorn.internal.ir.ReferenceNode;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.RuntimeNode.Request;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.ir.TernaryNode;
+import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.Debug;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.ECMAException;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * This is the attribution pass of the code generator. Attr takes Lowered IR,
+ * that is, IR where control flow has been computed and high level to low level
+ * substitions for operations have been performed.
+ *
+ * After Attr, every symbol will have a conservative correct type.
+ *
+ * Any expression that requires temporary storage as part of computation will
+ * also be detected here and give a temporary symbol
+ *
+ * Types can be narrowed after Attr by Access Specialization in FinalizeTypes,
+ * but in general, this is where the main symbol type information is
+ * computed.
+ */
+
+final class Attr extends NodeOperatorVisitor {
+    /**
+     * Local definitions in current block (to discriminate from function
+     * declarations always defined in the function scope. This is for
+     * "can be undefined" analysis.
+     */
+    private Set<String> localDefs;
+
+    /**
+     * Local definitions in current block to guard against cases like
+     * NASHORN-467 when things can be undefined as they are used before
+     * their local var definition. *sigh* JavaScript...
+     */
+    private Set<String> localUses;
+
+    private static final DebugLogger LOG   = new DebugLogger("attr");
+    private static final boolean     DEBUG = LOG.isEnabled();
+
+    /**
+     * Constructor.
+     */
+    Attr() {
+    }
+
+    @Override
+    protected Node enterDefault(final Node node) {
+        return start(node);
+    }
+
+    @Override
+    protected Node leaveDefault(final Node node) {
+        return end(node);
+    }
+
+    @Override
+    public Node leave(final AccessNode accessNode) {
+        newTemporary(Type.OBJECT, accessNode);  //While Object type is assigned here, Access Specialization in FinalizeTypes may narrow this
+        end(accessNode);
+        return accessNode;
+    }
+
+    @Override
+    public Node enter(final Block block) {
+        start(block);
+
+        final Set<String> savedLocalDefs = localDefs;
+        final Set<String> savedLocalUses = localUses;
+
+        block.setFrame(getCurrentFunctionNode().pushFrame());
+
+        try {
+            // a block starts out by copying the local defs and local uses
+            // from the outer level. But we need the copies, as when we
+            // leave the block the def and use sets given upon entry must
+            // be restored
+            localDefs = new HashSet<>(savedLocalDefs);
+            localUses = new HashSet<>(savedLocalUses);
+
+            for (final Node statement : block.getStatements()) {
+                statement.accept(this);
+            }
+        } finally {
+            localDefs = savedLocalDefs;
+            localUses = savedLocalUses;
+
+            getCurrentFunctionNode().popFrame();
+        }
+
+        end(block);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final CallNode callNode) {
+        start(callNode);
+
+        callNode.getFunction().accept(this);
+
+        final List<Node> acceptedArgs = new ArrayList<>(callNode.getArgs().size());
+        for (final Node arg : callNode.getArgs()) {
+            LOG.info("Doing call arg " + arg);
+            acceptedArgs.add(arg.accept(this));
+        }
+        callNode.setArgs(acceptedArgs);
+
+        final EvalArgs evalArgs = callNode.getEvalArgs();
+        if (evalArgs != null) {
+            evalArgs.setCode(evalArgs.getCode().accept(this));
+
+            final IdentNode thisNode = new IdentNode(getCurrentFunctionNode().getThisNode());
+            assert thisNode.getSymbol() != null; //should copy attributed symbol and that's it
+            evalArgs.setThis(thisNode);
+        }
+
+        newTemporary(Type.OBJECT, callNode); // object type here, access specialization in FinalizeTypes may narrow it later
+        newType(callNode.getFunction().getSymbol(), Type.OBJECT);
+
+        end(callNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final CatchNode catchNode) {
+        final IdentNode exception = catchNode.getException();
+        final Block     block     = getCurrentBlock();
+
+        start(catchNode);
+
+        // define block-local exception variable
+        final Symbol def = block.defineSymbol(exception.getName(), IS_VAR | IS_LET, exception);
+        newType(def, Type.OBJECT);
+        addLocalDef(exception.getName());
+
+        return catchNode;
+    }
+
+    @Override
+    public Node enter(final FunctionNode functionNode) {
+        start(functionNode, false);
+        if (functionNode.isLazy()) {
+            LOG.info("LAZY: " + functionNode.getName());
+            end(functionNode);
+            return null;
+        }
+
+        clearLocalDefs();
+        clearLocalUses();
+
+        functionNode.setFrame(functionNode.pushFrame());
+
+        initCallee(functionNode);
+        initThis(functionNode);
+        if (functionNode.isVarArg()) {
+            initVarArg(functionNode);
+        }
+
+        initParameters(functionNode);
+        initScope(functionNode);
+        initReturn(functionNode);
+
+        // Add all nested functions as symbols in this function
+        for (final FunctionNode nestedFunction : functionNode.getFunctions()) {
+            final IdentNode ident = nestedFunction.getIdent();
+            if (ident != null && nestedFunction.isStatement()) {
+                final Symbol functionSymbol = functionNode.defineSymbol(ident.getName(), IS_VAR, nestedFunction);
+                newType(functionSymbol, Type.typeFor(ScriptFunction.class));
+            }
+        }
+
+        if (functionNode.isScript()) {
+            initFromPropertyMap(functionNode);
+        }
+
+        // Add function name as local symbol
+        if (!functionNode.isStatement() && !functionNode.isAnonymous() && !functionNode.isScript()) {
+            final Symbol selfSymbol = functionNode.defineSymbol(functionNode.getIdent().getName(), IS_VAR, functionNode);
+            newType(selfSymbol, Type.OBJECT);
+            selfSymbol.setNode(functionNode);
+        }
+
+        /*
+         * This pushes all declarations (except for non-statements, i.e. for
+         * node temporaries) to the top of the function scope. This way we can
+         * get around problems like
+         *
+         * while (true) {
+         *   break;
+         *   if (true) {
+         *     var s;
+         *   }
+         * }
+         *
+         * to an arbitrary nesting depth.
+         *
+         * @see NASHORN-73
+         */
+
+        final List<Symbol> declaredSymbols = new ArrayList<>();
+        for (final VarNode decl : functionNode.getDeclarations()) {
+            final IdentNode ident = decl.getName();
+            // any declared symbols that aren't visited need to be typed as well, hence the list
+            declaredSymbols.add(functionNode.defineSymbol(ident.getName(), IS_VAR, new IdentNode(ident)));
+        }
+
+        // Every nested function needs a definition in the outer function with its name. Add these.
+        for (final FunctionNode nestedFunction : functionNode.getFunctions()) {
+            final VarNode varNode = nestedFunction.getFunctionVarNode();
+            if (varNode != null) {
+                varNode.accept(this);
+                assert varNode.isFunctionVarNode() : varNode + " should be function var node";
+            }
+        }
+
+        for (final Node statement : functionNode.getStatements()) {
+            if (statement instanceof VarNode && ((VarNode)statement).isFunctionVarNode()) {
+                continue; //var nodes have already been processed, skip or they will generate additional defs/uses and false "can be undefined"
+            }
+            statement.accept(this);
+        }
+
+        for (final FunctionNode nestedFunction : functionNode.getFunctions()) {
+            LOG.info("Going into nested function " + functionNode.getName() + " -> " + nestedFunction.getName());
+            nestedFunction.accept(this);
+        }
+
+        //unknown parameters are promoted to object type.
+        finalizeParameters(functionNode);
+        finalizeTypes(functionNode);
+        for (final Symbol symbol : declaredSymbols) {
+            if (symbol.getSymbolType().isUnknown()) {
+                symbol.setType(Type.OBJECT);
+                symbol.setCanBeUndefined();
+            }
+        }
+
+        if (functionNode.getReturnType().isUnknown()) {
+            LOG.info("Unknown return type promoted to object");
+            functionNode.setReturnType(Type.OBJECT);
+        }
+
+        if (functionNode.getSelfSymbolInit() != null) {
+            LOG.info("Accepting self symbol init " + functionNode.getSelfSymbolInit() + " for " + functionNode.getName());
+            final Node init = functionNode.getSelfSymbolInit();
+            final List<Node> newStatements = new ArrayList<>();
+            newStatements.add(init);
+            newStatements.addAll(functionNode.getStatements());
+            functionNode.setStatements(newStatements);
+            functionNode.setNeedsSelfSymbol(functionNode.getSelfSymbolInit().accept(this));
+        }
+
+        functionNode.popFrame();
+
+        end(functionNode, false);
+
+        return null;
+    }
+
+    @Override
+    public Node leaveCONVERT(final UnaryNode unaryNode) {
+        assert false : "There should be no convert operators in IR during Attribution";
+        end(unaryNode);
+        return unaryNode;
+    }
+
+    @Override
+    public Node enter(final IdentNode identNode) {
+        final String name = identNode.getName();
+
+        start(identNode);
+
+        if (identNode.isPropertyName()) {
+            // assign a pseudo symbol to property name
+            final Symbol pseudoSymbol = pseudoSymbol(name);
+            LOG.info("IdentNode is property name -> assigning pseudo symbol " + pseudoSymbol);
+            LOG.unindent();
+            identNode.setSymbol(pseudoSymbol);
+            return null;
+        }
+
+        final Block  block     = getCurrentBlock();
+        final Symbol oldSymbol = identNode.getSymbol();
+
+        Symbol symbol = block.findSymbol(name);
+
+        //If an existing symbol with the name is found, use that otherwise, declare a new one
+        if (symbol != null) {
+            LOG.info("Existing symbol = " + symbol);
+            if (isFunctionExpressionSelfReference(symbol)) {
+                final FunctionNode functionNode = (FunctionNode)symbol.getNode();
+                assert functionNode.getCalleeNode() != null;
+
+                final VarNode var = new VarNode(functionNode.getSource(), functionNode.getToken(), functionNode.getFinish(), functionNode.getIdent(), functionNode.getCalleeNode());
+                //newTemporary(Type.OBJECT, var); //ScriptFunction? TODO
+
+                functionNode.setNeedsSelfSymbol(var);
+            }
+
+            if (!identNode.isInitializedHere()) { // NASHORN-448
+                // here is a use outside the local def scope
+                if (!isLocalDef(name)) {
+                    newType(symbol, Type.OBJECT);
+                    symbol.setCanBeUndefined();
+                }
+            }
+
+            identNode.setSymbol(symbol);
+            if (!getCurrentFunctionNode().isLocal(symbol)) {
+                // non-local: we need to put symbol in scope (if it isn't already)
+                if (!symbol.isScope()) {
+                    final List<Block> lookupBlocks = findLookupBlocksHelper(getCurrentFunctionNode(), symbol.findFunction());
+                    for (final Block lookupBlock : lookupBlocks) {
+                        final Symbol refSymbol = lookupBlock.findSymbol(name);
+                        if (refSymbol != null) { // See NASHORN-837, function declaration in lexical scope: try {} catch (x){ function f() { use(x) } } f()
+                            LOG.finest("Found a ref symbol that must be scope " + refSymbol);
+                            refSymbol.setIsScope();
+                        }
+                    }
+                }
+            }
+        } else {
+            LOG.info("No symbol exists. Declare undefined: " + symbol);
+            symbol = block.useSymbol(name, identNode);
+            // we have never seen this before, it can be undefined
+            newType(symbol, Type.OBJECT); // TODO unknown -we have explicit casts anyway?
+            symbol.setCanBeUndefined();
+            symbol.setIsScope();
+        }
+
+        assert symbol != null;
+        if(symbol.isGlobal()) {
+            getCurrentFunctionNode().setUsesGlobalSymbol();
+        } else if(symbol.isScope()) {
+            getCurrentFunctionNode().setUsesScopeSymbol(symbol);
+        }
+
+        if (symbol != oldSymbol && !identNode.isInitializedHere()) {
+            symbol.increaseUseCount();
+        }
+        addLocalUse(identNode.getName());
+
+        end(identNode);
+
+        return null;
+    }
+
+    @Override
+    public Node leave(final IndexNode indexNode) {
+        newTemporary(Type.OBJECT, indexNode); //TORO
+        return indexNode;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Node enter(final LiteralNode literalNode) {
+        try {
+            start(literalNode);
+            assert !literalNode.isTokenType(TokenType.THIS) : "tokentype for " + literalNode + " is this"; //guard against old dead code case. literal nodes should never inherit tokens
+
+            if (literalNode instanceof ArrayLiteralNode) {
+                final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode;
+                final Node[]           array            = arrayLiteralNode.getValue();
+
+                for (int i = 0; i < array.length; i++) {
+                    final Node element = array[i];
+                    if (element != null) {
+                        array[i] = element.accept(this);
+                    }
+                }
+                arrayLiteralNode.analyze();
+                //array literal node now has an element type and all elements are attributed
+            } else {
+                assert !(literalNode.getValue() instanceof Node) : "literals with Node values not supported";
+            }
+
+            getCurrentFunctionNode().newLiteral(literalNode);
+        } finally {
+            end(literalNode);
+        }
+        return null;
+    }
+
+    @Override
+    public Node leave(final ObjectNode objectNode) {
+        newTemporary(Type.OBJECT, objectNode);
+        end(objectNode);
+        return objectNode;
+    }
+
+    @Override
+    public Node enter(final PropertyNode propertyNode) {
+        // assign a pseudo symbol to property name, see NASHORN-710
+        propertyNode.setSymbol(new Symbol(propertyNode.getKeyName(), 0, Type.OBJECT));
+        end(propertyNode);
+        return propertyNode;
+    }
+
+    @Override
+    public Node enter(final ReferenceNode referenceNode) {
+        final FunctionNode functionNode = referenceNode.getReference();
+        if (functionNode != null) {
+            functionNode.addReferencingParentBlock(getCurrentBlock());
+        }
+        return referenceNode;
+    }
+
+    @Override
+    public Node leave(final ReferenceNode referenceNode) {
+        newTemporary(Type.OBJECT, referenceNode); //reference node type is always an object, i.e. the scriptFunction. the function return type varies though
+
+        final FunctionNode functionNode = referenceNode.getReference();
+        //assert !functionNode.getType().isUnknown() || functionNode.isLazy() : functionNode.getType();
+        if (functionNode.isLazy()) {
+            LOG.info("Lazy function node call reference: " + functionNode.getName() + " => Promoting to OBJECT");
+            functionNode.setReturnType(Type.OBJECT);
+        }
+        end(referenceNode);
+
+        return referenceNode;
+    }
+
+    @Override
+    public Node leave(final ReturnNode returnNode) {
+        final Node expr = returnNode.getExpression();
+
+        if (expr != null) {
+            //we can't do parameter specialization if we return something that hasn't been typed yet
+            final Symbol symbol = expr.getSymbol();
+            if (expr.getType().isUnknown() && symbol.isParam()) {
+                symbol.setType(Type.OBJECT);
+            }
+            getCurrentFunctionNode().setReturnType(Type.widest(getCurrentFunctionNode().getReturnType(), symbol.getSymbolType()));
+            LOG.info("Returntype is now " + getCurrentFunctionNode().getReturnType());
+        }
+
+        end(returnNode);
+
+        return returnNode;
+    }
+
+    @Override
+    public Node leave(final SwitchNode switchNode) {
+        Type type = Type.UNKNOWN;
+
+        for (final CaseNode caseNode : switchNode.getCases()) {
+            final Node test = caseNode.getTest();
+            if (test != null) {
+                if (test instanceof LiteralNode) {
+                    //go down to integers if we can
+                    final LiteralNode<?> lit = (LiteralNode<?>)test;
+                    if (lit.isNumeric() && !(lit.getValue() instanceof Integer)) {
+                        if (JSType.isRepresentableAsInt(lit.getNumber())) {
+                            caseNode.setTest(LiteralNode.newInstance(lit, lit.getInt32()).accept(this));
+                        }
+                    }
+                } else {
+                    // the "all integer" case that CodeGenerator optimizes for currently assumes literals only
+                    type = Type.OBJECT;
+                    break;
+                }
+
+                type = Type.widest(type, caseNode.getTest().getType());
+            }
+        }
+
+        //only optimize for all integers
+        if (!type.isInteger()) {
+            type = Type.OBJECT;
+        }
+
+        switchNode.setTag(newInternal(getCurrentFunctionNode().uniqueName(SWITCH_TAG_PREFIX.tag()), type));
+
+        end(switchNode);
+
+        return switchNode;
+    }
+
+    @Override
+    public Node leave(final TryNode tryNode) {
+        tryNode.setException(exceptionSymbol());
+
+        if (tryNode.getFinallyBody() != null) {
+            tryNode.setFinallyCatchAll(exceptionSymbol());
+        }
+
+        end(tryNode);
+
+        return tryNode;
+    }
+
+    @Override
+    public Node enter(final VarNode varNode) {
+        start(varNode);
+
+        final IdentNode ident = varNode.getName();
+        final String    name  = ident.getName();
+
+        final Symbol symbol = getCurrentBlock().defineSymbol(name, IS_VAR, ident);
+        assert symbol != null;
+
+        LOG.info("VarNode " + varNode + " set symbol " + symbol);
+        varNode.setSymbol(symbol);
+
+        // NASHORN-467 - use before definition of vars - conservative
+        if (localUses.contains(ident.getName())) {
+            newType(symbol, Type.OBJECT);
+            symbol.setCanBeUndefined();
+        }
+
+        if (varNode.getInit() != null) {
+            varNode.getInit().accept(this);
+        }
+
+        return varNode;
+    }
+
+    @Override
+    public Node leave(final VarNode varNode) {
+        final Node      init  = varNode.getInit();
+        final IdentNode ident = varNode.getName();
+        final String    name  = ident.getName();
+
+        if (init != null) {
+            addLocalDef(name);
+        }
+
+        if (init == null) {
+            // var x; with no init will be treated like a use of x by
+            // visit(IdentNode) unless we remove the name
+            // from the localdef list.
+            removeLocalDef(name);
+            return varNode;
+        }
+
+        final Symbol  symbol   = varNode.getSymbol();
+        final boolean isScript = symbol.getBlock().getFunction().isScript(); //see NASHORN-56
+        if ((init.getType().isNumeric() || init.getType().isBoolean()) && !isScript) {
+            // Forbid integers as local vars for now as we have no way to treat them as undefined
+            newType(symbol, init.getType());
+        } else {
+            newType(symbol, Type.OBJECT);
+        }
+
+        assert varNode.hasType() : varNode;
+
+        end(varNode);
+
+        return varNode;
+    }
+
+    @Override
+    public Node leaveADD(final UnaryNode unaryNode) {
+        newTemporary(arithType(), unaryNode);
+        end(unaryNode);
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveBIT_NOT(final UnaryNode unaryNode) {
+        newTemporary(Type.INT, unaryNode);
+        end(unaryNode);
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveDECINC(final UnaryNode unaryNode) {
+        // @see assignOffset
+        ensureAssignmentSlots(getCurrentFunctionNode(), unaryNode.rhs());
+        final Type type = arithType();
+        newType(unaryNode.rhs().getSymbol(), type);
+        newTemporary(type, unaryNode);
+        end(unaryNode);
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveDELETE(final UnaryNode unaryNode) {
+        final FunctionNode   currentFunctionNode = getCurrentFunctionNode();
+        final boolean        strictMode          = currentFunctionNode.isStrictMode();
+        final Node           rhs                 = unaryNode.rhs();
+        final Node           strictFlagNode      = LiteralNode.newInstance(unaryNode, strictMode).accept(this);
+
+        Request request = Request.DELETE;
+        final RuntimeNode runtimeNode;
+        final List<Node> args = new ArrayList<>();
+
+        if (rhs instanceof IdentNode) {
+            // If this is a declared variable or a function parameter, delete always fails (except for globals).
+            final String name = ((IdentNode)rhs).getName();
+
+            final boolean failDelete = strictMode || rhs.getSymbol().isParam() || (rhs.getSymbol().isVar() && !rhs.getSymbol().isTopLevel());
+
+            if (failDelete && rhs.getSymbol().isThis()) {
+                return LiteralNode.newInstance(unaryNode, true).accept(this);
+            }
+            final Node literalNode = LiteralNode.newInstance(unaryNode, name).accept(this);
+
+            if (!failDelete) {
+                args.add(currentFunctionNode.getScopeNode());
+            }
+            args.add(literalNode);
+            args.add(strictFlagNode);
+
+            if (failDelete) {
+                request = Request.FAIL_DELETE;
+            }
+        } else if (rhs instanceof AccessNode) {
+            final Node      base     = ((AccessNode)rhs).getBase();
+            final IdentNode property = ((AccessNode)rhs).getProperty();
+
+            args.add(base);
+            args.add(LiteralNode.newInstance(unaryNode, property.getName()).accept(this));
+            args.add(strictFlagNode);
+
+        } else if (rhs instanceof IndexNode) {
+            final Node base  = ((IndexNode)rhs).getBase();
+            final Node index = ((IndexNode)rhs).getIndex();
+
+            args.add(base);
+            args.add(index);
+            args.add(strictFlagNode);
+
+        } else {
+            return LiteralNode.newInstance(unaryNode, true).accept(this);
+        }
+
+        runtimeNode = new RuntimeNode(unaryNode, request, args);
+        assert runtimeNode.getSymbol() == unaryNode.getSymbol(); //clone constructor should do this
+
+        runtimeNode.accept(this);
+        return runtimeNode;
+    }
+
+
+    @Override
+    public Node leaveNEW(final UnaryNode unaryNode) {
+        newTemporary(Type.OBJECT, unaryNode);
+        end(unaryNode);
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveNOT(final UnaryNode unaryNode) {
+        newTemporary(Type.BOOLEAN, unaryNode);
+        end(unaryNode);
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveTYPEOF(final UnaryNode unaryNode) {
+        final Node rhs    = unaryNode.rhs();
+
+        RuntimeNode runtimeNode;
+
+        List<Node> args = new ArrayList<>();
+        if (rhs instanceof IdentNode && !rhs.getSymbol().isParam() && !rhs.getSymbol().isVar()) {
+            args.add(getCurrentFunctionNode().getScopeNode());
+            args.add(LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null
+        } else {
+            args.add(rhs);
+            args.add(LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this'
+        }
+
+        runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args);
+        assert runtimeNode.getSymbol() == unaryNode.getSymbol();
+
+        runtimeNode.accept(this);
+
+        end(unaryNode);
+
+        return runtimeNode;
+    }
+
+    @Override
+    public Node leave(final RuntimeNode runtimeNode) {
+        newTemporary(runtimeNode.getRequest().getReturnType(), runtimeNode);
+        return runtimeNode;
+    }
+
+    @Override
+    public Node leaveSUB(final UnaryNode unaryNode) {
+        newTemporary(arithType(), unaryNode);
+        end(unaryNode);
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveVOID(final UnaryNode unaryNode) {
+        final RuntimeNode runtimeNode = new RuntimeNode(unaryNode, Request.VOID);
+        runtimeNode.accept(this);
+        assert runtimeNode.getSymbol().getSymbolType().isObject();
+        end(unaryNode);
+        return runtimeNode;
+    }
+
+    /**
+     * Add is a special binary, as it works not only on arithmetic, but for
+     * strings etc as well.
+     */
+    @Override
+    public Node leaveADD(final BinaryNode binaryNode) {
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        ensureTypeNotUnknown(lhs);
+        ensureTypeNotUnknown(rhs);
+        newTemporary(Type.widest(lhs.getType(), rhs.getType()), binaryNode);
+
+        end(binaryNode);
+
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveAND(final BinaryNode binaryNode) {
+        newTemporary(Type.OBJECT, binaryNode);
+        end(binaryNode);
+        return binaryNode;
+    }
+
+    /**
+     * This is a helper called before an assignment.
+     * @param binaryNode assignment node
+     */
+    private Node enterAssignmentNode(final BinaryNode binaryNode) {
+        start(binaryNode);
+
+        final Node lhs = binaryNode.lhs();
+
+        if (lhs instanceof IdentNode) {
+            final Block     block = getCurrentBlock();
+            final IdentNode ident = (IdentNode)lhs;
+            final String    name  = ident.getName();
+
+            Symbol symbol = getCurrentBlock().findSymbol(name);
+
+            if (symbol == null) {
+                symbol = block.defineSymbol(name, IS_GLOBAL, ident);
+                binaryNode.setSymbol(symbol);
+            } else if (!getCurrentFunctionNode().isLocal(symbol)) {
+                symbol.setIsScope();
+            }
+
+            addLocalDef(name);
+        }
+
+        return binaryNode;
+    }
+
+    @Override
+    public Node enterASSIGN(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN(final BinaryNode binaryNode) {
+        return leaveAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_ADD(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_ADD(final BinaryNode binaryNode) {
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        final Type widest = Type.widest(lhs.getType(), rhs.getType());
+        //Type.NUMBER if we can't prove that the add doesn't overflow. todo
+        return leaveSelfModifyingAssignmentNode(binaryNode, widest.isNumeric() ? Type.NUMBER : Type.OBJECT);
+    }
+
+    @Override
+    public Node enterASSIGN_BIT_AND(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_BIT_AND(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_BIT_OR(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_BIT_OR(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_DIV(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_DIV(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_MOD(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_MOD(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_MUL(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_MUL(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_SAR(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SAR(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_SHL(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SHL(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_SHR(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SHR(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN_SUB(final BinaryNode binaryNode) {
+        return enterAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SUB(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode);
+    }
+
+    @Override
+    public Node leaveBIT_AND(final BinaryNode binaryNode) {
+        newTemporary(Type.INT, binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveBIT_OR(final BinaryNode binaryNode) {
+        newTemporary(Type.INT, binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveBIT_XOR(final BinaryNode binaryNode) {
+        newTemporary(Type.INT, binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveCOMMARIGHT(final BinaryNode binaryNode) {
+        newTemporary(binaryNode.rhs().getType(), binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
+        newTemporary(binaryNode.lhs().getType(), binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveDIV(final BinaryNode binaryNode) {
+        return leaveBinaryArithmetic(binaryNode);
+    }
+
+    private Node leaveCmp(final BinaryNode binaryNode, final RuntimeNode.Request request) {
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        newTemporary(Type.BOOLEAN, binaryNode);
+        ensureTypeNotUnknown(lhs);
+        ensureTypeNotUnknown(rhs);
+
+        end(binaryNode);
+        return binaryNode;
+    }
+
+    //leave a binary node and inherit the widest type of lhs , rhs
+    private Node leaveBinaryArithmetic(final BinaryNode binaryNode) {
+        if (!Compiler.shouldUseIntegerArithmetic()) {
+            newTemporary(Type.NUMBER, binaryNode);
+            return binaryNode;
+        }
+        newTemporary(Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType(), Type.NUMBER), binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveEQ(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.EQ);
+    }
+
+    @Override
+    public Node leaveEQ_STRICT(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.EQ_STRICT);
+    }
+
+    @Override
+    public Node leaveGE(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.GE);
+    }
+
+    @Override
+    public Node leaveGT(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.GT);
+    }
+
+    @Override
+    public Node leaveIN(final BinaryNode binaryNode) {
+        try {
+            return new RuntimeNode(binaryNode, Request.IN).accept(this);
+        } finally {
+            end(binaryNode);
+        }
+    }
+
+    @Override
+    public Node leaveINSTANCEOF(final BinaryNode binaryNode) {
+        try {
+            return new RuntimeNode(binaryNode, Request.INSTANCEOF).accept(this);
+        } finally {
+            end(binaryNode);
+        }
+    }
+
+    @Override
+    public Node leaveLE(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.LE);
+    }
+
+    @Override
+    public Node leaveLT(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.LT);
+    }
+
+    @Override
+    public Node leaveMOD(final BinaryNode binaryNode) {
+        return leaveBinaryArithmetic(binaryNode);
+    }
+
+    @Override
+    public Node leaveMUL(final BinaryNode binaryNode) {
+        return leaveBinaryArithmetic(binaryNode);
+    }
+
+    @Override
+    public Node leaveNE(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.NE);
+    }
+
+    @Override
+    public Node leaveNE_STRICT(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.NE_STRICT);
+    }
+
+    @Override
+    public Node leaveOR(final BinaryNode binaryNode) {
+        newTemporary(Type.OBJECT, binaryNode);
+        end(binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveSAR(final BinaryNode binaryNode) {
+        newTemporary(Type.INT, binaryNode);
+        end(binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveSHL(final BinaryNode binaryNode) {
+        newTemporary(Type.INT, binaryNode);
+        end(binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveSHR(final BinaryNode binaryNode) {
+        newTemporary(Type.LONG, binaryNode);
+        end(binaryNode);
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveSUB(final BinaryNode binaryNode) {
+        return leaveBinaryArithmetic(binaryNode);
+    }
+
+    @Override
+    public Node leave(final ForNode forNode) {
+        if (forNode.isForIn()) {
+            forNode.setIterator(newInternal(getCurrentFunctionNode(), getCurrentFunctionNode().uniqueName(ITERATOR_PREFIX.tag()), Type.OBJECT)); //NASHORN-73
+            /*
+             * Iterators return objects, so we need to widen the scope of the
+             * init variable if it, for example, has been assigned double type
+             * see NASHORN-50
+             */
+            newType(forNode.getInit().getSymbol(), Type.OBJECT);
+        }
+
+        end(forNode);
+
+        return forNode;
+    }
+
+    @Override
+    public Node leave(final TernaryNode ternaryNode) {
+        final Node lhs  = ternaryNode.rhs();
+        final Node rhs  = ternaryNode.third();
+
+        ensureTypeNotUnknown(lhs);
+        ensureTypeNotUnknown(rhs);
+
+        final Type type = Type.widest(lhs.getType(), rhs.getType());
+        newTemporary(type, ternaryNode);
+
+        end(ternaryNode);
+
+        return ternaryNode;
+    }
+
+    private static void initThis(final FunctionNode functionNode) {
+        final Symbol thisSymbol = functionNode.defineSymbol(THIS.tag(), IS_PARAM | IS_THIS, null);
+        newType(thisSymbol, Type.OBJECT);
+        thisSymbol.setNeedsSlot(true);
+        functionNode.getThisNode().setSymbol(thisSymbol);
+        LOG.info("Initialized scope symbol: " + thisSymbol);
+    }
+
+    private static void initScope(final FunctionNode functionNode) {
+        final Symbol scopeSymbol = functionNode.defineSymbol(SCOPE.tag(), IS_VAR | IS_INTERNAL, null);
+        newType(scopeSymbol, Type.typeFor(ScriptObject.class));
+        scopeSymbol.setNeedsSlot(true);
+        functionNode.getScopeNode().setSymbol(scopeSymbol);
+        LOG.info("Initialized scope symbol: " + scopeSymbol);
+    }
+
+    private static void initReturn(final FunctionNode functionNode) {
+        final Symbol returnSymbol = functionNode.defineSymbol(SCRIPT_RETURN.tag(), IS_VAR | IS_INTERNAL, null);
+        newType(returnSymbol, Type.OBJECT);
+        returnSymbol.setNeedsSlot(true);
+        functionNode.getResultNode().setSymbol(returnSymbol);
+        LOG.info("Initialized return symbol: " + returnSymbol);
+        //return symbol is always object as it's the __return__ thing. What returnType is is another matter though
+    }
+
+    private void initVarArg(final FunctionNode functionNode) {
+        if (functionNode.isVarArg()) {
+            final Symbol varArgsSymbol = functionNode.defineSymbol(VARARGS.tag(), IS_PARAM | IS_INTERNAL, null);
+            varArgsSymbol.setTypeOverride(Type.OBJECT_ARRAY);
+            varArgsSymbol.setNeedsSlot(true);
+            functionNode.getVarArgsNode().setSymbol(varArgsSymbol);
+            LOG.info("Initialized varargs symbol: " + varArgsSymbol);
+
+            if (functionNode.needsArguments()) {
+                final String    argumentsName   = functionNode.getArgumentsNode().getName();
+                final Symbol    argumentsSymbol = functionNode.defineSymbol(argumentsName, IS_VAR | IS_INTERNAL, null);
+                newType(argumentsSymbol, Type.typeFor(ScriptObject.class));
+                argumentsSymbol.setNeedsSlot(true);
+                functionNode.getArgumentsNode().setSymbol(argumentsSymbol);
+                addLocalDef(argumentsName);
+                LOG.info("Initialized vararg varArgsSymbol=" + varArgsSymbol + " argumentsSymbol=" + argumentsSymbol);
+            }
+        }
+    }
+
+    private static void initCallee(final FunctionNode functionNode) {
+        assert functionNode.getCalleeNode() != null : functionNode + " has no callee";
+        final Symbol calleeSymbol = functionNode.defineSymbol(CALLEE.tag(), IS_PARAM | IS_INTERNAL, null);
+        newType(calleeSymbol, Type.typeFor(ScriptFunction.class));
+        calleeSymbol.setNeedsSlot(true);
+        functionNode.getCalleeNode().setSymbol(calleeSymbol);
+        LOG.info("Initialized callee symbol " + calleeSymbol);
+    }
+
+    /**
+     * Initialize parameters for function node. This may require specializing
+     * types if a specialization profile is known
+     *
+     * @param functionNode the function node
+     */
+    private void initParameters(final FunctionNode functionNode) {
+        //If a function is specialized, we don't need to tag either it return
+        // type or its parameters with the widest (OBJECT) type for safety.
+        functionNode.setReturnType(Type.UNKNOWN);
+
+        for (final IdentNode ident : functionNode.getParameters()) {
+            addLocalDef(ident.getName());
+            final Symbol paramSymbol = functionNode.defineSymbol(ident.getName(), IS_PARAM, ident);
+            if (paramSymbol != null) {
+                newType(paramSymbol, Type.UNKNOWN);
+            }
+
+            LOG.info("Initialized param " + paramSymbol);
+        }
+    }
+
+    /**
+     * This has to run before fix assignment types, store any type specializations for
+     * paramters, then turn then to objects for the generic version of this method
+     *
+     * @param functionNode functionNode
+     */
+    private static void finalizeParameters(final FunctionNode functionNode) {
+        boolean nonObjectParams = false;
+        List<Type> paramSpecializations = new ArrayList<>();
+
+        for (final IdentNode ident : functionNode.getParameters()) {
+            final Symbol paramSymbol = ident.getSymbol();
+            if (paramSymbol != null) {
+                Type type = paramSymbol.getSymbolType();
+                if (type.isUnknown()) {
+                    type = Type.OBJECT;
+                }
+                paramSpecializations.add(type);
+                if (!type.isObject()) {
+                    nonObjectParams = true;
+                }
+                newType(paramSymbol, Type.OBJECT);
+            }
+        }
+
+        if (!nonObjectParams) {
+            paramSpecializations = null;
+            // Later, when resolving a call to this method, the linker can say "I have a double, an int and an object" as parameters
+            // here. If the callee has parameter specializations, we can regenerate it with those particular types for speed.
+        } else {
+            LOG.info("parameter specialization possible: " + functionNode.getName() + " " + paramSpecializations);
+        }
+
+        // parameters should not be slots for a function that uses variable arity signature
+        if (functionNode.isVarArg()) {
+            for (final IdentNode param : functionNode.getParameters()) {
+                param.getSymbol().setNeedsSlot(false);
+            }
+        }
+    }
+
+    /**
+     * Move any properties from a global map into the scope of this method
+     * @param functionNode the function node for which to init scope vars
+     */
+    private static void initFromPropertyMap(final FunctionNode functionNode) {
+        // For a script, add scope symbols as defined in the property map
+        assert functionNode.isScript();
+
+        final PropertyMap map = Context.getGlobalMap();
+
+        for (final Property property : map.getProperties()) {
+            final String key    = property.getKey();
+            final Symbol symbol = functionNode.defineSymbol(key, IS_GLOBAL, null);
+            newType(symbol, Type.OBJECT);
+            LOG.info("Added global symbol from property map " + symbol);
+        }
+    }
+
+    private static void ensureTypeNotUnknown(final Node node) {
+
+        final Symbol symbol = node.getSymbol();
+
+        LOG.info("Ensure type not unknown for: " + symbol);
+
+        /*
+         * Note that not just unknowns, but params need to be blown
+         * up to objects, because we can have something like
+         *
+         * function f(a) {
+         *    var b = ~a; //b and a are inferred to be int
+         *    return b;
+         * }
+         *
+         * In this case, it would be correct to say that "if you have
+         * an int at the callsite, just pass it".
+         *
+         * However
+         *
+         * function f(a) {
+         *    var b = ~a;      //b and a are inferred to be int
+         *    return b == 17;  //b is still inferred to be int.
+         * }
+         *
+         * can be called with f("17") and if we assume that b is an
+         * int and don't blow it up to an object in the comparison, we
+         * are screwed. I hate JavaScript.
+         *
+         * This check has to be done for any operation that might take
+         * objects as parameters, for example +, but not *, which is known
+         * to coerce types into doubles
+         */
+        if (node.getType().isUnknown() || symbol.isParam()) {
+            newType(symbol, Type.OBJECT);
+            symbol.setCanBeUndefined();
+         }
+    }
+
+    private static Symbol pseudoSymbol(final String name) {
+        return new Symbol(name, 0, Type.OBJECT);
+    }
+
+    private Symbol exceptionSymbol() {
+        return newInternal(getCurrentFunctionNode().uniqueName(EXCEPTION_PREFIX.tag()), Type.typeFor(ECMAException.class));
+    }
+
+    /**
+     * In an assignment, recursively make sure that there are slots for
+     * everything that has to be laid out as temporary storage, which is the
+     * case if we are assign-op:ing a BaseNode subclass. This has to be
+     * recursive to handle things like multi dimensional arrays as lhs
+     *
+     * see NASHORN-258
+     *
+     * @param functionNode   the current function node (has to be passed as it changes in the visitor below)
+     * @param assignmentDest the destination node of the assignment, e.g. lhs for binary nodes
+     */
+    private static void ensureAssignmentSlots(final FunctionNode functionNode, final Node assignmentDest) {
+        assignmentDest.accept(new NodeVisitor() {
+            @Override
+            public Node leave(final IndexNode indexNode) {
+                final Node index = indexNode.getIndex();
+                index.getSymbol().setNeedsSlot(!index.getSymbol().isConstant());
+                return indexNode;
+            }
+        });
+    }
+
+    /**
+     * Return the type that arithmetic ops should use. Until we have implemented better type
+     * analysis (range based) or overflow checks that are fast enough for int arithmetic,
+     * this is the number type
+     * @return the arithetic type
+     */
+    private static Type arithType() {
+        return Compiler.shouldUseIntegerArithmetic() ? Type.INT : Type.NUMBER;
+    }
+
+    /**
+     * If types have changed, we can have failed to update vars. For example
+     *
+     * var x = 17; //x is int
+     * x = "apa";  //x is object. This will be converted fine
+     *
+     * @param functionNode
+     */
+    private static void finalizeTypes(final FunctionNode functionNode) {
+        final Set<Node> changed = new HashSet<>();
+        do {
+            changed.clear();
+            functionNode.accept(new NodeVisitor() {
+
+                private void widen(final Node node, final Type to) {
+                    if (node instanceof LiteralNode) {
+                        return;
+                    }
+                    Type from = node.getType();
+                    if (!Type.areEquivalent(from, to) && Type.widest(from, to) == to) {
+                        LOG.fine("Had to post pass widen '" + node + "' " + Debug.id(node) + " from " + node.getType() + " to " + to);
+                        newType(node.getSymbol(), to);
+                        changed.add(node);
+                    }
+                }
+
+                @Override
+                public Node enter(final FunctionNode node) {
+                    return node.isLazy() ? null : node;
+                }
+
+                /**
+                 * Eg.
+                 *
+                 * var d = 17;
+                 * var e;
+                 * e = d; //initially typed as int for node type, should retype as double
+                 * e = object;
+                 *
+                 * var d = 17;
+                 * var e;
+                 * e -= d; //initially type number, should number remain with a final conversion supplied by Store. ugly, but the computation result of the sub is numeric
+                 * e = object;
+                 *
+                 */
+                @SuppressWarnings("fallthrough")
+                @Override
+                public Node leave(final BinaryNode binaryNode) {
+                    final Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
+                    switch (binaryNode.tokenType()) {
+                    default:
+                        if (!binaryNode.isAssignment() || binaryNode.isSelfModifying()) {
+                            break;
+                        }
+                        widen(binaryNode.lhs(), widest);
+                    case ADD:
+                        widen(binaryNode, widest);
+                        break;
+                    }
+                    return binaryNode;
+                }
+            });
+        } while (!changed.isEmpty());
+    }
+
+    /**
+     * This assign helper is called after an assignment, when all children of
+     * the assign has been processed. It fixes the types and recursively makes
+     * sure that everyhing has slots that should have them in the chain.
+     *
+     * @param binaryNode assignment node
+     */
+    private Node leaveAssignmentNode(final BinaryNode binaryNode) {
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        final Type type;
+        if (rhs.getType().isNumeric()) {
+            type = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
+        } else {
+            type = Type.OBJECT; //force lhs to be an object if not numeric assignment, e.g. strings too.
+        }
+        newTemporary(type, binaryNode);
+        newType(lhs.getSymbol(), type);
+        end(binaryNode);
+        return binaryNode;
+    }
+
+    private Node leaveSelfModifyingAssignmentNode(final BinaryNode binaryNode) {
+        return leaveSelfModifyingAssignmentNode(binaryNode, binaryNode.getWidestOperationType());
+    }
+
+    private Node leaveSelfModifyingAssignmentNode(final BinaryNode binaryNode, final Type destType) {
+        //e.g. for -=, Number, no wider, destType (binaryNode.getWidestOperationType())  is the coerce type
+        final Node lhs = binaryNode.lhs();
+
+        newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType
+        newTemporary(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine
+
+        ensureAssignmentSlots(getCurrentFunctionNode(), binaryNode);
+
+        end(binaryNode);
+        return binaryNode;
+    }
+
+    private static List<Block> findLookupBlocksHelper(final FunctionNode currentFunction, final FunctionNode topFunction) {
+        if (currentFunction.findParentFunction() == topFunction) {
+            final List<Block> blocks = new LinkedList<>();
+
+            blocks.add(currentFunction.getParent());
+            blocks.addAll(currentFunction.getReferencingParentBlocks());
+            return blocks;
+        }
+        /*
+         * assumption: all parent blocks of an inner function will always be in the same outer function;
+         * therefore we can simply skip through intermediate functions.
+         * @see FunctionNode#addReferencingParentBlock(Block)
+         */
+        return findLookupBlocksHelper(currentFunction.findParentFunction(), topFunction);
+    }
+
+    private static boolean isFunctionExpressionSelfReference(final Symbol symbol) {
+        if (symbol.isVar() && symbol.getNode() == symbol.getBlock() && symbol.getNode() instanceof FunctionNode) {
+            return ((FunctionNode)symbol.getNode()).getIdent().getName().equals(symbol.getName());
+        }
+        return false;
+    }
+
+    private static Symbol newTemporary(final FunctionNode functionNode, final Type type, final Node node) {
+        LOG.info("New TEMPORARY added to " + functionNode.getName() + " type=" + type);
+        return functionNode.newTemporary(type, node);
+    }
+
+    private Symbol newTemporary(final Type type, final Node node) {
+        return newTemporary(getCurrentFunctionNode(), type, node);
+    }
+
+    private Symbol newInternal(final FunctionNode functionNode, final String name, final Type type) {
+        final Symbol iter = getCurrentFunctionNode().defineSymbol(name, IS_VAR | IS_INTERNAL, null);
+        iter.setType(type); // NASHORN-73
+        return iter;
+    }
+
+    private Symbol newInternal(final String name, final Type type) {
+        return newInternal(getCurrentFunctionNode(), name, type);
+    }
+
+    private static void newType(final Symbol symbol, final Type type) {
+        final Type oldType = symbol.getSymbolType();
+        symbol.setType(type);
+
+        if (symbol.getSymbolType() != oldType) {
+            LOG.info("New TYPE " + type + " for " + symbol + " (was " + oldType + ")");
+        }
+
+        if (symbol.isParam()) {
+            symbol.setType(type);
+            LOG.info("Param type change " + symbol);
+        }
+    }
+
+    private void clearLocalDefs() {
+        localDefs = new HashSet<>();
+    }
+
+    private boolean isLocalDef(final String name) {
+        return localDefs.contains(name);
+    }
+
+    private void addLocalDef(final String name) {
+        LOG.info("Adding local def of symbol: '" + name + "'");
+        localDefs.add(name);
+    }
+
+    private void removeLocalDef(final String name) {
+        LOG.info("Removing local def of symbol: '" + name + "'");
+        localDefs.remove(name);
+    }
+
+    private void clearLocalUses() {
+        localUses = new HashSet<>();
+    }
+
+    private void addLocalUse(final String name) {
+        LOG.info("Adding local use of symbol: '" + name + "'");
+        localUses.add(name);
+    }
+
+    private static String name(final Node node) {
+        final String cn = node.getClass().getName();
+        int lastDot = cn.lastIndexOf('.');
+        if (lastDot == -1) {
+            return cn;
+        }
+        return cn.substring(lastDot + 1);
+    }
+
+    private Node start(final Node node) {
+        return start(node, true);
+    }
+
+    private Node start(final Node node, final boolean printNode) {
+        if (DEBUG) {
+            final StringBuilder sb = new StringBuilder();
+
+            sb.append("[ENTER ").
+                append(name(node)).
+                append("] ").
+                append(printNode ? node.toString() : "").
+                append(" in '").
+                append(getCurrentFunctionNode().getName()).
+                append("'");
+            LOG.info(sb.toString());
+            LOG.indent();
+        }
+
+        return node;
+    }
+
+    private Node end(final Node node) {
+        return end(node, true);
+    }
+
+    private Node end(final Node node, final boolean printNode) {
+        if (DEBUG) {
+            final StringBuilder sb = new StringBuilder();
+
+            sb.append("[LEAVE ").
+                append(name(node)).
+                append("] ").
+                append(printNode ? node.toString() : "").
+                append(" in '").
+                append(getCurrentFunctionNode().getName());
+
+            if (node.getSymbol() == null) {
+                sb.append(" <NO SYMBOL>");
+            } else {
+                sb.append(" <symbol=").append(node.getSymbol()).append('>');
+            }
+
+            LOG.unindent();
+            LOG.info(sb.toString());
+        }
+
+        return node;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java
new file mode 100644
index 0000000..84cef43
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java
@@ -0,0 +1,199 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.Condition.EQ;
+import static jdk.nashorn.internal.codegen.Condition.GE;
+import static jdk.nashorn.internal.codegen.Condition.GT;
+import static jdk.nashorn.internal.codegen.Condition.LE;
+import static jdk.nashorn.internal.codegen.Condition.LT;
+import static jdk.nashorn.internal.codegen.Condition.NE;
+
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.TernaryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+
+/**
+ * Branch optimizer for CodeGenerator. Given a jump condition this helper
+ * class attempts to simplify the control flow
+ */
+final class BranchOptimizer {
+
+    private final CodeGenerator codegen;
+    private final MethodEmitter method;
+
+    BranchOptimizer(final CodeGenerator codegen, final MethodEmitter method) {
+        this.codegen = codegen;
+        this.method  = method;
+    }
+
+    void execute(final Node node, final Label label, final boolean state) {
+        branchOptimizer(node, label, state);
+    }
+
+    private void load(final Node node) {
+        codegen.load(node);
+    }
+
+    private void branchOptimizer(final UnaryNode unaryNode, final Label label, final boolean state) {
+        final Node rhs = unaryNode.rhs();
+
+        switch (unaryNode.tokenType()) {
+        case NOT:
+            branchOptimizer(rhs, label, !state);
+            return;
+        case CONVERT:
+            if (unaryNode.getType().isBoolean()) {
+                branchOptimizer(rhs, label, state);
+                return;
+            }
+            break;
+        default:
+            break;
+        }
+
+        // convert to boolean
+        load(unaryNode);
+        method.convert(Type.BOOLEAN);
+        if (state) {
+            method.ifne(label);
+        } else {
+            method.ifeq(label);
+        }
+    }
+
+    private void branchOptimizer(final BinaryNode binaryNode, final Label label, final boolean state) {
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        switch (binaryNode.tokenType()) {
+        case AND:
+            if (state) {
+                final Label skip = new Label("skip");
+                branchOptimizer(lhs, skip, false);
+                branchOptimizer(rhs, label, true);
+                method.label(skip);
+            } else {
+                branchOptimizer(lhs, label, false);
+                branchOptimizer(rhs, label, false);
+            }
+            return;
+
+        case OR:
+            if (state) {
+                branchOptimizer(lhs, label, true);
+                branchOptimizer(rhs, label, true);
+            } else {
+                final Label skip = new Label("skip");
+                branchOptimizer(lhs, skip, true);
+                branchOptimizer(rhs, label, false);
+                method.label(skip);
+            }
+            return;
+
+        case EQ:
+        case EQ_STRICT:
+            assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol();
+            load(lhs);
+            load(rhs);
+            method.conditionalJump(state ? EQ : NE, true, label);
+            return;
+
+        case NE:
+        case NE_STRICT:
+            assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol();
+            load(lhs);
+            load(rhs);
+            method.conditionalJump(state ? NE : EQ, true, label);
+            return;
+
+        case GE:
+            assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol();
+            load(lhs);
+            load(rhs);
+            method.conditionalJump(state ? GE : LT, !state, label);
+            return;
+
+        case GT:
+            assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol();
+            load(lhs);
+            load(rhs);
+            method.conditionalJump(state ? GT : LE, !state, label);
+            return;
+
+        case LE:
+            assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol();
+            load(lhs);
+            load(rhs);
+            method.conditionalJump(state ? LE : GT, state, label);
+            return;
+
+        case LT:
+            assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol() + " in " + binaryNode;
+            load(lhs);
+            load(rhs);
+            method.conditionalJump(state ? LT : GE, state, label);
+            return;
+
+        default:
+            break;
+        }
+
+        load(binaryNode);
+        method.convert(Type.BOOLEAN);
+        if (state) {
+            method.ifne(label);
+        } else {
+            method.ifeq(label);
+        }
+    }
+
+    private void branchOptimizer(final Node node, final Label label, final boolean state) {
+        if (!(node instanceof TernaryNode)) {
+
+            if (node instanceof BinaryNode) {
+                branchOptimizer((BinaryNode)node, label, state);
+                return;
+            }
+
+            if (node instanceof UnaryNode) {
+                branchOptimizer((UnaryNode)node, label, state);
+                return;
+            }
+        }
+
+        load(node);
+        method.convert(Type.BOOLEAN);
+        if (state) {
+            method.ifne(label);
+        } else {
+            method.ifeq(label);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java
new file mode 100644
index 0000000..35e7482
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java
@@ -0,0 +1,623 @@
+/*
+ * 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.codegen;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_VARARGS;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEINTERFACE;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESPECIAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_NEWINVOKESPECIAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
+import static jdk.nashorn.internal.codegen.CompilerConstants.CLINIT;
+import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.GET_ARRAY_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.GET_ARRAY_SUFFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP;
+import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING;
+import static jdk.nashorn.internal.codegen.CompilerConstants.INIT;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SET_MAP;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.className;
+import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Set;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.util.TraceClassVisitor;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * The interface responsible for speaking to ASM, emitting classes,
+ * fields and methods.
+ * <p>
+ * This file contains the ClassEmitter, which is the master object
+ * responsible for writing byte codes. It utilizes a MethodEmitter
+ * for method generation, which also the NodeVisitors own, to keep
+ * track of the current code generator and what it is doing.
+ * <p>
+ * There is, however, nothing stopping you from using this in a
+ * completely self contained environment, for example in ObjectGenerator
+ * where there are no visitors or external hooks.
+ * <p>
+ * MethodEmitter makes it simple to generate code for methods without
+ * having to do arduous type checking. It maintains a type stack
+ * and will pick the appropriate operation for all operations sent to it
+ * We also allow chained called to a MethodEmitter for brevity, e.g.
+ * it is legal to write _new(className).dup() or
+ * load(slot).load(slot2).xor().store(slot3);
+ * <p>
+ * If running with assertions enabled, any type conflict, such as different
+ * bytecode stack sizes or operating on the wrong type will be detected
+ * and an error thrown.
+ * <p>
+ * There is also a very nice debug interface that can emit formatted
+ * bytecodes that have been written. This is enabled by setting the
+ * environment "nashorn.codegen.debug" to true, or --log=codegen:{@literal <level>}
+ * <p>
+ * A ClassEmitter implements an Emitter - i.e. it needs to have
+ * well defined start and end calls for whatever it is generating. Assertions
+ * detect if this is not true
+ *
+ * @see Compiler
+ */
+public class ClassEmitter implements Emitter {
+
+    /** Sanity check flag - have we started on a class? */
+    private boolean classStarted;
+
+    /** Sanity check flag - have we ended this emission? */
+    private boolean classEnded;
+
+    /**
+     * Sanity checks - which methods have we currently
+     * started for generation in this class?
+     */
+    private final HashSet<MethodEmitter> methodsStarted;
+
+    /** The ASM classwriter that we use for all bytecode operations */
+    protected final ClassWriter cw;
+
+    /** The script environment */
+    protected final ScriptEnvironment env;
+
+    /** Default flags for class generation - oublic class */
+    private static final EnumSet<Flag> DEFAULT_METHOD_FLAGS = EnumSet.of(Flag.PUBLIC);
+
+    /** Compile unit class name. */
+    private String unitClassName;
+
+    /** Set of constants access methods required. */
+    private Set<Class<?>> constantMethodNeeded;
+
+    /**
+     * Constructor - only used internally in this class as it breaks
+     * abstraction towards ASM or other code generator below
+     *
+     * @param env script environment
+     * @param cw  ASM classwriter
+     */
+    private ClassEmitter(final ScriptEnvironment env, final ClassWriter cw) {
+        assert env != null;
+
+        this.env            = env;
+        this.cw             = cw;
+        this.methodsStarted = new HashSet<>();
+    }
+
+    /**
+     * Constructor
+     *
+     * @param env             script environment
+     * @param className       name of class to weave
+     * @param superClassName  super class name for class
+     * @param interfaceNames  names of interfaces implemented by this class, or null if none
+     */
+    ClassEmitter(final ScriptEnvironment env, final String className, final String superClassName, final String... interfaceNames) {
+        this(env, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
+        cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClassName, interfaceNames);
+    }
+
+    /**
+     * Constructor from the compiler
+     *
+     * @param compiler      Compiler
+     * @param unitClassName Compile unit class name.
+     * @param strictMode    Should we generate this method in strict mode
+     */
+    ClassEmitter(final ScriptEnvironment env, final String sourceName, final String unitClassName, final boolean strictMode) {
+        this(env,
+             new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
+                private static final String OBJECT_CLASS  = "java/lang/Object";
+
+                @Override
+                protected String getCommonSuperClass(final String type1, final String type2) {
+                    try {
+                        return super.getCommonSuperClass(type1, type2);
+                    } catch (final RuntimeException e) {
+                        if (isScriptObject(Compiler.SCRIPTS_PACKAGE, type1) && isScriptObject(Compiler.SCRIPTS_PACKAGE, type2)) {
+                            return className(ScriptObject.class);
+                        }
+                        return OBJECT_CLASS;
+                    }
+                }
+            });
+
+        this.unitClassName        = unitClassName;
+        this.constantMethodNeeded = new HashSet<>();
+
+        cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, unitClassName, null, pathName(jdk.nashorn.internal.scripts.JS.class.getName()), null);
+        cw.visitSource(sourceName, null);
+
+        defineCommonStatics(strictMode);
+    }
+
+    /**
+     * Convert a binary name to a package/class name.
+     *
+     * @param name Binary name.
+     * @return Package/class name.
+     */
+    private static String pathName(final String name) {
+        return name.replace('.', '/');
+    }
+
+    /**
+     * Define the static fields common in all scripts.
+     * @param strictMode Should we generate this method in strict mode
+     */
+    private void defineCommonStatics(final boolean strictMode) {
+        // source - used to store the source data (text) for this script.  Shared across
+        // compile units.  Set externally by the compiler.
+        field(EnumSet.of(Flag.PRIVATE, Flag.STATIC), SOURCE.tag(), Source.class);
+
+        // constants - used to the constants array for this script.  Shared across
+        // compile units.  Set externally by the compiler.
+        field(EnumSet.of(Flag.PRIVATE, Flag.STATIC), CONSTANTS.tag(), Object[].class);
+
+        // strictMode - was this script compiled in strict mode.  Set externally by the compiler.
+        field(EnumSet.of(Flag.PUBLIC, Flag.STATIC, Flag.FINAL), STRICT_MODE.tag(), boolean.class, strictMode);
+    }
+
+    /**
+     * Define static utilities common needed in scripts.  These are per compile unit
+     * and therefore have to be defined here and not in code gen.
+     */
+    private void defineCommonUtilities() {
+        assert unitClassName != null;
+
+        if (constantMethodNeeded.contains(String.class)) {
+            // $getString - get the ith entry from the constants table and cast to String.
+            final MethodEmitter getStringMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), GET_STRING.tag(), String.class, int.class);
+            getStringMethod.begin();
+            getStringMethod.getStatic(unitClassName, CONSTANTS.tag(), CONSTANTS.descriptor())
+                        .load(Type.INT, 0)
+                        .arrayload()
+                        .checkcast(String.class)
+                        ._return();
+            getStringMethod.end();
+        }
+
+        if (constantMethodNeeded.contains(PropertyMap.class)) {
+            // $getMap - get the ith entry from the constants table and cast to PropertyMap.
+            final MethodEmitter getMapMethod = method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), GET_MAP.tag(), PropertyMap.class, int.class);
+            getMapMethod.begin();
+            getMapMethod.loadConstants(unitClassName)
+                        .load(Type.INT, 0)
+                        .arrayload()
+                        .checkcast(PropertyMap.class)
+                        ._return();
+            getMapMethod.end();
+
+            // $setMap - overwrite an existing map.
+            final MethodEmitter setMapMethod = method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), SET_MAP.tag(), void.class, int.class, PropertyMap.class);
+            setMapMethod.begin();
+            setMapMethod.loadConstants(unitClassName)
+                        .load(Type.INT, 0)
+                        .load(Type.OBJECT, 1)
+                        .arraystore();
+            setMapMethod.returnVoid();
+            setMapMethod.end();
+        }
+
+        // $getXXXX$array - get the ith entry from the constants table and cast to XXXX[].
+        for (final Class<?> cls : constantMethodNeeded) {
+            if (cls.isArray()) {
+                defineGetArrayMethod(cls);
+            }
+        }
+    }
+
+    /**
+     * Constructs a primitive specific method for getting the ith entry from the constants table and cast.
+     * @param cls Array class.
+     */
+    private void defineGetArrayMethod(final Class<?> cls) {
+        assert unitClassName != null;
+
+        final String        methodName     = getArrayMethodName(cls);
+        final MethodEmitter getArrayMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), methodName, cls, int.class);
+
+        getArrayMethod.begin();
+        getArrayMethod.getStatic(unitClassName, CONSTANTS.tag(), CONSTANTS.descriptor())
+                      .load(Type.INT, 0)
+                      .arrayload()
+                      .checkcast(cls)
+                      .dup()
+                      .arraylength()
+                      .invoke(staticCallNoLookup(Arrays.class, "copyOf", cls, cls, int.class))
+                      ._return();
+        getArrayMethod.end();
+    }
+
+    /**
+     * Generate the name of a get array from constant pool method.
+     * @param cls Name of array class.
+     * @return Method name.
+     */
+    static String getArrayMethodName(final Class<?> cls) {
+        assert cls.isArray();
+        return GET_ARRAY_PREFIX.tag() + cls.getComponentType().getSimpleName() + GET_ARRAY_SUFFIX.tag();
+    }
+
+    /**
+     * Ensure a get constant method is issued for the class.
+     * @param cls Class of constant.
+     */
+    void needGetConstantMethod(final Class<?> cls) {
+        constantMethodNeeded.add(cls);
+    }
+
+    /**
+     * Inspect class name and decide whether we are generating a ScriptObject class
+     *
+     * @param scriptPrefix the script class prefix for the current script
+     * @param type         the type to check
+     *
+     * @return true if type is ScriptObject
+     */
+    private static boolean isScriptObject(final String scriptPrefix, final String type) {
+        if (type.startsWith(scriptPrefix)) {
+            return true;
+        } else if (type.equals(CompilerConstants.className(ScriptObject.class))) {
+            return true;
+        } else if (type.startsWith(Compiler.OBJECTS_PACKAGE)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Call at beginning of class emission
+     * @see Emitter
+     */
+    @Override
+    public void begin() {
+        classStarted = true;
+    }
+
+    /**
+     * Call at end of class emission
+     * @see Emitter
+     */
+    @Override
+    public void end() {
+        assert classStarted;
+
+        if (unitClassName != null) {
+            defineCommonUtilities();
+        }
+
+        cw.visitEnd();
+        classStarted = false;
+        classEnded   = true;
+        assert methodsStarted.isEmpty() : "methodsStarted not empty " + methodsStarted;
+    }
+
+    /**
+     * Disassemble an array of byte code.
+     * @param bytecode  byte array representing bytecode
+     * @return disassembly as human readable string
+     */
+    static String disassemble(final byte[] bytecode) {
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (final PrintWriter pw = new PrintWriter(baos)) {
+            new ClassReader(bytecode).accept(new TraceClassVisitor(pw), 0);
+        }
+        return new String(baos.toByteArray());
+    }
+
+    /**
+     * @return env used for class emission
+     */
+    ScriptEnvironment getEnv() {
+        return env;
+    }
+
+    /**
+     * Call back from MethodEmitter for method start
+     *
+     * @see MethodEmitter
+     *
+     * @param method method emitter.
+     */
+    void beginMethod(final MethodEmitter method) {
+        assert !methodsStarted.contains(method);
+        methodsStarted.add(method);
+    }
+
+    /**
+     * Call back from MethodEmitter for method end
+     *
+     * @see MethodEmitter
+     *
+     * @param method
+     */
+    void endMethod(final MethodEmitter method) {
+        assert methodsStarted.contains(method);
+        methodsStarted.remove(method);
+    }
+
+    /**
+     * Add a new method to the class - defaults to public method
+     *
+     * @param methodName name of method
+     * @param rtype      return type of the method
+     * @param ptypes     parameter types the method
+     *
+     * @return method emitter to use for weaving this method
+     */
+    MethodEmitter method(final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
+        return method(DEFAULT_METHOD_FLAGS, methodName, rtype, ptypes); //TODO why public default ?
+    }
+
+    /**
+     * Add a new method to the class - defaults to public method
+     *
+     * @param methodFlags access flags for the method
+     * @param methodName  name of method
+     * @param rtype       return type of the method
+     * @param ptypes      parameter types the method
+     *
+     * @return method emitter to use for weaving this method
+     */
+    MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
+        return new MethodEmitter(this, cw.visitMethod(Flag.getValue(methodFlags), methodName, methodDescriptor(rtype, ptypes), null, null));
+    }
+
+    /**
+     * Add a new method to the class - defaults to public method
+     *
+     * @param methodName name of method
+     * @param descriptor descriptor of method
+     *
+     * @return method emitter to use for weaving this method
+     */
+    MethodEmitter method(final String methodName, final String descriptor) {
+        return method(DEFAULT_METHOD_FLAGS, methodName, descriptor);
+    }
+
+    /**
+     * Add a new method to the class - defaults to public method
+     *
+     * @param methodFlags access flags for the method
+     * @param methodName  name of method
+     * @param descriptor  descriptor of method
+     *
+     * @return method emitter to use for weaving this method
+     */
+    MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final String descriptor) {
+        return new MethodEmitter(this, cw.visitMethod(Flag.getValue(methodFlags), methodName, descriptor, null, null));
+    }
+
+    /**
+     * Add a new method to the class, representing a function node
+     *
+     * @param functionNode the function node to generate a method for
+     * @return method emitter to use for weaving this method
+     */
+    MethodEmitter method(final FunctionNode functionNode) {
+        final MethodVisitor mv = cw.visitMethod(
+            ACC_PUBLIC | ACC_STATIC | (functionNode.isVarArg() ? ACC_VARARGS : 0),
+            functionNode.getName(),
+            new FunctionSignature(functionNode).toString(),
+            null,
+            null);
+
+        return new MethodEmitter(this, mv, functionNode);
+    }
+
+    /**
+     * Start generating the <clinit> method in the class
+     *
+     * @return method emitter to use for weaving <clinit>
+     */
+    MethodEmitter clinit() {
+        return method(EnumSet.of(Flag.STATIC), CLINIT.tag(), void.class);
+    }
+
+    /**
+     * Start generating an <init>()V method in the class
+     *
+     * @return method emitter to use for weaving <init>()V
+     */
+    MethodEmitter init() {
+        return method(INIT.tag(), void.class);
+    }
+
+    /**
+     * Start generating an <init>()V method in the class
+     *
+     * @param ptypes parameter types for constructor
+     * @return method emitter to use for weaving <init>()V
+     */
+    MethodEmitter init(final Class<?>... ptypes) {
+        return method(INIT.tag(), void.class, ptypes);
+    }
+
+    /**
+     * Start generating an <init>(...)V method in the class
+     *
+     * @param flags  access flags for the constructor
+     * @param ptypes parameter types for the constructor
+     *
+     * @return method emitter to use for weaving <init>(...)V
+     */
+    MethodEmitter init(final EnumSet<Flag> flags, final Class<?>... ptypes) {
+        return method(flags, INIT.tag(), void.class, ptypes);
+    }
+
+    /**
+     * Add a field to the class, initialized to a value
+     *
+     * @param fieldFlags flags, e.g. should it be static or public etc
+     * @param fieldName  name of field
+     * @param fieldType  the type of the field
+     * @param value      the value
+     *
+     * @see ClassEmitter.Flag
+     */
+    final void field(final EnumSet<Flag> fieldFlags, final String fieldName, final Class<?> fieldType, final Object value) {
+        cw.visitField(Flag.getValue(fieldFlags), fieldName, typeDescriptor(fieldType), null, value).visitEnd();
+    }
+
+    /**
+     * Add a field to the class
+     *
+     * @param fieldFlags access flags for the field
+     * @param fieldName  name of field
+     * @param fieldType  type of the field
+     *
+     * @see ClassEmitter.Flag
+     */
+    final void field(final EnumSet<Flag> fieldFlags, final String fieldName, final Class<?> fieldType) {
+        field(fieldFlags, fieldName, fieldType, null);
+    }
+
+    /**
+     * Add a field to the class - defaults to public
+     *
+     * @param fieldName  name of field
+     * @param fieldType  type of field
+     */
+    final void field(final String fieldName, final Class<?> fieldType) {
+        field(EnumSet.of(Flag.PUBLIC), fieldName, fieldType, null);
+    }
+
+    /**
+     * Return a bytecode array from this ClassEmitter. The ClassEmitter must
+     * have been ended (having its end function called) for this to work.
+     *
+     * @return byte code array for generated class, null if class generation hasn't been ended with {@link ClassEmitter#end()}
+     */
+    byte[] toByteArray() {
+        assert classEnded;
+        if (!classEnded) {
+            return null;
+        }
+
+        return cw.toByteArray();
+    }
+
+    /**
+     * Abstraction for flags used in class emission
+     *
+     * We provide abstraction separating these from the underlying bytecode
+     * emitter.
+     *
+     * Flags are provided for method handles, protection levels, static/virtual
+     * fields/methods.
+     */
+    static enum Flag {
+        /** method handle with static access */
+        HANDLE_STATIC(H_INVOKESTATIC),
+        /** method handle with new invoke special access */
+        HANDLE_NEWSPECIAL(H_NEWINVOKESPECIAL),
+        /** method handle with invoke special access */
+        HANDLE_SPECIAL(H_INVOKESPECIAL),
+        /** method handle with invoke virtual access */
+        HANDLE_VIRTUAL(H_INVOKEVIRTUAL),
+        /** method handle with invoke interface access */
+        HANDLE_INTERFACE(H_INVOKEINTERFACE),
+
+        /** final access */
+        FINAL(ACC_FINAL),
+        /** static access */
+        STATIC(ACC_STATIC),
+        /** public access */
+        PUBLIC(ACC_PUBLIC),
+        /** private access */
+        PRIVATE(ACC_PRIVATE);
+
+        private int value;
+
+        private Flag(final int value) {
+            this.value = value;
+        }
+
+        /**
+         * Get the value of this flag
+         * @return the int value
+         */
+        int getValue() {
+            return value;
+        }
+
+        /**
+         * Return the corresponding ASM flag value for an enum set of flags
+         *
+         * @param flags enum set of flags
+         * @return an integer value representing the flags intrinsic values or:ed together
+         */
+        static int getValue(final EnumSet<Flag> flags) {
+            int v = 0;
+            for (final Flag flag : flags) {
+                v |= flag.getValue();
+            }
+            return v;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
new file mode 100644
index 0000000..2ffb5bd
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
@@ -0,0 +1,3315 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.HANDLE_STATIC;
+import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.PRIVATE;
+import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.STATIC;
+import static jdk.nashorn.internal.codegen.CompilerConstants.ALLOCATE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP;
+import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING;
+import static jdk.nashorn.internal.codegen.CompilerConstants.LEAF;
+import static jdk.nashorn.internal.codegen.CompilerConstants.QUICK_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.REGEX_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_ARRAY_ARG;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticField;
+import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
+import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
+import static jdk.nashorn.internal.ir.Symbol.IS_TEMP;
+import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE;
+import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_SCOPE;
+import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
+
+import java.io.PrintWriter;
+import java.lang.invoke.MethodHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode;
+import jdk.nashorn.internal.codegen.types.ArrayType;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.BaseNode;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BreakNode;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.CaseNode;
+import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ContinueNode;
+import jdk.nashorn.internal.ir.DoWhileNode;
+import jdk.nashorn.internal.ir.EmptyNode;
+import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.IndexNode;
+import jdk.nashorn.internal.ir.LineNumberNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
+import jdk.nashorn.internal.ir.PropertyNode;
+import jdk.nashorn.internal.ir.ReferenceNode;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.RuntimeNode.Request;
+import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.ir.TernaryNode;
+import jdk.nashorn.internal.ir.ThrowNode;
+import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.WhileNode;
+import jdk.nashorn.internal.ir.WithNode;
+import jdk.nashorn.internal.ir.debug.ASTWriter;
+import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Lexer.RegexToken;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.CodeInstaller;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ECMAException;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.Scope;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptFunctionData;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.Undefined;
+import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
+
+/**
+ * This is the lowest tier of the code generator. It takes lowered ASTs emitted
+ * from Lower and emits Java byte code. The byte code emission logic is broken
+ * out into MethodEmitter. MethodEmitter works internally with a type stack, and
+ * keeps track of the contents of the byte code stack. This way we avoid a large
+ * number of special cases on the form
+ * <pre>
+ * if (type == INT) {
+ *     visitInsn(ILOAD, slot);
+ * } else if (type == DOUBLE) {
+ *     visitInsn(DOUBLE, slot);
+ * }
+ * </pre>
+ * This quickly became apparent when the code generator was generalized to work
+ * with all types, and not just numbers or objects.
+ * <p>
+ * The CodeGenerator visits nodes only once, tags them as resolved and emits
+ * bytecode for them.
+ */
+final class CodeGenerator extends NodeOperatorVisitor {
+
+    /** Name of the Global object, cannot be referred to as .class, @see CodeGenerator */
+    private static final String GLOBAL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "Global";
+
+    /** Name of the ScriptFunctionImpl, cannot be referred to as .class @see FunctionObjectCreator */
+    private static final String SCRIPTFUNCTION_IMPL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "ScriptFunctionImpl";
+
+    private static final String SCRIPTFUNCTION_TRAMPOLINE_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "ScriptFunctionTrampolineImpl";
+
+    /** Constant data & installation. The only reason the compiler keeps this is because it is assigned
+     *  by reflection in class installation */
+    private final Compiler compiler;
+
+    /** Call site flags given to the code generator to be used for all generated call sites */
+    private final int callSiteFlags;
+
+    /** How many regexp fields have been emitted */
+    private int regexFieldCount;
+
+    /** Map of shared scope call sites */
+    private final Map<SharedScopeCall, SharedScopeCall> scopeCalls = new HashMap<>();
+
+    /** When should we stop caching regexp expressions in fields to limit bytecode size? */
+    private static final int MAX_REGEX_FIELDS = 2 * 1024;
+
+    /**
+     * Constructor.
+     *
+     * @param compiler
+     */
+    CodeGenerator(final Compiler compiler) {
+        this.compiler      = compiler;
+        this.callSiteFlags = compiler.getEnv()._callsite_flags;
+    }
+
+    /**
+     * Gets the call site flags, adding the strict flag if the current function
+     * being generated is in strict mode
+     *
+     * @return the correct flags for a call site in the current function
+     */
+    int getCallSiteFlags() {
+        return getCurrentFunctionNode().isStrictMode() ? callSiteFlags | CALLSITE_STRICT : callSiteFlags;
+    }
+
+    /**
+     * Load an identity node
+     *
+     * @param identNode an identity node to load
+     * @return the method generator used
+     */
+    private MethodEmitter loadIdent(final IdentNode identNode) {
+        final Symbol symbol = identNode.getSymbol();
+
+        if (!symbol.isScope()) {
+            assert symbol.hasSlot() || symbol.isParam();
+            return method.load(symbol);
+        }
+
+        final String name = symbol.getName();
+
+        if (CompilerConstants.__FILE__.name().equals(name)) {
+            return method.load(identNode.getSource().getName());
+        } else if (CompilerConstants.__DIR__.name().equals(name)) {
+            return method.load(identNode.getSource().getBase());
+        } else if (CompilerConstants.__LINE__.name().equals(name)) {
+            return method.load(identNode.getSource().getLine(identNode.position())).convert(Type.OBJECT);
+        } else {
+            assert identNode.getSymbol().isScope() : identNode + " is not in scope!";
+
+            final int flags = CALLSITE_SCOPE | getCallSiteFlags();
+            method.loadScope();
+
+            if (symbol.isFastScope(getCurrentFunctionNode())) {
+                // Only generate shared scope getter for fast-scope symbols so we know we can dial in correct scope.
+                if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD) {
+                    return loadSharedScopeVar(identNode.getType(), symbol, flags);
+                }
+                return loadFastScopeVar(identNode.getType(), symbol, flags, identNode.isFunction());
+            }
+            return method.dynamicGet(identNode.getType(), identNode.getName(), flags, identNode.isFunction());
+        }
+    }
+
+    private MethodEmitter loadSharedScopeVar(final Type valueType, final Symbol symbol, final int flags) {
+        method.load(symbol.isFastScope(getCurrentFunctionNode()) ? getScopeProtoDepth(getCurrentBlock(), symbol) : -1);
+        final SharedScopeCall scopeCall = getScopeGet(valueType, symbol, flags | CALLSITE_FAST_SCOPE);
+        scopeCall.generateInvoke(method);
+        return method;
+    }
+
+    private MethodEmitter loadFastScopeVar(final Type valueType, final Symbol symbol, final int flags, final boolean isMethod) {
+        loadFastScopeProto(symbol, false);
+        method.dynamicGet(valueType, symbol.getName(), flags | CALLSITE_FAST_SCOPE, isMethod);
+        return method;
+    }
+
+    private MethodEmitter storeFastScopeVar(final Type valueType, final Symbol symbol, final int flags) {
+        loadFastScopeProto(symbol, true);
+        method.dynamicSet(valueType, symbol.getName(), flags | CALLSITE_FAST_SCOPE);
+        return method;
+    }
+
+    private static int getScopeProtoDepth(final Block currentBlock, final Symbol symbol) {
+        if (currentBlock == symbol.getBlock()) {
+            return 0;
+        }
+
+        final int   delta       = currentBlock.needsScope() ? 1 : 0;
+        final Block parentBlock = currentBlock.getParent();
+
+        if (parentBlock != null) {
+            final int result = getScopeProtoDepth(parentBlock, symbol);
+            if (result != -1) {
+                return delta + result;
+            }
+        }
+
+        if (currentBlock instanceof FunctionNode) {
+            for (final Block lookupBlock : ((FunctionNode)currentBlock).getReferencingParentBlocks()) {
+                final int result = getScopeProtoDepth(lookupBlock, symbol);
+                if (result != -1) {
+                    return delta + result;
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    private void loadFastScopeProto(final Symbol symbol, final boolean swap) {
+        final int depth = getScopeProtoDepth(getCurrentBlock(), symbol);
+        assert depth != -1;
+        if(depth > 0) {
+            if (swap) {
+                method.swap();
+            }
+            for (int i = 0; i < depth; i++) {
+                method.invoke(ScriptObject.GET_PROTO);
+            }
+            if (swap) {
+                method.swap();
+            }
+        }
+    }
+
+    /**
+     * Generate code that loads this node to the stack. This method is only
+     * public to be accessible from the maps sub package. Do not call externally
+     *
+     * @param node node to load
+     *
+     * @return the method emitter used
+     */
+    MethodEmitter load(final Node node) {
+        return load(node, false);
+    }
+
+    private MethodEmitter load(final Node node, final boolean baseAlreadyOnStack) {
+        final Symbol symbol = node.getSymbol();
+
+        // If we lack symbols, we just generate what we see.
+        if (symbol == null) {
+            node.accept(this);
+            return method;
+        }
+
+        /*
+         * The load may be of type IdentNode, e.g. "x", AccessNode, e.g. "x.y"
+         * or IndexNode e.g. "x[y]". Both AccessNodes and IndexNodes are
+         * BaseNodes and the logic for loading the base object is reused
+         */
+        final CodeGenerator codegen = this;
+
+        node.accept(new NodeVisitor(getCurrentCompileUnit(), method) {
+            @Override
+            public Node enter(final IdentNode identNode) {
+                loadIdent(identNode);
+                return null;
+            }
+
+            @Override
+            public Node enter(final AccessNode accessNode) {
+                if (!baseAlreadyOnStack) {
+                    load(accessNode.getBase()).convert(Type.OBJECT);
+                }
+                assert method.peekType().isObject();
+                method.dynamicGet(node.getType(), accessNode.getProperty().getName(), getCallSiteFlags(), accessNode.isFunction());
+                return null;
+            }
+
+            @Override
+            public Node enter(final IndexNode indexNode) {
+                if (!baseAlreadyOnStack) {
+                    load(indexNode.getBase()).convert(Type.OBJECT);
+                    load(indexNode.getIndex());
+                }
+                method.dynamicGetIndex(node.getType(), getCallSiteFlags(), indexNode.isFunction());
+                return null;
+            }
+
+            @Override
+            public Node enterDefault(final Node otherNode) {
+                otherNode.accept(codegen); // generate code for whatever we are looking at.
+                method.load(symbol); // load the final symbol to the stack (or nop if no slot, then result is already there)
+                return null;
+            }
+        });
+
+        return method;
+    }
+
+    @Override
+    public Node enter(final AccessNode accessNode) {
+        if (accessNode.testResolved()) {
+            return null;
+        }
+
+        load(accessNode);
+
+        return null;
+    }
+
+    /**
+     * Initialize a specific set of vars to undefined. This has to be done at
+     * the start of each method for local variables that aren't passed as
+     * parameters.
+     *
+     * @param symbols list of symbols.
+     */
+    private void initSymbols(final Iterable<Symbol> symbols) {
+        final LinkedList<Symbol> numbers = new LinkedList<>();
+        final LinkedList<Symbol> objects = new LinkedList<>();
+
+        for (final Symbol symbol : symbols) {
+            /*
+             * The following symbols are guaranteed to be defined and thus safe
+             * from having undefined written to them: parameters internals this
+             *
+             * Otherwise we must, unless we perform control/escape analysis,
+             * assign them undefined.
+             */
+            final boolean isInternal = symbol.isParam() || symbol.isInternal() || symbol.isThis() || !symbol.canBeUndefined();
+
+            if (symbol.hasSlot() && !isInternal) {
+                assert symbol.getSymbolType().isNumber() || symbol.getSymbolType().isObject() : "no potentially undefined narrower local vars than doubles are allowed: " + symbol + " in " + getCurrentFunctionNode();
+                if (symbol.getSymbolType().isNumber()) {
+                    numbers.add(symbol);
+                } else if (symbol.getSymbolType().isObject()) {
+                    objects.add(symbol);
+                }
+            }
+        }
+
+        initSymbols(numbers, Type.NUMBER);
+        initSymbols(objects, Type.OBJECT);
+    }
+
+    private void initSymbols(final LinkedList<Symbol> symbols, final Type type) {
+        if (symbols.isEmpty()) {
+            return;
+        }
+
+        method.loadUndefined(type);
+        while (!symbols.isEmpty()) {
+            final Symbol symbol = symbols.removeFirst();
+            if (!symbols.isEmpty()) {
+                method.dup();
+            }
+            method.store(symbol);
+        }
+    }
+
+    /**
+     * Create symbol debug information.
+     *
+     * @param block block containing symbols.
+     */
+    private void symbolInfo(final Block block) {
+        for (final Symbol symbol : block.getFrame().getSymbols()) {
+            method.localVariable(symbol, block.getEntryLabel(), block.getBreakLabel());
+        }
+    }
+
+    @Override
+    public Node enter(final Block block) {
+        if (block.testResolved()) {
+            return null;
+        }
+
+        method.label(block.getEntryLabel());
+        initLocals(block);
+
+        return block;
+    }
+
+    @Override
+    public Node leave(final Block block) {
+        method.label(block.getBreakLabel());
+        symbolInfo(block);
+
+        if (block.needsScope()) {
+            popBlockScope(block);
+        }
+
+        return block;
+    }
+
+    private void popBlockScope(final Block block) {
+        final Label exitLabel     = new Label("block_exit");
+        final Label recoveryLabel = new Label("block_catch");
+        final Label skipLabel     = new Label("skip_catch");
+
+        /* pop scope a la try-finally */
+        method.loadScope();
+        method.invoke(ScriptObject.GET_PROTO);
+        method.storeScope();
+        method._goto(skipLabel);
+        method.label(exitLabel);
+
+        method._catch(recoveryLabel);
+        method.loadScope();
+        method.invoke(ScriptObject.GET_PROTO);
+        method.storeScope();
+        method.athrow();
+        method.label(skipLabel);
+        method._try(block.getEntryLabel(), exitLabel, recoveryLabel, Throwable.class);
+    }
+
+    @Override
+    public Node enter(final BreakNode breakNode) {
+        if (breakNode.testResolved()) {
+            return null;
+        }
+
+        for (int i = 0; i < breakNode.getScopeNestingLevel(); i++) {
+            closeWith();
+        }
+
+        method.splitAwareGoto(breakNode.getTargetLabel());
+
+        return null;
+    }
+
+    private int loadArgs(final List<Node> args) {
+        return loadArgs(args, null, false, args.size());
+    }
+
+    private int loadArgs(final List<Node> args, final String signature, final boolean isVarArg, final int argCount) {
+        // arg have already been converted to objects here.
+        if (isVarArg || argCount > LinkerCallSite.ARGLIMIT) {
+            loadArgsArray(args);
+            return 1;
+        }
+
+        // pad with undefined if size is too short. argCount is the real number of args
+        int n = 0;
+        final Type[] params = signature == null ? null : Type.getMethodArguments(signature);
+        for (final Node arg : args) {
+            assert arg != null;
+            load(arg);
+            if (n >= argCount) {
+                method.pop(); // we had to load the arg for its side effects
+            } else if (params != null) {
+                method.convert(params[n]);
+            }
+            n++;
+        }
+
+        while (n < argCount) {
+            method.loadUndefined(Type.OBJECT);
+            n++;
+        }
+
+        return argCount;
+    }
+
+    @Override
+    public Node enter(final CallNode callNode) {
+        if (callNode.testResolved()) {
+            return null;
+        }
+
+        final List<Node>   args            = callNode.getArgs();
+        final Node         function        = callNode.getFunction();
+        final FunctionNode currentFunction = getCurrentFunctionNode();
+        final Block        currentBlock    = getCurrentBlock();
+
+        function.accept(new NodeVisitor(getCurrentCompileUnit(), method) {
+
+            private void sharedScopeCall(final IdentNode identNode, final int flags) {
+                final Symbol symbol = identNode.getSymbol();
+                int    scopeCallFlags = flags;
+                method.loadScope();
+                if (symbol.isFastScope(currentFunction)) {
+                    method.load(getScopeProtoDepth(currentBlock, symbol));
+                    scopeCallFlags |= CALLSITE_FAST_SCOPE;
+                } else {
+                    method.load(-1); // Bypass fast-scope code in shared callsite
+                }
+                loadArgs(args);
+                final Type[] paramTypes = method.getTypesFromStack(args.size());
+                final SharedScopeCall scopeCall = getScopeCall(symbol, identNode.getType(), callNode.getType(), paramTypes, scopeCallFlags);
+                scopeCall.generateInvoke(method);
+            }
+
+            private void scopeCall(final IdentNode node, final int flags) {
+                load(node);
+                method.convert(Type.OBJECT); // foo() makes no sense if foo == 3
+                // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
+                method.loadNull(); //the 'this'
+                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), flags);
+            }
+
+            private void evalCall(final IdentNode node, final int flags) {
+                load(node);
+                method.convert(Type.OBJECT); // foo() makes no sense if foo == 3
+
+                final Label not_eval  = new Label("not_eval");
+                final Label eval_done = new Label("eval_done");
+
+                // check if this is the real built-in eval
+                method.dup();
+                globalIsEval();
+
+                method.ifeq(not_eval);
+                // We don't need ScriptFunction object for 'eval'
+                method.pop();
+
+                method.loadScope(); // Load up self (scope).
+
+                final CallNode.EvalArgs evalArgs = callNode.getEvalArgs();
+                // load evaluated code
+                load(evalArgs.getCode());
+                method.convert(Type.OBJECT);
+                // special/extra 'eval' arguments
+                load(evalArgs.getThis());
+                method.load(evalArgs.getLocation());
+                method.load(evalArgs.getStrictMode());
+                method.convert(Type.OBJECT);
+
+                // direct call to Global.directEval
+                globalDirectEval();
+                method.convert(callNode.getType());
+                method._goto(eval_done);
+
+                method.label(not_eval);
+                // This is some scope 'eval' or global eval replaced by user
+                // but not the built-in ECMAScript 'eval' function call
+                method.loadNull();
+                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), flags);
+
+                method.label(eval_done);
+            }
+
+            @Override
+            public Node enter(final IdentNode node) {
+                final Symbol symbol = node.getSymbol();
+
+                if (symbol.isScope()) {
+                    final int flags = getCallSiteFlags() | CALLSITE_SCOPE;
+                    final int useCount = symbol.getUseCount();
+
+                    // Threshold for generating shared scope callsite is lower for fast scope symbols because we know
+                    // we can dial in the correct scope. However, we als need to enable it for non-fast scopes to
+                    // support huge scripts like mandreel.js.
+                    if (callNode.isEval()) {
+                        evalCall(node, flags);
+                    } else if (useCount <= SharedScopeCall.FAST_SCOPE_CALL_THRESHOLD
+                            || (!symbol.isFastScope(currentFunction) && useCount <= SharedScopeCall.SLOW_SCOPE_CALL_THRESHOLD)
+                            || callNode.inWithBlock()) {
+                        scopeCall(node, flags);
+                    } else {
+                        sharedScopeCall(node, flags);
+                    }
+                    assert method.peekType().equals(callNode.getType());
+                } else {
+                    enterDefault(node);
+                }
+
+                return null;
+            }
+
+            @Override
+            public Node enter(final AccessNode node) {
+                load(node.getBase());
+                method.convert(Type.OBJECT);
+                method.dup();
+                method.dynamicGet(node.getType(), node.getProperty().getName(), getCallSiteFlags(), true);
+                method.swap();
+                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags());
+                assert method.peekType().equals(callNode.getType());
+
+                return null;
+            }
+
+            @Override
+            public Node enter(final ReferenceNode node) {
+                final FunctionNode callee   = node.getReference();
+                final boolean      isVarArg = callee.isVarArg();
+                final int          argCount = isVarArg ? -1 : callee.getParameters().size();
+
+                final String signature = new FunctionSignature(true, callee.needsCallee(), callee.getReturnType(), isVarArg ? null : callee.getParameters()).toString();
+
+                if (callee.needsCallee()) {
+                    newFunctionObject(callee);
+                }
+
+                if (callee.isStrictMode()) { // self is undefined
+                    method.loadUndefined(Type.OBJECT);
+                } else { // get global from scope (which is the self)
+                    globalInstance();
+                }
+                loadArgs(args, signature, isVarArg, argCount);
+                method.invokestatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature);
+                assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType();
+
+                return null;
+            }
+
+            @Override
+            public Node enter(final IndexNode node) {
+                load(node.getBase());
+                method.convert(Type.OBJECT);
+                method.dup();
+                load(node.getIndex());
+                final Type indexType = node.getIndex().getType();
+                if (indexType.isObject() || indexType.isBoolean()) {
+                    method.convert(Type.OBJECT); //TODO
+                }
+                method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
+                method.swap();
+                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags());
+                assert method.peekType().equals(callNode.getType());
+
+                return null;
+            }
+
+            @Override
+            protected Node enterDefault(final Node node) {
+                // Load up function.
+                load(function);
+                method.convert(Type.OBJECT); //TODO, e.g. booleans can be used as functions
+                method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
+                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
+                assert method.peekType().equals(callNode.getType());
+
+                return null;
+            }
+        });
+
+        method.store(callNode.getSymbol());
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final ContinueNode continueNode) {
+        if (continueNode.testResolved()) {
+            return null;
+        }
+
+        for (int i = 0; i < continueNode.getScopeNestingLevel(); i++) {
+            closeWith();
+        }
+
+        method.splitAwareGoto(continueNode.getTargetLabel());
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final DoWhileNode doWhileNode) {
+        return enter((WhileNode)doWhileNode);
+    }
+
+    @Override
+    public Node enter(final EmptyNode emptyNode) {
+        return null;
+    }
+
+    @Override
+    public Node enter(final ExecuteNode executeNode) {
+        if (executeNode.testResolved()) {
+            return null;
+        }
+
+        final Node expression = executeNode.getExpression();
+        expression.accept(this);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final ForNode forNode) {
+        if (forNode.testResolved()) {
+            return null;
+        }
+
+        final Node  test   = forNode.getTest();
+        final Block body   = forNode.getBody();
+        final Node  modify = forNode.getModify();
+
+        final Label breakLabel    = forNode.getBreakLabel();
+        final Label continueLabel = forNode.getContinueLabel();
+        final Label loopLabel     = new Label("loop");
+
+        Node init = forNode.getInit();
+
+        if (forNode.isForIn()) {
+            final Symbol iter = forNode.getIterator();
+
+            // We have to evaluate the optional initializer expression
+            // of the iterator variable of the for-in statement.
+            if (init instanceof VarNode) {
+                init.accept(this);
+                init = ((VarNode)init).getName();
+            }
+
+            load(modify);
+            assert modify.getType().isObject();
+            method.invoke(forNode.isForEach() ? ScriptRuntime.TO_VALUE_ITERATOR : ScriptRuntime.TO_PROPERTY_ITERATOR);
+            method.store(iter);
+            method._goto(continueLabel);
+            method.label(loopLabel);
+
+            new Store<Node>(init) {
+                @Override
+                protected void evaluate() {
+                    method.load(iter);
+                    method.invoke(interfaceCallNoLookup(Iterator.class, "next", Object.class));
+                }
+            }.store();
+
+            body.accept(this);
+
+            method.label(continueLabel);
+            method.load(iter);
+            method.invoke(interfaceCallNoLookup(Iterator.class, "hasNext", boolean.class));
+            method.ifne(loopLabel);
+            method.label(breakLabel);
+        } else {
+            if (init != null) {
+                init.accept(this);
+            }
+
+            final Label testLabel = new Label("test");
+
+            method._goto(testLabel);
+            method.label(loopLabel);
+            body.accept(this);
+            method.label(continueLabel);
+
+            if (!body.isTerminal() && modify != null) {
+                load(modify);
+            }
+
+            method.label(testLabel);
+            if (test != null) {
+                new BranchOptimizer(this, method).execute(test, loopLabel, true);
+            } else {
+                method._goto(loopLabel);
+            }
+
+            method.label(breakLabel);
+        }
+
+        return null;
+    }
+
+    /**
+     * Initialize the slots in a frame to undefined.
+     *
+     * @param block block with local vars.
+     */
+    private void initLocals(final Block block) {
+        final FunctionNode function       = block.getFunction();
+        final boolean      isFunctionNode = block == function;
+
+        /*
+         * Get the symbols from the frame and realign the frame so that all
+         * slots get correct numbers. The slot numbering is not fixed until
+         * after initLocals has been run
+         */
+        final Frame        frame   = block.getFrame();
+        final List<Symbol> symbols = frame.getSymbols();
+
+        /* Fix the predefined slots so they have numbers >= 0, like varargs. */
+        frame.realign();
+
+        if (isFunctionNode) {
+            if (function.needsParentScope()) {
+                initParentScope();
+            }
+            if (function.needsArguments()) {
+                initArguments(function);
+            }
+        }
+
+        /*
+         * Determine if block needs scope, if not, just do initSymbols for this block.
+         */
+        if (block.needsScope()) {
+            /*
+             * Determine if function is varargs and consequently variables have to
+             * be in the scope.
+             */
+            final boolean varsInScope = function.allVarsInScope();
+
+            // TODO for LET we can do better: if *block* does not contain any eval/with, we don't need its vars in scope.
+
+            final List<String> nameList = new ArrayList<>();
+            final List<Symbol> locals   = new ArrayList<>();
+
+
+            // Initalize symbols and values
+            final List<Symbol> newSymbols = new ArrayList<>();
+            final List<Symbol> values     = new ArrayList<>();
+
+            final boolean hasArguments = function.needsArguments();
+            for (final Symbol symbol : symbols) {
+                if (symbol.isInternal() || symbol.isThis()) {
+                    continue;
+                }
+
+                if (symbol.isVar()) {
+                    if(varsInScope || symbol.isScope()) {
+                        nameList.add(symbol.getName());
+                        newSymbols.add(symbol);
+                        values.add(null);
+                        assert symbol.isScope()   : "scope for " + symbol + " should have been set in Lower already " + function.getName();
+                        assert !symbol.hasSlot()  : "slot for " + symbol + " should have been removed in Lower already" + function.getName();
+                    } else {
+                        assert symbol.hasSlot() : symbol + " should have a slot only, no scope";
+                        locals.add(symbol);
+                    }
+                } else if (symbol.isParam() && (varsInScope || hasArguments || symbol.isScope())) {
+                    nameList.add(symbol.getName());
+                    newSymbols.add(symbol);
+                    values.add(hasArguments ? null : symbol);
+                    assert symbol.isScope()   : "scope for " + symbol + " should have been set in Lower already " + function.getName() + " varsInScope="+varsInScope+" hasArguments="+hasArguments+" symbol.isScope()=" + symbol.isScope();
+                    assert !(hasArguments && symbol.hasSlot())  : "slot for " + symbol + " should have been removed in Lower already " + function.getName();
+                }
+            }
+
+            /* Correct slot numbering again */
+            frame.realign();
+
+            // we may have locals that need to be initialized
+            initSymbols(locals);
+
+            /*
+             * Create a new object based on the symbols and values, generate
+             * bootstrap code for object
+             */
+            final FieldObjectCreator<Symbol> foc = new FieldObjectCreator<Symbol>(this, nameList, newSymbols, values, true, hasArguments) {
+                @Override
+                protected Type getValueType(final Symbol value) {
+                    return value.getSymbolType();
+                }
+
+                @Override
+                protected void loadValue(final Symbol value) {
+                    method.load(value);
+                }
+
+                @Override
+                protected void loadScope(MethodEmitter m) {
+                    if(function.needsParentScope()) {
+                        m.loadScope();
+                    } else {
+                        m.loadNull();
+                    }
+                }
+            };
+            foc.makeObject(method);
+
+            // runScript(): merge scope into global
+            if (isFunctionNode && function.isScript()) {
+                method.invoke(ScriptRuntime.MERGE_SCOPE);
+            }
+
+            method.storeScope();
+        } else {
+            // Since we don't have a scope, parameters didn't get assigned array indices by the FieldObjectCreator, so
+            // we need to assign them separately here.
+            int nextParam = 0;
+            if (isFunctionNode && function.isVarArg()) {
+                for (final IdentNode param : function.getParameters()) {
+                    param.getSymbol().setFieldIndex(nextParam++);
+                }
+            }
+            initSymbols(symbols);
+        }
+
+        // Debugging: print symbols? @see --print-symbols flag
+        printSymbols(block, (isFunctionNode ? "Function " : "Block in ") + (function.getIdent() == null ? "<anonymous>" : function.getIdent().getName()));
+    }
+
+    private void initArguments(final FunctionNode function) {
+        method.loadVarArgs();
+        if(function.needsCallee()) {
+            method.loadCallee();
+        } else {
+            // If function is strict mode, "arguments.callee" is not populated, so we don't necessarily need the
+            // caller.
+            assert function.isStrictMode();
+            method.loadNull();
+        }
+        method.load(function.getParameters().size());
+        globalAllocateArguments();
+        method.storeArguments();
+    }
+
+    private void initParentScope() {
+        method.loadCallee();
+        method.invoke(ScriptFunction.GET_SCOPE);
+        method.storeScope();
+    }
+
+    @Override
+    public Node enter(final FunctionNode functionNode) {
+        if (functionNode.isLazy()) {
+            return null;
+        }
+
+        if (functionNode.testResolved()) {
+            return null;
+        }
+
+        setCurrentCompileUnit(functionNode.getCompileUnit());
+        assert getCurrentCompileUnit() != null;
+
+        method = getCurrentCompileUnit().getClassEmitter().method(functionNode);
+        functionNode.setMethodEmitter(method);
+        // Mark end for variable tables.
+        method.begin();
+        method.label(functionNode.getEntryLabel());
+
+        initLocals(functionNode);
+
+        return functionNode;
+    }
+
+    @Override
+    public Node leave(final FunctionNode functionNode) {
+        // Mark end for variable tables.
+        method.label(functionNode.getBreakLabel());
+
+        if (!functionNode.needsScope()) {
+            method.markerVariable(LEAF.tag(), functionNode.getEntryLabel(), functionNode.getBreakLabel());
+        }
+
+        symbolInfo(functionNode);
+        try {
+            method.end(); // wrap up this method
+        } catch (final Throwable t) {
+            Context.printStackTrace(t);
+            final VerifyError e = new VerifyError("Code generation bug in \"" + functionNode.getName() + "\": likely stack misaligned: " + t + " " + functionNode.getSource().getName());
+            e.initCause(t);
+            throw e;
+        }
+
+        return functionNode;
+    }
+
+    @Override
+    public Node enter(final IdentNode identNode) {
+        return null;
+    }
+
+    @Override
+    public Node enter(final IfNode ifNode) {
+        if (ifNode.testResolved()) {
+            return null;
+        }
+
+        final Node  test = ifNode.getTest();
+        final Block pass = ifNode.getPass();
+        final Block fail = ifNode.getFail();
+
+        final Label failLabel  = new Label("if_fail");
+        final Label afterLabel = fail == null ? failLabel : new Label("if_done");
+
+        new BranchOptimizer(this, method).execute(test, failLabel, false);
+
+        boolean passTerminal = false;
+        boolean failTerminal = false;
+
+        pass.accept(this);
+        if (!pass.hasTerminalFlags()) {
+            method._goto(afterLabel); //don't fallthru to fail block
+        } else {
+            passTerminal = pass.isTerminal();
+        }
+
+        if (fail != null) {
+            method.label(failLabel);
+            fail.accept(this);
+            failTerminal = fail.isTerminal();
+        }
+
+        //if if terminates, put the after label there
+        if (!passTerminal || !failTerminal) {
+            method.label(afterLabel);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final IndexNode indexNode) {
+        if (indexNode.testResolved()) {
+            return null;
+        }
+
+        load(indexNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final LineNumberNode lineNumberNode) {
+        if (lineNumberNode.testResolved()) {
+            return null;
+        }
+
+        final Label label = new Label("line:" + lineNumberNode.getLineNumber() + " (" + getCurrentFunctionNode().getName() + ")");
+        method.label(label);
+        method.lineNumber(lineNumberNode.getLineNumber(), label);
+
+        return null;
+    }
+
+    /**
+     * Load a list of nodes as an array of a specific type
+     * The array will contain the visited nodes.
+     *
+     * @param arrayLiteralNode the array of contents
+     * @param arrayType        the type of the array, e.g. ARRAY_NUMBER or ARRAY_OBJECT
+     *
+     * @return the method generator that was used
+     */
+    private MethodEmitter loadArray(final ArrayLiteralNode arrayLiteralNode, final ArrayType arrayType) {
+        assert arrayType == Type.INT_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY;
+
+        final Node[]          nodes    = arrayLiteralNode.getValue();
+        final Object          presets  = arrayLiteralNode.getPresets();
+        final int[]           postsets = arrayLiteralNode.getPostsets();
+        final Class<?>        type     = arrayType.getTypeClass();
+        final List<ArrayUnit> units    = arrayLiteralNode.getUnits();
+
+        loadConstant(presets);
+
+        final Type elementType = arrayType.getElementType();
+
+        if (units != null) {
+            final CompileUnit   savedCompileUnit = getCurrentCompileUnit();
+            final MethodEmitter savedMethod      = getCurrentMethodEmitter();
+
+            try {
+                for (final ArrayUnit unit : units) {
+                    setCurrentCompileUnit(unit.getCompileUnit());
+
+                    final String className = getCurrentCompileUnit().getUnitClassName();
+                    final String name      = getCurrentFunctionNode().uniqueName(SPLIT_PREFIX.tag());
+                    final String signature = methodDescriptor(type, Object.class, ScriptFunction.class, ScriptObject.class, type);
+
+                    method = getCurrentCompileUnit().getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature);
+                    method.setFunctionNode(getCurrentFunctionNode());
+                    method.begin();
+
+                    fixScopeSlot();
+
+                    method.load(arrayType, SPLIT_ARRAY_ARG.slot());
+
+                    for (int i = unit.getLo(); i < unit.getHi(); i++) {
+                        storeElement(nodes, elementType, postsets[i]);
+                    }
+
+                    method._return();
+                    method.end();
+
+                    savedMethod.loadThis();
+                    savedMethod.swap();
+                    savedMethod.loadCallee();
+                    savedMethod.swap();
+                    savedMethod.loadScope();
+                    savedMethod.swap();
+                    savedMethod.invokestatic(className, name, signature);
+                }
+            } finally {
+                setCurrentCompileUnit(savedCompileUnit);
+                setCurrentMethodEmitter(savedMethod);
+            }
+
+            return method;
+        }
+
+        for (final int postset : postsets) {
+            storeElement(nodes, elementType, postset);
+        }
+
+        return method;
+    }
+
+    private void storeElement(final Node[] nodes, final Type elementType, final int index) {
+        method.dup();
+        method.load(index);
+
+        final Node element = nodes[index];
+
+        if (element == null) {
+            method.loadEmpty(elementType);
+        } else {
+            assert elementType.isEquivalentTo(element.getType()) : "array element type doesn't match array type";
+            load(element);
+        }
+
+        method.arraystore();
+    }
+
+    private MethodEmitter loadArgsArray(final List<Node> args) {
+        final Object[] array = new Object[args.size()];
+        loadConstant(array);
+
+        for (int i = 0; i < args.size(); i++) {
+            method.dup();
+            method.load(i);
+            load(args.get(i)).convert(Type.OBJECT); //has to be upcast to object or we fail
+            method.arraystore();
+        }
+
+        return method;
+    }
+
+    /**
+     * Load a constant from the constant array. This is only public to be callable from the objects
+     * subpackage. Do not call directly.
+     *
+     * @param string string to load
+     */
+    void loadConstant(final String string) {
+        final String       unitClassName = getCurrentCompileUnit().getUnitClassName();
+        final ClassEmitter classEmitter  = getCurrentCompileUnit().getClassEmitter();
+        final int          index         = compiler.getConstantData().add(string);
+
+        method.load(index);
+        method.invokestatic(unitClassName, GET_STRING.tag(), methodDescriptor(String.class, int.class));
+        classEmitter.needGetConstantMethod(String.class);
+    }
+
+    /**
+     * Load a constant from the constant array. This is only public to be callable from the objects
+     * subpackage. Do not call directly.
+     *
+     * @param object object to load
+     */
+    void loadConstant(final Object object) {
+        final String       unitClassName = getCurrentCompileUnit().getUnitClassName();
+        final ClassEmitter classEmitter  = getCurrentCompileUnit().getClassEmitter();
+        final int          index         = compiler.getConstantData().add(object);
+        final Class<?>     cls           = object.getClass();
+
+        if (cls == PropertyMap.class) {
+            method.load(index);
+            method.invokestatic(unitClassName, GET_MAP.tag(), methodDescriptor(PropertyMap.class, int.class));
+            classEmitter.needGetConstantMethod(PropertyMap.class);
+        } else if (cls.isArray()) {
+            method.load(index);
+            final String methodName = ClassEmitter.getArrayMethodName(cls);
+            method.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class));
+            classEmitter.needGetConstantMethod(cls);
+        } else {
+            method.loadConstants(unitClassName).load(index).arrayload();
+            if (cls != Object.class) {
+                method.checkcast(cls);
+            }
+        }
+    }
+
+    // literal values
+    private MethodEmitter load(final LiteralNode<?> node) {
+        final Object value = node.getValue();
+
+        if (value == null) {
+            method.loadNull();
+        } else if (value instanceof Undefined) {
+            method.loadUndefined(Type.OBJECT);
+        } else if (value instanceof String) {
+            final String string = (String)value;
+
+            if (string.length() > (MethodEmitter.LARGE_STRING_THRESHOLD / 3)) { // 3 == max bytes per encoded char
+                loadConstant(string);
+            } else {
+                method.load(string);
+            }
+        } else if (value instanceof RegexToken) {
+            loadRegex((RegexToken)value);
+        } else if (value instanceof Boolean) {
+            method.load((Boolean)value);
+        } else if (value instanceof Integer) {
+            method.load((Integer)value);
+        } else if (value instanceof Long) {
+            method.load((Long)value);
+        } else if (value instanceof Double) {
+            method.load((Double)value);
+        } else if (node instanceof ArrayLiteralNode) {
+            final ArrayType type = (ArrayType)node.getType();
+            loadArray((ArrayLiteralNode)node, type);
+            globalAllocateArray(type);
+        } else {
+            assert false : "Unknown literal for " + node.getClass() + " " + value.getClass() + " " + value;
+        }
+
+        return method;
+    }
+
+    private MethodEmitter loadRegexToken(final RegexToken value) {
+        method.load(value.getExpression());
+        method.load(value.getOptions());
+        return globalNewRegExp();
+    }
+
+    private MethodEmitter loadRegex(final RegexToken regexToken) {
+        if (regexFieldCount > MAX_REGEX_FIELDS) {
+            return loadRegexToken(regexToken);
+        }
+        // emit field
+        final String       regexName    = getCurrentFunctionNode().uniqueName(REGEX_PREFIX.tag());
+        final ClassEmitter classEmitter = getCurrentCompileUnit().getClassEmitter();
+
+        classEmitter.field(EnumSet.of(PRIVATE, STATIC), regexName, Object.class);
+        regexFieldCount++;
+
+        // get field, if null create new regex, finally clone regex object
+        method.getStatic(getCurrentCompileUnit().getUnitClassName(), regexName, typeDescriptor(Object.class));
+        method.dup();
+        final Label cachedLabel = new Label("cached");
+        method.ifnonnull(cachedLabel);
+
+        method.pop();
+        loadRegexToken(regexToken);
+        method.dup();
+        method.putStatic(getCurrentCompileUnit().getUnitClassName(), regexName, typeDescriptor(Object.class));
+
+        method.label(cachedLabel);
+        globalRegExpCopy();
+
+        return method;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Node enter(final LiteralNode literalNode) {
+        assert literalNode.getSymbol() != null : literalNode + " has no symbol";
+        load(literalNode).store(literalNode.getSymbol());
+        return null;
+    }
+
+    @Override
+    public Node enter(final ObjectNode objectNode) {
+        if (objectNode.testResolved()) {
+            return null;
+        }
+
+        final List<Node> elements = objectNode.getElements();
+        final int        size     = elements.size();
+
+        final List<String> keys    = new ArrayList<>();
+        final List<Symbol> symbols = new ArrayList<>();
+        final List<Node>   values  = new ArrayList<>();
+
+        boolean hasGettersSetters = false;
+
+        for (int i = 0; i < size; i++) {
+            final PropertyNode propertyNode = (PropertyNode)elements.get(i);
+            final Node         value        = propertyNode.getValue();
+            final String       key          = propertyNode.getKeyName();
+            final Symbol       symbol       = value == null ? null : propertyNode.getSymbol();
+
+            if (value == null) {
+                hasGettersSetters = true;
+            }
+
+            keys.add(key);
+            symbols.add(symbol);
+            values.add(value);
+        }
+
+        new FieldObjectCreator<Node>(this, keys, symbols, values) {
+            @Override
+            protected Type getValueType(final Node node) {
+                return node.getType();
+            }
+
+            @Override
+            protected void loadValue(final Node node) {
+                load(node);
+            }
+
+            /**
+             * Ensure that the properties start out as object types so that
+             * we can do putfield initializations instead of dynamicSetIndex
+             * which would be the case to determine initial property type
+             * otherwise.
+             *
+             * Use case, it's very expensive to do a million var x = {a:obj, b:obj}
+             * just to have to invalidate them immediately on initialization
+             *
+             * see NASHORN-594
+             */
+            @Override
+            protected MapCreator newMapCreator(final Class<?> fieldObjectClass) {
+                return new MapCreator(fieldObjectClass, keys, symbols) {
+                    @Override
+                    protected int getPropertyFlags(final Symbol symbol, final boolean isVarArg) {
+                        return super.getPropertyFlags(symbol, isVarArg) | Property.IS_ALWAYS_OBJECT;
+                    }
+                };
+            }
+
+        }.makeObject(method);
+
+        method.dup();
+        globalObjectPrototype();
+        method.invoke(ScriptObject.SET_PROTO);
+
+        if (!hasGettersSetters) {
+            method.store(objectNode.getSymbol());
+            return null;
+        }
+
+        for (final Node element : elements) {
+            final PropertyNode  propertyNode = (PropertyNode)element;
+            final Object        key          = propertyNode.getKey();
+            final ReferenceNode getter       = (ReferenceNode)propertyNode.getGetter();
+            final ReferenceNode setter       = (ReferenceNode)propertyNode.getSetter();
+
+            if (getter == null && setter == null) {
+                continue;
+            }
+
+            method.dup().loadKey(key);
+
+            if (getter == null) {
+                method.loadNull();
+            } else {
+                getter.accept(this);
+            }
+
+            if (setter == null) {
+                method.loadNull();
+            } else {
+                setter.accept(this);
+            }
+
+            method.invoke(ScriptObject.SET_USER_ACCESSORS);
+        }
+
+        method.store(objectNode.getSymbol());
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final ReferenceNode referenceNode) {
+        if (referenceNode.testResolved()) {
+            return null;
+        }
+
+        newFunctionObject(referenceNode.getReference());
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final ReturnNode returnNode) {
+        if (returnNode.testResolved()) {
+            return null;
+        }
+
+        // Set the split return flag in the scope if this is a split method fragment.
+        if (method.getSplitNode() != null) {
+            assert method.getSplitNode().hasReturn() : "unexpected return in split node";
+
+            method.loadScope();
+            method.checkcast(Scope.class);
+            method.load(0);
+            method.invoke(Scope.SET_SPLIT_STATE);
+        }
+
+        final Node expression = returnNode.getExpression();
+        if (expression != null) {
+            load(expression);
+        } else {
+            method.loadUndefined(getCurrentFunctionNode().getReturnType());
+        }
+
+        method._return(getCurrentFunctionNode().getReturnType());
+
+        return null;
+    }
+
+    private static boolean isNullLiteral(final Node node) {
+        return node instanceof LiteralNode<?> && ((LiteralNode<?>) node).isNull();
+    }
+
+    private boolean nullCheck(final RuntimeNode runtimeNode, final List<Node> args, final String signature) {
+        final Request request = runtimeNode.getRequest();
+
+        if (!Request.isEQ(request) && !Request.isNE(request)) {
+            return false;
+        }
+
+        assert args.size() == 2 : "EQ or NE or TYPEOF need two args";
+
+        Node lhs = args.get(0);
+        Node rhs = args.get(1);
+
+        if (isNullLiteral(lhs)) {
+            final Node tmp = lhs;
+            lhs = rhs;
+            rhs = tmp;
+        }
+
+        if (isNullLiteral(rhs)) {
+            final Label trueLabel  = new Label("trueLabel");
+            final Label falseLabel = new Label("falseLabel");
+            final Label endLabel   = new Label("end");
+
+            load(lhs);
+            method.dup();
+            if (Request.isEQ(request)) {
+                method.ifnull(trueLabel);
+            } else if (Request.isNE(request)) {
+                method.ifnonnull(trueLabel);
+            } else {
+                assert false : "Invalid request " + request;
+            }
+
+            method.label(falseLabel);
+            load(rhs);
+            method.invokestatic(CompilerConstants.className(ScriptRuntime.class), request.toString(), signature);
+            method._goto(endLabel);
+
+            method.label(trueLabel);
+            // if NE (not strict) this can be "undefined != null" which is supposed to be false
+            if (request == Request.NE) {
+                method.loadUndefined(Type.OBJECT);
+                final Label isUndefined = new Label("isUndefined");
+                final Label afterUndefinedCheck = new Label("afterUndefinedCheck");
+                method.if_acmpeq(isUndefined);
+                // not undefined
+                method.load(true);
+                method._goto(afterUndefinedCheck);
+                method.label(isUndefined);
+                method.load(false);
+                method.label(afterUndefinedCheck);
+            } else {
+                method.pop();
+                method.load(true);
+            }
+            method.label(endLabel);
+            method.convert(runtimeNode.getType());
+            method.store(runtimeNode.getSymbol());
+
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean specializationCheck(final RuntimeNode.Request request, final Node node, final List<Node> args) {
+        if (!request.canSpecialize()) {
+            return false;
+        }
+
+        assert args.size() == 2;
+        final Node lhs = args.get(0);
+        final Node rhs = args.get(1);
+
+        final Type returnType = node.getType();
+        load(lhs);
+        load(rhs);
+
+        Request finalRequest = request;
+
+        final Request reverse = Request.reverse(request);
+        if (method.peekType().isObject() && reverse != null) {
+            if (!method.peekType(1).isObject()) {
+                method.swap();
+                finalRequest = reverse;
+            }
+        }
+
+        method.dynamicRuntimeCall(
+                new SpecializedRuntimeNode(
+                    finalRequest,
+                    new Type[] {
+                        method.peekType(1),
+                        method.peekType()
+                    },
+                    returnType).getInitialName(),
+                returnType,
+                finalRequest);
+
+        method.convert(node.getType());
+        method.store(node.getSymbol());
+
+        return true;
+    }
+
+    private static boolean isReducible(final Request request) {
+        return Request.isComparison(request) || request == Request.ADD;
+    }
+
+    @Override
+    public Node enter(final RuntimeNode runtimeNode) {
+        if (runtimeNode.testResolved()) {
+            return null;
+        }
+
+        /*
+         * First check if this should be something other than a runtime node
+         * AccessSpecializer might have changed the type
+         *
+         * TODO - remove this - Access Specializer will always know after Attr/Lower
+         */
+        if (runtimeNode.isPrimitive() && !runtimeNode.isFinal() && isReducible(runtimeNode.getRequest())) {
+            final Node lhs = runtimeNode.getArgs().get(0);
+            assert runtimeNode.getArgs().size() > 1 : runtimeNode + " must have two args";
+            final Node rhs = runtimeNode.getArgs().get(1);
+
+            final Type   type   = runtimeNode.getType();
+            final Symbol symbol = runtimeNode.getSymbol();
+
+            switch (runtimeNode.getRequest()) {
+            case EQ:
+            case EQ_STRICT:
+                return enterCmp(lhs, rhs, Condition.EQ, type, symbol);
+            case NE:
+            case NE_STRICT:
+                return enterCmp(lhs, rhs, Condition.NE, type, symbol);
+            case LE:
+                return enterCmp(lhs, rhs, Condition.LE, type, symbol);
+            case LT:
+                return enterCmp(lhs, rhs, Condition.LT, type, symbol);
+            case GE:
+                return enterCmp(lhs, rhs, Condition.GE, type, symbol);
+            case GT:
+                return enterCmp(lhs, rhs, Condition.GT, type, symbol);
+            case ADD:
+                Type widest = Type.widest(lhs.getType(), rhs.getType());
+                load(lhs);
+                method.convert(widest);
+                load(rhs);
+                method.convert(widest);
+                method.add();
+                method.convert(type);
+                method.store(symbol);
+                return null;
+            default:
+                // it's ok to send this one on with only primitive arguments, maybe INSTANCEOF(true, true) or similar
+                // assert false : runtimeNode + " has all primitive arguments. This is an inconsistent state";
+                break;
+            }
+        }
+
+        // Get the request arguments.
+        final List<Node> args = runtimeNode.getArgs();
+
+        if (nullCheck(runtimeNode, args, new FunctionSignature(false, false, runtimeNode.getType(), args).toString())) {
+            return null;
+        }
+
+        if (!runtimeNode.isFinal() && specializationCheck(runtimeNode.getRequest(), runtimeNode, args)) {
+            return null;
+        }
+
+        for (final Node arg : runtimeNode.getArgs()) {
+            load(arg).convert(Type.OBJECT); //TODO this should not be necessary below Lower
+        }
+
+        method.invokestatic(
+            CompilerConstants.className(ScriptRuntime.class),
+            runtimeNode.getRequest().toString(),
+            new FunctionSignature(
+                false,
+                false,
+                runtimeNode.getType(),
+                runtimeNode.getArgs().size()).toString());
+        method.convert(runtimeNode.getType());
+        method.store(runtimeNode.getSymbol());
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final SplitNode splitNode) {
+        if (splitNode.testResolved()) {
+            return null;
+        }
+
+        final CompileUnit splitCompileUnit = splitNode.getCompileUnit();
+
+        final FunctionNode fn   = getCurrentFunctionNode();
+        final String className  = splitCompileUnit.getUnitClassName();
+        final String name       = splitNode.getName();
+
+        final Class<?>   rtype  = fn.getReturnType().getTypeClass();
+        final boolean needsArguments = fn.needsArguments();
+        final Class<?>[] ptypes = needsArguments ?
+                new Class<?>[] {ScriptFunction.class, Object.class, ScriptObject.class, Object.class} :
+                new Class<?>[] {ScriptFunction.class, Object.class, ScriptObject.class};
+
+        setCurrentCompileUnit(splitCompileUnit);
+        splitNode.setCompileUnit(splitCompileUnit);
+
+        final Call splitCall = staticCallNoLookup(
+            className,
+            name,
+            methodDescriptor(rtype, ptypes));
+
+        setCurrentMethodEmitter(
+            splitCompileUnit.getClassEmitter().method(
+                EnumSet.of(Flag.PUBLIC, Flag.STATIC),
+                name,
+                rtype,
+                ptypes));
+
+        method.setFunctionNode(fn);
+        method.setSplitNode(splitNode);
+        splitNode.setMethodEmitter(method);
+
+        final MethodEmitter caller = splitNode.getCaller();
+        if(fn.needsCallee()) {
+            caller.loadCallee();
+        } else {
+            caller.loadNull();
+        }
+        caller.loadThis();
+        caller.loadScope();
+        if (needsArguments) {
+            caller.loadArguments();
+        }
+        caller.invoke(splitCall);
+        caller.storeResult();
+
+        method.begin();
+
+        method.loadUndefined(fn.getReturnType());
+        method.storeResult();
+
+        fixScopeSlot();
+
+        return splitNode;
+    }
+
+    private void fixScopeSlot() {
+        if (getCurrentFunctionNode().getScopeNode().getSymbol().getSlot() != SCOPE.slot()) {
+            // TODO hack to move the scope to the expected slot (that's needed because split methods reuse the same slots as the root method)
+            method.load(Type.typeFor(ScriptObject.class), SCOPE.slot());
+            method.storeScope();
+        }
+    }
+
+    @Override
+    public Node leave(final SplitNode splitNode) {
+        try {
+            // Wrap up this method.
+            method.loadResult();
+            method._return(getCurrentFunctionNode().getReturnType());
+            method.end();
+        } catch (final Throwable t) {
+            Context.printStackTrace(t);
+            final VerifyError e = new VerifyError("Code generation bug in \"" + splitNode.getName() + "\": likely stack misaligned: " + t + " " + getCurrentFunctionNode().getSource().getName());
+            e.initCause(t);
+            throw e;
+        }
+
+        // Handle return from split method if there was one.
+        final MethodEmitter caller      = splitNode.getCaller();
+        final List<Label>   targets     = splitNode.getExternalTargets();
+        final int           targetCount = targets.size();
+
+        if (splitNode.hasReturn() || targetCount > 0) {
+
+            caller.loadScope();
+            caller.checkcast(Scope.class);
+            caller.invoke(Scope.GET_SPLIT_STATE);
+
+            // Split state is -1 for no split state, 0 for return, 1..n+1 for break/continue
+            final Label   breakLabel = new Label("no_split_state");
+            final int     low        = splitNode.hasReturn() ? 0 : 1;
+            final int     labelCount = targetCount + 1 - low;
+            final Label[] labels     = new Label[labelCount];
+
+            for (int i = 0; i < labelCount; i++) {
+                labels[i] = new Label("split_state_" + i);
+            }
+
+            caller.tableswitch(low, targetCount, breakLabel, labels);
+            for (int i = low; i <= targetCount; i++) {
+                caller.label(labels[i - low]);
+                if (i == 0) {
+                    caller.loadResult();
+                    caller._return(getCurrentFunctionNode().getReturnType());
+                } else {
+                    // Clear split state.
+                    caller.loadScope();
+                    caller.checkcast(Scope.class);
+                    caller.load(-1);
+                    caller.invoke(Scope.SET_SPLIT_STATE);
+                    caller.splitAwareGoto(targets.get(i - 1));
+                }
+            }
+
+            caller.label(breakLabel);
+        }
+
+        return splitNode;
+    }
+
+    @Override
+    public Node enter(final SwitchNode switchNode) {
+        if (switchNode.testResolved()) {
+            return null;
+        }
+
+        final Node           expression  = switchNode.getExpression();
+        final Symbol         tag         = switchNode.getTag();
+        final boolean        allInteger  = tag.getSymbolType().isInteger();
+        final List<CaseNode> cases       = switchNode.getCases();
+        final CaseNode       defaultCase = switchNode.getDefaultCase();
+        final Label          breakLabel  = switchNode.getBreakLabel();
+
+        Label defaultLabel = breakLabel;
+        boolean hasDefault = false;
+
+        if (defaultCase != null) {
+            defaultLabel = defaultCase.getEntry();
+            hasDefault = true;
+        }
+
+        if (cases.isEmpty()) {
+            method.label(breakLabel);
+            return null;
+        }
+
+        if (allInteger) {
+            // Tree for sorting values.
+            final TreeMap<Integer, Label> tree = new TreeMap<>();
+
+            // Build up sorted tree.
+            for (final CaseNode caseNode : cases) {
+                final Node test = caseNode.getTest();
+
+                if (test != null) {
+                    final Integer value = (Integer)((LiteralNode<?>)test).getValue();
+                    final Label   entry = caseNode.getEntry();
+
+                    // Take first duplicate.
+                    if (!(tree.containsKey(value))) {
+                        tree.put(value, entry);
+                    }
+                }
+            }
+
+            // Copy values and labels to arrays.
+            final int       size   = tree.size();
+            final Integer[] values = tree.keySet().toArray(new Integer[size]);
+            final Label[]   labels = tree.values().toArray(new Label[size]);
+
+            // Discern low, high and range.
+            final int lo    = values[0];
+            final int hi    = values[size - 1];
+            final int range = hi - lo + 1;
+
+            // Find an unused value for default.
+            int deflt = Integer.MIN_VALUE;
+            for (final int value : values) {
+                if (deflt == value) {
+                    deflt++;
+                } else if (deflt < value) {
+                    break;
+                }
+            }
+
+            // Load switch expression.
+            load(expression);
+            final Type type = expression.getType();
+
+            // If expression not int see if we can convert, if not use deflt to trigger default.
+            if (!type.isInteger()) {
+                method.load(deflt);
+                method.invoke(staticCallNoLookup(ScriptRuntime.class, "switchTagAsInt", int.class, type.getTypeClass(), int.class));
+            }
+
+            // If reasonable size and not too sparse (80%), use table otherwise use lookup.
+            if (range > 0 && range < 4096 && range < (size * 5 / 4)) {
+                final Label[] table = new Label[range];
+                Arrays.fill(table, defaultLabel);
+
+                for (int i = 0; i < size; i++) {
+                    final int value = values[i];
+                    table[value - lo] = labels[i];
+                }
+
+                method.tableswitch(lo, hi, defaultLabel, table);
+            } else {
+                final int[] ints = new int[size];
+
+                for (int i = 0; i < size; i++) {
+                    ints[i] = values[i];
+                }
+
+                method.lookupswitch(defaultLabel, ints, labels);
+            }
+        } else {
+            load(expression);
+
+            if (expression.getType().isInteger()) {
+                method.convert(Type.NUMBER).dup();
+                method.store(tag);
+                method.conditionalJump(Condition.NE, true, defaultLabel);
+            } else {
+                method.store(tag);
+            }
+
+            for (final CaseNode caseNode : cases) {
+                final Node test = caseNode.getTest();
+
+                if (test != null) {
+                    method.load(tag);
+                    load(test);
+                    method.invoke(ScriptRuntime.EQ_STRICT);
+                    method.ifne(caseNode.getEntry());
+                }
+            }
+
+            method._goto(hasDefault ? defaultLabel : breakLabel);
+        }
+
+        for (final CaseNode caseNode : cases) {
+            method.label(caseNode.getEntry());
+            caseNode.getBody().accept(this);
+        }
+
+        if (!switchNode.isTerminal()) {
+            method.label(breakLabel);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final ThrowNode throwNode) {
+        if (throwNode.testResolved()) {
+            return null;
+        }
+
+        method._new(ECMAException.class).dup();
+
+        final Node   expression = throwNode.getExpression();
+        final Source source     = throwNode.getSource();
+        final int    position   = throwNode.position();
+        final int    line       = source.getLine(position);
+        final int    column     = source.getColumn(position);
+
+        load(expression);
+        assert expression.getType().isObject();
+
+        method.load(source.getName());
+        method.load(line);
+        method.load(column);
+        method.invoke(ECMAException.THROW_INIT);
+
+        method.athrow();
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final TryNode tryNode) {
+        if (tryNode.testResolved()) {
+            return null;
+        }
+
+        final Block       body        = tryNode.getBody();
+        final List<Block> catchBlocks = tryNode.getCatchBlocks();
+        final Symbol      symbol      = tryNode.getException();
+        final Label       entry       = new Label("try");
+        final Label       recovery    = new Label("catch");
+        final Label       exit        = tryNode.getExit();
+        final Label       skip        = new Label("skip");
+
+        method.label(entry);
+
+        body.accept(this);
+
+        if (!body.hasTerminalFlags()) {
+            method._goto(skip);
+        }
+
+        method.label(exit);
+
+        method._catch(recovery);
+        method.store(symbol);
+
+        for (int i = 0; i < catchBlocks.size(); i++) {
+            final Block saveBlock = getCurrentBlock();
+            final Block catchBlock = catchBlocks.get(i);
+
+            setCurrentBlock(catchBlock);
+
+            try {
+                enter(catchBlock);
+
+                final CatchNode catchNode          = (CatchNode)catchBlocks.get(i).getStatements().get(0);
+                final IdentNode exception          = catchNode.getException();
+                final Node      exceptionCondition = catchNode.getExceptionCondition();
+                final Block     catchBody          = catchNode.getBody();
+
+                if (catchNode.isSyntheticRethrow()) {
+                    // Generate catch body (inlined finally) and rethrow exception
+                    catchBody.accept(this);
+                    method.load(symbol).athrow();
+                    continue;
+                }
+
+                new Store<IdentNode>(exception) {
+                    @Override
+                    protected void evaluate() {
+                        /*
+                         * If caught object is an instance of ECMAException, then
+                         * bind obj.thrown to the script catch var. Or else bind the
+                         * caught object itself to the script catch var.
+                         */
+                        final Label notEcmaException = new Label("no_ecma_exception");
+
+                        method.load(symbol).dup()._instanceof(ECMAException.class).ifeq(notEcmaException);
+                        method.checkcast(ECMAException.class); //TODO is this necessary?
+                        method.getField(ECMAException.THROWN);
+                        method.label(notEcmaException);
+                    }
+                }.store();
+
+                final Label next;
+
+                if (exceptionCondition != null) {
+                    next = new Label("next");
+                    load(exceptionCondition).convert(Type.BOOLEAN).ifeq(next);
+                } else {
+                    next = null;
+                }
+
+                catchBody.accept(this);
+
+                if (i + 1 != catchBlocks.size() && !catchBody.hasTerminalFlags()) {
+                    method._goto(skip);
+                }
+
+                if (next != null) {
+                    if (i + 1 == catchBlocks.size()) {
+                        // no next catch block - rethrow if condition failed
+                        method._goto(skip);
+                        method.label(next);
+                        method.load(symbol).athrow();
+                    } else {
+                        method.label(next);
+                    }
+                }
+
+                leave(catchBlock);
+            } finally {
+                setCurrentBlock(saveBlock);
+            }
+        }
+
+        method.label(skip);
+        method._try(entry, exit, recovery, Throwable.class);
+
+        // Finally body is always inlined elsewhere so it doesn't need to be emitted
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final VarNode varNode) {
+        final Node init = varNode.getInit();
+
+        if (varNode.testResolved() || init == null) {
+            return null;
+        }
+
+        final Symbol varSymbol = varNode.getSymbol();
+        assert varSymbol != null : "variable node " + varNode + " requires a symbol";
+
+        assert method != null;
+
+        final boolean needsScope = varSymbol.isScope();
+        if (needsScope) {
+            method.loadScope();
+        }
+        load(init);
+
+        if (needsScope) {
+            int flags = CALLSITE_SCOPE | getCallSiteFlags();
+            final IdentNode identNode = varNode.getName();
+            final Type type = identNode.getType();
+            if (varSymbol.isFastScope(getCurrentFunctionNode())) {
+                storeFastScopeVar(type, varSymbol, flags);
+            } else {
+                method.dynamicSet(type, identNode.getName(), flags);
+            }
+        } else {
+            assert varNode.getType() == varNode.getName().getType() : "varNode type=" + varNode.getType() + " nametype=" + varNode.getName().getType() + " inittype=" + init.getType();
+
+            method.convert(varNode.getType()); // aw: convert moved here
+            method.store(varSymbol);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final WhileNode whileNode) {
+        if (whileNode.testResolved()) {
+            return null;
+        }
+
+        final Node  test          = whileNode.getTest();
+        final Block body          = whileNode.getBody();
+        final Label breakLabel    = whileNode.getBreakLabel();
+        final Label continueLabel = whileNode.getContinueLabel();
+        final Label loopLabel     = new Label("loop");
+
+        if (!(whileNode instanceof DoWhileNode)) {
+            method._goto(continueLabel);
+        }
+
+        method.label(loopLabel);
+        body.accept(this);
+        if (!whileNode.isTerminal()) {
+            method.label(continueLabel);
+            new BranchOptimizer(this, method).execute(test, loopLabel, true);
+            method.label(breakLabel);
+        }
+
+        return null;
+    }
+
+    private void closeWith() {
+        method.loadScope();
+        method.invoke(ScriptRuntime.CLOSE_WITH);
+        method.storeScope();
+    }
+
+    @Override
+    public Node enter(final WithNode withNode) {
+        if (withNode.testResolved()) {
+            return null;
+        }
+
+        final Node expression = withNode.getExpression();
+        final Node body       = withNode.getBody();
+
+        final Label tryLabel   = new Label("with_try");
+        final Label endLabel   = new Label("with_end");
+        final Label catchLabel = new Label("with_catch");
+        final Label exitLabel  = new Label("with_exit");
+
+        method.label(tryLabel);
+
+        method.loadScope();
+        load(expression);
+
+        assert expression.getType().isObject() : "with expression needs to be object: " + expression;
+
+        method.invoke(ScriptRuntime.OPEN_WITH);
+        method.storeScope();
+
+        body.accept(this);
+
+        if (!body.isTerminal()) {
+            closeWith();
+            method._goto(exitLabel);
+        }
+
+        method.label(endLabel);
+
+        method._catch(catchLabel);
+        closeWith();
+        method.athrow();
+
+        method.label(exitLabel);
+
+        method._try(tryLabel, endLabel, catchLabel);
+
+        return null;
+    }
+
+    @Override
+    public Node enterADD(final UnaryNode unaryNode) {
+        if (unaryNode.testResolved()) {
+            return null;
+        }
+
+        load(unaryNode.rhs());
+        assert unaryNode.rhs().getType().isNumber();
+        method.store(unaryNode.getSymbol());
+
+        return null;
+    }
+
+    @Override
+    public Node enterBIT_NOT(final UnaryNode unaryNode) {
+        if (unaryNode.testResolved()) {
+            return null;
+        }
+
+        load(unaryNode.rhs()).convert(Type.INT).load(-1).xor().store(unaryNode.getSymbol());
+
+        return null;
+    }
+
+    // do this better with convert calls to method. TODO
+    @Override
+    public Node enterCONVERT(final UnaryNode unaryNode) {
+        if (unaryNode.testResolved()) {
+            return null;
+        }
+
+        final Node rhs = unaryNode.rhs();
+        final Type to  = unaryNode.getType();
+
+        if (to.isObject() && rhs instanceof LiteralNode) {
+            final LiteralNode<?> literalNode = (LiteralNode<?>)rhs;
+            final Object value = literalNode.getValue();
+
+            if (value instanceof Number) {
+                assert !to.isArray() : "type hygiene - cannot convert number to array: (" + to.getTypeClass().getSimpleName() + ')' + value;
+                if (value instanceof Integer) {
+                    method.load((Integer)value);
+                } else if (value instanceof Long) {
+                    method.load((Long)value);
+                } else if (value instanceof Double) {
+                    method.load((Double)value);
+                } else {
+                    assert false;
+                }
+                method.convert(Type.OBJECT);
+            } else if (value instanceof Boolean) {
+                method.getField(staticField(Boolean.class, value.toString().toUpperCase(), Boolean.class));
+            } else {
+                load(rhs);
+                method.convert(unaryNode.getType());
+            }
+        } else {
+            load(rhs);
+            method.convert(unaryNode.getType());
+        }
+
+        method.store(unaryNode.getSymbol());
+
+        return null;
+    }
+
+    @Override
+    public Node enterDECINC(final UnaryNode unaryNode) {
+        if (unaryNode.testResolved()) {
+            return null;
+        }
+
+        final Node      rhs         = unaryNode.rhs();
+        final Type      type        = unaryNode.getType();
+        final TokenType tokenType   = unaryNode.tokenType();
+        final boolean   isPostfix   = tokenType == TokenType.DECPOSTFIX || tokenType == TokenType.INCPOSTFIX;
+        final boolean   isIncrement = tokenType == TokenType.INCPREFIX || tokenType == TokenType.INCPOSTFIX;
+
+        assert !type.isObject();
+
+        new SelfModifyingStore<UnaryNode>(unaryNode, rhs) {
+
+            @Override
+            protected void evaluate() {
+                load(rhs, true);
+
+                method.convert(type);
+                if (!isPostfix) {
+                    if (type.isInteger()) {
+                        method.load(isIncrement ? 1 : -1);
+                    } else if (type.isLong()) {
+                        method.load(isIncrement ? 1L : -1L);
+                    } else {
+                        method.load(isIncrement ? 1.0 : -1.0);
+                    }
+                    method.add();
+                }
+            }
+
+            @Override
+            protected void storeNonDiscard() {
+                super.storeNonDiscard();
+                if (isPostfix) {
+                    if (type.isInteger()) {
+                        method.load(isIncrement ? 1 : -1);
+                    } else if (type.isLong()) {
+                        method.load(isIncrement ? 1L : 1L);
+                    } else {
+                        method.load(isIncrement ? 1.0 : -1.0);
+                    }
+                    method.add();
+                }
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterDISCARD(final UnaryNode unaryNode) {
+        if (unaryNode.testResolved()) {
+            return null;
+        }
+
+        final Node rhs = unaryNode.rhs();
+
+        load(rhs);
+
+        if (rhs.shouldDiscard()) {
+            method.pop();
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enterNEW(final UnaryNode unaryNode) {
+        if (unaryNode.testResolved()) {
+            return null;
+        }
+
+        final CallNode callNode = (CallNode)unaryNode.rhs();
+        final List<Node> args   = callNode.getArgs();
+
+        // Load function reference.
+        load(callNode.getFunction()).convert(Type.OBJECT); // must detect type error
+
+        method.dynamicNew(1 + loadArgs(args), getCallSiteFlags());
+        method.store(unaryNode.getSymbol());
+
+        return null;
+    }
+
+    @Override
+    public Node enterNOT(final UnaryNode unaryNode) {
+        if (unaryNode.testResolved()) {
+            return null;
+        }
+
+        final Node rhs = unaryNode.rhs();
+
+        load(rhs);
+
+        final Label trueLabel  = new Label("true");
+        final Label afterLabel = new Label("after");
+
+        method.convert(Type.BOOLEAN);
+        method.ifne(trueLabel);
+        method.load(true);
+        method._goto(afterLabel);
+        method.label(trueLabel);
+        method.load(false);
+        method.label(afterLabel);
+        method.store(unaryNode.getSymbol());
+
+        return null;
+    }
+
+    @Override
+    public Node enterSUB(final UnaryNode unaryNode) {
+        if (unaryNode.testResolved()) {
+            return null;
+        }
+
+        load(unaryNode.rhs()).neg().store(unaryNode.getSymbol());
+
+        return null;
+    }
+
+    private Node enterNumericAdd(final Node lhs, final Node rhs, final Type type, final Symbol symbol) {
+        assert lhs.getType().equals(rhs.getType()) && lhs.getType().equals(type) : lhs.getType() + " != " + rhs.getType() + " != " + type + " " + new ASTWriter(lhs) + " " + new ASTWriter(rhs);
+        load(lhs);
+        load(rhs);
+        method.add();
+        method.store(symbol);
+        return null;
+    }
+
+    @Override
+    public Node enterADD(final BinaryNode binaryNode) {
+        if (binaryNode.testResolved()) {
+            return null;
+        }
+
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        final Type type = binaryNode.getType();
+        if (type.isNumeric()) {
+            enterNumericAdd(lhs, rhs, type, binaryNode.getSymbol());
+        } else {
+            load(lhs).convert(Type.OBJECT);
+            load(rhs).convert(Type.OBJECT);
+            method.add();
+            method.store(binaryNode.getSymbol());
+        }
+
+        return null;
+    }
+
+    private Node enterAND_OR(final BinaryNode binaryNode) {
+        if (binaryNode.testResolved()) {
+            return null;
+        }
+
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        final Label skip = new Label("skip");
+
+        load(lhs).convert(Type.OBJECT).dup().convert(Type.BOOLEAN);
+
+        if (binaryNode.tokenType() == TokenType.AND) {
+            method.ifeq(skip);
+        } else {
+            method.ifne(skip);
+        }
+
+        method.pop();
+        load(rhs).convert(Type.OBJECT);
+        method.label(skip);
+        method.store(binaryNode.getSymbol());
+
+        return null;
+    }
+
+    @Override
+    public Node enterAND(final BinaryNode binaryNode) {
+        return enterAND_OR(binaryNode);
+    }
+
+    @Override
+    public Node enterASSIGN(final BinaryNode binaryNode) {
+        if (binaryNode.testResolved()) {
+            return null;
+        }
+
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        final Type lhsType = lhs.getType();
+        final Type rhsType = rhs.getType();
+
+        if (!lhsType.isEquivalentTo(rhsType)) {
+            //this is OK if scoped, only locals are wrong
+            assert !(lhs instanceof IdentNode) || lhs.getSymbol().isScope() : new ASTWriter(binaryNode);
+        }
+
+        new Store<BinaryNode>(binaryNode, lhs) {
+            @Override
+            protected void evaluate() {
+                load(rhs);
+            }
+        }.store();
+
+        return null;
+    }
+
+    /**
+     * Helper class for assignment ops, e.g. *=, += and so on..
+     */
+    private abstract class AssignOp extends SelfModifyingStore<BinaryNode> {
+
+        /** The type of the resulting operation */
+        private final Type opType;
+
+        /**
+         * Constructor
+         *
+         * @param node the assign op node
+         */
+        AssignOp(final BinaryNode node) {
+            this(node.getType(), node);
+        }
+
+        /**
+         * Constructor
+         *
+         * @param opType type of the computation - overriding the type of the node
+         * @param node the assign op node
+         */
+        AssignOp(final Type opType, final BinaryNode node) {
+            super(node, node.lhs());
+            this.opType = opType;
+        }
+
+        @Override
+        public void store() {
+            if (assignNode.testResolved()) {
+                return;
+            }
+            super.store();
+        }
+
+        protected abstract void op();
+
+        @Override
+        protected void evaluate() {
+            load(assignNode.lhs(), true).convert(opType);
+            load(assignNode.rhs()).convert(opType);
+            op();
+            method.convert(assignNode.getType());
+        }
+    }
+
+    @Override
+    public Node enterASSIGN_ADD(final BinaryNode binaryNode) {
+        assert RuntimeNode.Request.ADD.canSpecialize();
+        final boolean specialize = binaryNode.getType() == Type.OBJECT;
+
+        new AssignOp(binaryNode) {
+            @Override
+            protected boolean isSelfModifying() {
+                return !specialize;
+            }
+
+            @Override
+            protected void op() {
+                method.add();
+            }
+
+            @Override
+            protected void evaluate() {
+                if (specialize && specializationCheck(Request.ADD, assignNode, Arrays.asList(assignNode.lhs(), assignNode.rhs()))) {
+                    return;
+                }
+                super.evaluate();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_BIT_AND(final BinaryNode binaryNode) {
+        new AssignOp(Type.INT, binaryNode) {
+            @Override
+            protected void op() {
+                method.and();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_BIT_OR(final BinaryNode binaryNode) {
+        new AssignOp(Type.INT, binaryNode) {
+            @Override
+            protected void op() {
+                method.or();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+        new AssignOp(Type.INT, binaryNode) {
+            @Override
+            protected void op() {
+                method.xor();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_DIV(final BinaryNode binaryNode) {
+        new AssignOp(binaryNode) {
+            @Override
+            protected void op() {
+                method.div();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_MOD(final BinaryNode binaryNode) {
+        new AssignOp(binaryNode) {
+            @Override
+            protected void op() {
+                method.rem();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_MUL(final BinaryNode binaryNode) {
+        new AssignOp(binaryNode) {
+            @Override
+            protected void op() {
+                method.mul();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_SAR(final BinaryNode binaryNode) {
+        new AssignOp(Type.INT, binaryNode) {
+            @Override
+            protected void op() {
+                method.sar();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_SHL(final BinaryNode binaryNode) {
+        new AssignOp(Type.INT, binaryNode) {
+            @Override
+            protected void op() {
+                method.shl();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_SHR(final BinaryNode binaryNode) {
+        new AssignOp(Type.INT, binaryNode) {
+            @Override
+            protected void op() {
+                method.shr();
+                method.convert(Type.LONG).load(0xffff_ffffL).and();
+            }
+        }.store();
+
+        return null;
+    }
+
+    @Override
+    public Node enterASSIGN_SUB(final BinaryNode binaryNode) {
+        new AssignOp(binaryNode) {
+            @Override
+            protected void op() {
+                method.sub();
+            }
+        }.store();
+
+        return null;
+    }
+
+    /**
+     * Helper class for binary arithmetic ops
+     */
+    private abstract class BinaryArith {
+
+        protected abstract void op();
+
+        protected void evaluate(final BinaryNode node) {
+            if (node.testResolved()) {
+                return;
+            }
+            load(node.lhs());
+            load(node.rhs());
+            op();
+            method.store(node.getSymbol());
+        }
+    }
+
+    @Override
+    public Node enterBIT_AND(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.and();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enterBIT_OR(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.or();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enterBIT_XOR(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.xor();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    private Node enterComma(final BinaryNode binaryNode) {
+        if (binaryNode.testResolved()) {
+            return null;
+        }
+
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        load(lhs);
+        load(rhs);
+        method.store(binaryNode.getSymbol());
+
+        return null;
+    }
+
+    @Override
+    public Node enterCOMMARIGHT(final BinaryNode binaryNode) {
+        return enterComma(binaryNode);
+    }
+
+    @Override
+    public Node enterCOMMALEFT(final BinaryNode binaryNode) {
+        return enterComma(binaryNode);
+    }
+
+    @Override
+    public Node enterDIV(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.div();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    private Node enterCmp(final Node lhs, final Node rhs, final Condition cond, final Type type, final Symbol symbol) {
+        final Type lhsType = lhs.getType();
+        final Type rhsType = rhs.getType();
+
+        final Type widest = Type.widest(lhsType, rhsType);
+        assert widest.isNumeric() || widest.isBoolean() : widest;
+
+        load(lhs);
+        method.convert(widest);
+        load(rhs);
+        method.convert(widest);
+
+        final Label trueLabel  = new Label("trueLabel");
+        final Label afterLabel = new Label("skip");
+
+        method.conditionalJump(cond, trueLabel);
+
+        method.load(Boolean.FALSE);
+        method._goto(afterLabel);
+        method.label(trueLabel);
+        method.load(Boolean.TRUE);
+        method.label(afterLabel);
+
+        method.convert(type);
+        method.store(symbol);
+
+        return null;
+    }
+
+    private Node enterCmp(final BinaryNode binaryNode, final Condition cond) {
+        if (binaryNode.testResolved()) {
+            return null;
+        }
+        return enterCmp(binaryNode.lhs(), binaryNode.rhs(), cond, binaryNode.getType(), binaryNode.getSymbol());
+    }
+
+    @Override
+    public Node enterEQ(final BinaryNode binaryNode) {
+        return enterCmp(binaryNode, Condition.EQ);
+    }
+
+    @Override
+    public Node enterEQ_STRICT(final BinaryNode binaryNode) {
+        return enterCmp(binaryNode, Condition.EQ);
+    }
+
+    @Override
+    public Node enterGE(final BinaryNode binaryNode) {
+        return enterCmp(binaryNode, Condition.GE);
+    }
+
+    @Override
+    public Node enterGT(final BinaryNode binaryNode) {
+        return enterCmp(binaryNode, Condition.GT);
+    }
+
+    @Override
+    public Node enterLE(final BinaryNode binaryNode) {
+        return enterCmp(binaryNode, Condition.LE);
+    }
+
+    @Override
+    public Node enterLT(final BinaryNode binaryNode) {
+        return enterCmp(binaryNode, Condition.LT);
+    }
+
+    @Override
+    public Node enterMOD(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.rem();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enterMUL(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.mul();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enterNE(final BinaryNode binaryNode) {
+        return enterCmp(binaryNode, Condition.NE);
+    }
+
+    @Override
+    public Node enterNE_STRICT(final BinaryNode binaryNode) {
+        return enterCmp(binaryNode, Condition.NE);
+    }
+
+    @Override
+    public Node enterOR(final BinaryNode binaryNode) {
+        return enterAND_OR(binaryNode);
+    }
+
+    @Override
+    public Node enterSAR(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.sar();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enterSHL(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.shl();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enterSHR(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.shr();
+                method.convert(Type.LONG).load(0xffff_ffffL).and();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enterSUB(final BinaryNode binaryNode) {
+        new BinaryArith() {
+            @Override
+            protected void op() {
+                method.sub();
+            }
+        }.evaluate(binaryNode);
+
+        return null;
+    }
+
+    /*
+     * Ternary visits.
+     */
+    @Override
+    public Node enter(final TernaryNode ternaryNode) {
+        if (ternaryNode.testResolved()) {
+            return null;
+        }
+
+        final Node lhs   = ternaryNode.lhs();
+        final Node rhs   = ternaryNode.rhs();
+        final Node third = ternaryNode.third();
+
+        final Symbol symbol     = ternaryNode.getSymbol();
+        final Label  falseLabel = new Label("ternary_false");
+        final Label  exitLabel  = new Label("ternary_exit");
+
+        Type widest = Type.widest(rhs.getType(), third.getType());
+        if (rhs.getType().isArray() || third.getType().isArray()) { //loadArray creates a Java array type on the stack, calls global allocate, which creates a native array type
+            widest = Type.OBJECT;
+        }
+
+        load(lhs);
+        assert lhs.getType().isBoolean() : "lhs in ternary must be boolean";
+
+        // we still keep the conversion here as the AccessSpecializer can have separated the types, e.g. var y = x ? x=55 : 17
+        // will left as (Object)x=55 : (Object)17 by Lower. Then the first term can be {I}x=55 of type int, which breaks the
+        // symmetry for the temporary slot for this TernaryNode. This is evidence that we assign types and explicit conversions
+        // to early, or Apply the AccessSpecializer too late. We are mostly probably looking for a separate type pass to
+        // do this property. Then we never need any conversions in CodeGenerator
+        method.ifeq(falseLabel);
+        load(rhs);
+        method.convert(widest);
+        method._goto(exitLabel);
+        method.label(falseLabel);
+        load(third);
+        method.convert(widest);
+        method.label(exitLabel);
+        method.store(symbol);
+
+        return null;
+    }
+
+    /**
+     * Generate all shared scope calls generated during codegen.
+     */
+    protected void generateScopeCalls() {
+        for (final SharedScopeCall scopeAccess : scopeCalls.values()) {
+            scopeAccess.generateScopeCall();
+        }
+    }
+
+    /**
+     * Get a shared static method representing a dynamic scope callsite.
+     *
+     * @param symbol the symbol
+     * @param valueType the value type of the symbol
+     * @param returnType the return type
+     * @param paramTypes the parameter types
+     * @param flags the callsite flags
+     * @return an object representing a shared scope call
+     */
+    private SharedScopeCall getScopeCall(final Symbol symbol, final Type valueType, final Type returnType,
+                                         final Type[] paramTypes, final int flags) {
+
+        final SharedScopeCall scopeCall = new SharedScopeCall(symbol, valueType, returnType, paramTypes, flags);
+        if (scopeCalls.containsKey(scopeCall)) {
+            return scopeCalls.get(scopeCall);
+        }
+        scopeCall.setClassAndName(getCurrentCompileUnit(), getCurrentFunctionNode().uniqueName("scopeCall"));
+        scopeCalls.put(scopeCall, scopeCall);
+        return scopeCall;
+    }
+
+    /**
+     * Get a shared static method representing a dynamic scope get access.
+     *
+     * @param type the type of the variable
+     * @param symbol the symbol
+     * @param flags the callsite flags
+     * @return an object representing a shared scope call
+     */
+    private SharedScopeCall getScopeGet(final Type type, final Symbol symbol, final int flags) {
+
+        final SharedScopeCall scopeCall = new SharedScopeCall(symbol, type, type, null, flags);
+        if (scopeCalls.containsKey(scopeCall)) {
+            return scopeCalls.get(scopeCall);
+        }
+        scopeCall.setClassAndName(getCurrentCompileUnit(), getCurrentFunctionNode().uniqueName("scopeCall"));
+        scopeCalls.put(scopeCall, scopeCall);
+        return scopeCall;
+    }
+
+    /**
+     * Debug code used to print symbols
+     *
+     * @param block the block we are in
+     * @param ident identifier for block or function where applicable
+     */
+    private void printSymbols(final Block block, final String ident) {
+        if (!compiler.getEnv()._print_symbols) {
+            return;
+        }
+
+        @SuppressWarnings("resource")
+        final PrintWriter out = compiler.getEnv().getErr();
+        out.println("[BLOCK in '" + ident + "']");
+        if (!block.printSymbols(out)) {
+            out.println("<no symbols>");
+        }
+        out.println();
+    }
+
+
+    /**
+     * The difference between a store and a self modifying store is that
+     * the latter may load part of the target on the stack, e.g. the base
+     * of an AccessNode or the base and index of an IndexNode. These are used
+     * both as target and as an extra source. Previously it was problematic
+     * for self modifying stores if the target/lhs didn't belong to one
+     * of three trivial categories: IdentNode, AcessNodes, IndexNodes. In that
+     * case it was evaluated and tagged as "resolved", which meant at the second
+     * time the lhs of this store was read (e.g. in a = a (second) + b for a += b,
+     * it would be evaluated to a nop in the scope and cause stack underflow
+     *
+     * see NASHORN-703
+     *
+     * @param <T>
+     */
+    private abstract class SelfModifyingStore<T extends Node> extends Store<T> {
+        protected SelfModifyingStore(final T assignNode, final Node target) {
+            super(assignNode, target);
+        }
+
+        @Override
+        protected boolean isSelfModifying() {
+            return true;
+        }
+    }
+
+    /**
+     * Helper class to generate stores
+     */
+    private abstract class Store<T extends Node> {
+
+        /** An assignment node, e.g. x += y */
+        protected final T assignNode;
+
+        /** The target node to store to, e.g. x */
+        private final Node target;
+
+        /** Should the result always be discarded, no matter what? */
+        private final boolean alwaysDiscard;
+
+        /** How deep on the stack do the arguments go if this generates an indy call */
+        private int depth;
+
+        /** If we have too many arguments, we need temporary storage, this is stored in 'quick' */
+        private Symbol quick;
+
+        /**
+         * Constructor
+         *
+         * @param assignNode the node representing the whole assignment
+         * @param target     the target node of the assignment (destination)
+         */
+        protected Store(final T assignNode, final Node target) {
+            this.assignNode = assignNode;
+            this.target = target;
+            this.alwaysDiscard = assignNode == target;
+        }
+
+        /**
+         * Constructor
+         *
+         * @param assignNode the node representing the whole assignment
+         */
+        protected Store(final T assignNode) {
+            this(assignNode, assignNode);
+        }
+
+        /**
+         * Is this a self modifying store operation, e.g. *= or ++
+         * @return true if self modifying store
+         */
+        protected boolean isSelfModifying() {
+            return false;
+        }
+
+        private void prologue() {
+            final Symbol targetSymbol = target.getSymbol();
+            final Symbol scopeSymbol  = getCurrentFunctionNode().getScopeNode().getSymbol();
+
+            /**
+             * This loads the parts of the target, e.g base and index. they are kept
+             * on the stack throughout the store and used at the end to execute it
+             */
+
+            target.accept(new NodeVisitor(getCurrentCompileUnit(), method) {
+                @Override
+                public Node enter(final IdentNode node) {
+                    if (targetSymbol.isScope()) {
+                        method.load(scopeSymbol);
+                        depth++;
+                    }
+                    return null;
+                }
+
+                private void enterBaseNode() {
+                    assert target instanceof BaseNode : "error - base node " + target + " must be instanceof BaseNode";
+                    final BaseNode baseNode = (BaseNode)target;
+                    final Node     base     = baseNode.getBase();
+
+                    load(base);
+                    method.convert(Type.OBJECT);
+                    depth += Type.OBJECT.getSlots();
+
+                    if (isSelfModifying()) {
+                        method.dup();
+                    }
+                }
+
+                @Override
+                public Node enter(final AccessNode node) {
+                    enterBaseNode();
+                    return null;
+                }
+
+                @Override
+                public Node enter(final IndexNode node) {
+                    enterBaseNode();
+
+                    final Node index = node.getIndex();
+                    // could be boolean here as well
+                    load(index);
+                    if (!index.getType().isNumeric()) {
+                        method.convert(Type.OBJECT);
+                    }
+                    depth += index.getType().getSlots();
+
+                    if (isSelfModifying()) {
+                        //convert "base base index" to "base index base index"
+                        method.dup(1);
+                    }
+
+                    return null;
+                }
+
+            });
+        }
+
+        private Symbol quickSymbol(final Type type) {
+            return quickSymbol(type, QUICK_PREFIX.tag());
+        }
+
+        /**
+         * Quick symbol generates an extra local variable, always using the same
+         * slot, one that is available after the end of the frame.
+         *
+         * @param type the type of the symbol
+         * @param prefix the prefix for the variable name for the symbol
+         *
+         * @return the quick symbol
+         */
+        private Symbol quickSymbol(final Type type, final String prefix) {
+            final String name = getCurrentFunctionNode().uniqueName(prefix);
+            final Symbol symbol = new Symbol(name, IS_TEMP | IS_INTERNAL, null, null);
+
+            symbol.setType(type);
+            symbol.setSlot(getCurrentBlock().getFrame().getSlotCount());
+
+            return symbol;
+        }
+
+        // store the result that "lives on" after the op, e.g. "i" in i++ postfix.
+        protected void storeNonDiscard() {
+            if (assignNode.shouldDiscard() || alwaysDiscard) {
+                assignNode.setDiscard(false);
+                return;
+            }
+
+            final Symbol symbol = assignNode.getSymbol();
+            if (symbol.hasSlot()) {
+                method.dup().store(symbol);
+                return;
+            }
+
+            if (method.dup(depth) == null) {
+                method.dup();
+                this.quick = quickSymbol(method.peekType());
+                method.store(quick);
+            }
+        }
+
+        private void epilogue() {
+            final FunctionNode currentFunction = getCurrentFunctionNode();
+
+            /**
+             * Take the original target args from the stack and use them
+             * together with the value to be stored to emit the store code
+             *
+             * The case that targetSymbol is in scope (!hasSlot) and we actually
+             * need to do a conversion on non-equivalent types exists, but is
+             * very rare. See for example test/script/basic/access-specializer.js
+             */
+            method.convert(target.getType());
+
+            target.accept(new NodeVisitor(getCurrentCompileUnit(), method) {
+                @Override
+                protected Node enterDefault(Node node) {
+                    throw new AssertionError("Unexpected node " + node + " in store epilogue");
+                }
+
+                @Override
+                public Node enter(final UnaryNode node) {
+                    if(node.tokenType() == TokenType.CONVERT && node.getSymbol() != null) {
+                        method.convert(node.rhs().getType());
+                    }
+                    return node;
+                }
+
+                @Override
+                public Node enter(final IdentNode node) {
+                    final Symbol symbol = node.getSymbol();
+                    assert symbol != null;
+                    if (symbol.isScope()) {
+                        if (symbol.isFastScope(currentFunction)) {
+                            storeFastScopeVar(node.getType(), symbol, CALLSITE_SCOPE | getCallSiteFlags());
+                        } else {
+                            method.dynamicSet(node.getType(), node.getName(), CALLSITE_SCOPE | getCallSiteFlags());
+                        }
+                    } else {
+                        method.store(symbol);
+                    }
+                    return null;
+
+                }
+
+                @Override
+                public Node enter(final AccessNode node) {
+                    method.dynamicSet(node.getProperty().getType(), node.getProperty().getName(), getCallSiteFlags());
+                    return null;
+                }
+
+                @Override
+                public Node enter(final IndexNode node) {
+                    method.dynamicSetIndex(getCallSiteFlags());
+                    return null;
+                }
+            });
+
+
+            // whatever is on the stack now is the final answer
+        }
+
+        protected abstract void evaluate();
+
+        void store() {
+            prologue();
+            evaluate(); // leaves an operation of whatever the operationType was on the stack
+            storeNonDiscard();
+            epilogue();
+            if (quick != null) {
+                method.load(quick);
+            }
+        }
+
+    }
+
+    private void newFunctionObject(final FunctionNode functionNode) {
+        final boolean isLazy = functionNode.isLazy();
+        final Class<?>[] cparams = new Class<?>[] { ScriptFunctionData.class, ScriptObject.class, MethodHandle.class };
+
+        new ObjectCreator(this, new ArrayList<String>(), new ArrayList<Symbol>(), false, false) {
+            @Override
+            protected void makeObject(final MethodEmitter method) {
+                final String className = isLazy ? SCRIPTFUNCTION_TRAMPOLINE_OBJECT : SCRIPTFUNCTION_IMPL_OBJECT;
+
+                method._new(className).dup();
+                if (isLazy) {
+                    loadConstant(compiler.getCodeInstaller());
+                    loadConstant(functionNode);
+                } else {
+                    final String signature = new FunctionSignature(true, functionNode.needsCallee(), functionNode.getReturnType(), functionNode.isVarArg() ? null : functionNode.getParameters()).toString();
+                    method.loadHandle(functionNode.getCompileUnit().getUnitClassName(), functionNode.getName(), signature, EnumSet.of(HANDLE_STATIC)); // function
+                }
+                loadConstant(new ScriptFunctionData(functionNode, makeMap()));
+
+                if (isLazy || functionNode.needsParentScope()) {
+                    method.loadScope();
+                } else {
+                    method.loadNull();
+                }
+
+                method.loadHandle(getClassName(), ALLOCATE.tag(), methodDescriptor(ScriptObject.class, PropertyMap.class), EnumSet.of(HANDLE_STATIC));
+
+                final List<Class<?>> cparamList = new ArrayList<>();
+                if (isLazy) {
+                    cparamList.add(CodeInstaller.class);
+                    cparamList.add(FunctionNode.class);
+                } else {
+                    cparamList.add(MethodHandle.class);
+                }
+                cparamList.addAll(Arrays.asList(cparams));
+
+                method.invoke(constructorNoLookup(className, cparamList.toArray(new Class<?>[cparamList.size()])));
+            }
+        }.makeObject(method);
+    }
+
+    /*
+     * Globals are special. We cannot refer to any Global (or NativeObject) class by .class, as they are different
+     * for different contexts. As far as I can tell, the only NativeObject that we need to deal with like this
+     * is from the code pipeline is Global
+     */
+    private MethodEmitter globalInstance() {
+        return method.invokestatic(GLOBAL_OBJECT, "instance", "()L" + GLOBAL_OBJECT + ';');
+    }
+
+    private MethodEmitter globalObjectPrototype() {
+        return method.invokestatic(GLOBAL_OBJECT, "objectPrototype", methodDescriptor(ScriptObject.class));
+    }
+
+    private MethodEmitter globalAllocateArguments() {
+        return method.invokestatic(GLOBAL_OBJECT, "allocateArguments", methodDescriptor(ScriptObject.class, Object[].class, Object.class, int.class));
+    }
+
+    private MethodEmitter globalNewRegExp() {
+        return method.invokestatic(GLOBAL_OBJECT, "newRegExp", methodDescriptor(Object.class, String.class, String.class));
+    }
+
+    private MethodEmitter globalRegExpCopy() {
+        return method.invokestatic(GLOBAL_OBJECT, "regExpCopy", methodDescriptor(Object.class, Object.class));
+    }
+
+    private MethodEmitter globalAllocateArray(final ArrayType type) {
+        //make sure the native array is treated as an array type
+        return method.invokestatic(GLOBAL_OBJECT, "allocate", "(" + type.getDescriptor() + ")Ljdk/nashorn/internal/objects/NativeArray;");
+    }
+
+    private MethodEmitter globalIsEval() {
+        return method.invokestatic(GLOBAL_OBJECT, "isEval", methodDescriptor(boolean.class, Object.class));
+    }
+
+    private MethodEmitter globalDirectEval() {
+        return method.invokestatic(GLOBAL_OBJECT, "directEval",
+                methodDescriptor(Object.class, Object.class, Object.class, Object.class, Object.class, Object.class));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilationException.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilationException.java
new file mode 100644
index 0000000..66fa324
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.codegen;
+
+/**
+ * Exception when something in the compiler breaks down. Can only
+ * be instantiated by the codegen package
+ */
+@SuppressWarnings("serial")
+public class CompilationException extends RuntimeException {
+
+    CompilationException(final String description) {
+        super(description);
+    }
+
+    CompilationException(final Exception cause) {
+        super(cause);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
new file mode 100644
index 0000000..e22454c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
@@ -0,0 +1,376 @@
+package jdk.nashorn.internal.codegen;
+
+import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.ATTR;
+import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.CONSTANT_FOLDED;
+import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.EMITTED;
+import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.FINALIZED;
+import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.INITIALIZED;
+import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.LOWERED;
+import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SPLIT;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Set;
+
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ReferenceNode;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.ir.debug.ASTWriter;
+import jdk.nashorn.internal.ir.debug.PrintVisitor;
+import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.Timing;
+
+/**
+ * A compilation phase is a step in the processes of turning a JavaScript FunctionNode
+ * into bytecode. It has an optional return value.
+ */
+enum CompilationPhase {
+
+    /*
+     * Lazy initialization - tag all function nodes not the script as lazy as
+     * default policy. The will get trampolines and only be generated when
+     * called
+     */
+    LAZY_INITIALIZATION_PHASE(EnumSet.of(FunctionNode.CompilationState.INITIALIZED)) {
+        @Override
+        void transform(final Compiler compiler, final FunctionNode fn) {
+
+            /*
+             * For lazy compilation, we might be given a node previously marked as lazy
+             * to compile as the outermost function node in the compiler. Unmark it
+             * so it can be compiled and not cause recursion. Make sure the return type
+             * is unknown so it can be correctly deduced. Return types are always
+             * Objects in Lazy nodes as we haven't got a change to generate code for
+             * them and decude its parameter specialization
+             *
+             * TODO: in the future specializations from a callsite will be passed here
+             * so we can generate a better non-lazy version of a function from a trampoline
+             */
+            //compute the signature from the callsite - todo - now just clone object params
+            final FunctionNode outermostFunctionNode = compiler.getFunctionNode();
+            outermostFunctionNode.setIsLazy(false);
+            outermostFunctionNode.setReturnType(Type.UNKNOWN);
+
+            final Set<FunctionNode> neverLazy = new HashSet<>();
+            final Set<FunctionNode> lazy = new HashSet<>();
+
+            outermostFunctionNode.accept(new NodeVisitor() {
+                // self references are done with invokestatic and thus cannot have trampolines - never lazy
+                @Override
+                public Node enter(final CallNode node) {
+                    final Node callee = node.getFunction();
+                    if (callee instanceof ReferenceNode) {
+                        neverLazy.add(((ReferenceNode)callee).getReference());
+                        return null;
+                    }
+                    return node;
+                }
+
+                @Override
+                public Node enter(final FunctionNode node) {
+                    if (node == outermostFunctionNode) {
+                        return node;
+                    }
+                    assert Compiler.LAZY_JIT;
+                    lazy.add(node);
+
+                    return node;
+                }
+            });
+
+            for (final FunctionNode node : neverLazy) {
+                Compiler.LOG.fine("Marking " + node.getName() + " as non lazy, as it's a self reference");
+                node.setIsLazy(false);
+                lazy.remove(node);
+            }
+
+            for (final FunctionNode node : lazy) {
+                Compiler.LOG.fine("Marking " + node.getName() + " as lazy");
+                node.setIsLazy(true);
+                final FunctionNode parent = node.findParentFunction();
+                if (parent != null) {
+                    Compiler.LOG.fine("Marking " + parent.getName() + " as having lazy children - it needs scope for all variables");
+                    parent.setHasLazyChildren();
+                }
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "[Lazy JIT Initialization]";
+        }
+    },
+
+    /*
+     * Constant folding pass
+     *   Simple constant folding that will make elementary constructs go away
+     */
+    CONSTANT_FOLDING_PHASE(EnumSet.of(INITIALIZED), CONSTANT_FOLDED) {
+        @Override
+        void transform(final Compiler compiler, final FunctionNode fn) {
+            fn.accept(new FoldConstants());
+        }
+
+        @Override
+        public String toString() {
+            return "[Constant Folding]";
+        }
+    },
+
+    /*
+     * Lower (Control flow pass)
+     *   Finalizes the control flow. Clones blocks for finally constructs and
+     *   similar things. Establishes termination criteria for nodes
+     *   Guarantee return instructions to method making sure control flow
+     *   cannot fall off the end. Replacing high level nodes with lower such
+     *   as runtime nodes where applicable.
+     *
+     */
+    LOWERING_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED), LOWERED) {
+        @Override
+        void transform(final Compiler compiler, final FunctionNode fn) {
+            fn.accept(new Lower());
+        }
+
+        @Override
+        public String toString() {
+            return "[Control Flow Lowering]";
+        }
+    },
+
+    /*
+     * Attribution
+     *   Assign symbols and types to all nodes.
+     */
+    ATTRIBUTION_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED), ATTR) {
+        @Override
+        void transform(final Compiler compiler, final FunctionNode fn) {
+            final ScriptEnvironment env = compiler.getEnv();
+
+            fn.accept(new Attr());
+            if (env._print_lower_ast) {
+                env.getErr().println(new ASTWriter(fn));
+            }
+
+            if (env._print_lower_parse) {
+                env.getErr().println(new PrintVisitor(fn));
+           }
+        }
+
+        @Override
+        public String toString() {
+            return "[Type Attribution]";
+        }
+    },
+
+    /*
+     * Splitter
+     *   Split the AST into several compile units based on a size heuristic
+     *   Splitter needs attributed AST for weight calculations (e.g. is
+     *   a + b a ScriptRuntime.ADD with call overhead or a dadd with much
+     *   less). Split IR can lead to scope information being changed.
+     */
+    SPLITTING_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED, ATTR), SPLIT) {
+        @Override
+        void transform(final Compiler compiler, final FunctionNode fn) {
+            final CompileUnit outermostCompileUnit = compiler.addCompileUnit(compiler.firstCompileUnitName());
+
+            new Splitter(compiler, fn, outermostCompileUnit).split();
+
+            assert fn.getCompileUnit() == outermostCompileUnit : "fn.compileUnit (" + fn.getCompileUnit() + ") != " + outermostCompileUnit;
+
+            if (fn.isStrictMode()) {
+                assert compiler.getStrictMode();
+                compiler.setStrictMode(true);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "[Code Splitting]";
+        }
+    },
+
+    /*
+     * FinalizeTypes
+     *
+     *   This pass finalizes the types for nodes. If Attr created wider types than
+     *   known during the first pass, convert nodes are inserted or access nodes
+     *   are specialized where scope accesses.
+     *
+     *   Runtime nodes may be removed and primitivized or reintroduced depending
+     *   on information that was established in Attr.
+     *
+     * Contract: all variables must have slot assignments and scope assignments
+     * before type finalization.
+     */
+    TYPE_FINALIZATION_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED, ATTR, SPLIT), FINALIZED) {
+        @Override
+        void transform(final Compiler compiler, final FunctionNode fn) {
+            fn.accept(new FinalizeTypes());
+        }
+
+        @Override
+        public String toString() {
+            return "[Type Finalization]";
+        }
+    },
+
+    /*
+     * Bytecode generation:
+     *
+     *   Generate the byte code class(es) resulting from the compiled FunctionNode
+     */
+    BYTECODE_GENERATION_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED, ATTR, SPLIT, FINALIZED), EMITTED) {
+        @Override
+        void transform(final Compiler compiler, final FunctionNode fn) {
+            final ScriptEnvironment env = compiler.getEnv();
+
+            try {
+                final CodeGenerator codegen = new CodeGenerator(compiler);
+                fn.accept(codegen);
+                codegen.generateScopeCalls();
+
+            } catch (final VerifyError e) {
+                if (env._verify_code || env._print_code) {
+                    env.getErr().println(e.getClass().getSimpleName() + ": " + e.getMessage());
+                    if (env._dump_on_error) {
+                        e.printStackTrace(env.getErr());
+                    }
+                } else {
+                    throw e;
+                }
+            }
+
+            for (final CompileUnit compileUnit : compiler.getCompileUnits()) {
+                final ClassEmitter classEmitter = compileUnit.getClassEmitter();
+                classEmitter.end();
+
+                final byte[] bytecode = classEmitter.toByteArray();
+                assert bytecode != null;
+
+                final String className = compileUnit.getUnitClassName();
+
+                compiler.addClass(className, bytecode);
+
+                //should could be printed to stderr for generate class?
+                if (env._print_code) {
+                    final StringBuilder sb = new StringBuilder();
+                    sb.append("class: " + className).
+                        append('\n').
+                        append(ClassEmitter.disassemble(bytecode)).
+                        append("=====");
+                    env.getErr().println(sb);
+                }
+
+                //should we verify the generated code?
+                if (env._verify_code) {
+                    compiler.getCodeInstaller().verify(bytecode);
+                }
+
+                //should code be dumped to disk - only valid in compile_only mode?
+                if (env._dest_dir != null && env._compile_only) {
+                    final String fileName = className.replace('.', File.separatorChar) + ".class";
+                    final int    index    = fileName.lastIndexOf(File.separatorChar);
+
+                    if (index != -1) {
+                        final File dir = new File(fileName.substring(0, index));
+                        try {
+                            if (!dir.exists() && !dir.mkdirs()) {
+                                throw new IOException(dir.toString());
+                            }
+                            final File file = new File(env._dest_dir, fileName);
+                            try (final FileOutputStream fos = new FileOutputStream(file)) {
+                                fos.write(bytecode);
+                            }
+                        } catch (final IOException e) {
+                            Compiler.LOG.warning("Skipping class dump for " + className + ": " + ECMAErrors.getMessage("io.error.cant.write", dir.toString()));
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "[Bytecode Generation]";
+        }
+    };
+
+    private final EnumSet<CompilationState> pre;
+    private final CompilationState post;
+    private long startTime;
+    private long endTime;
+    private boolean isFinished;
+
+    private CompilationPhase(final EnumSet<CompilationState> pre) {
+        this(pre, null);
+    }
+
+    private CompilationPhase(final EnumSet<CompilationState> pre, final CompilationState post) {
+        this.pre  = pre;
+        this.post = post;
+    }
+
+    boolean isApplicable(final FunctionNode functionNode) {
+        return functionNode.hasState(pre);
+    }
+
+    protected void begin(final FunctionNode functionNode) {
+        if (pre != null) {
+            //check that everything in pre is present
+            for (final CompilationState state : pre) {
+                assert functionNode.hasState(state);
+            }
+            //check that nothing else is present
+            for (final CompilationState state : CompilationState.values()) {
+                assert !(functionNode.hasState(state) && !pre.contains(state));
+            }
+        }
+
+        startTime = System.currentTimeMillis();
+    }
+
+    protected void end(final FunctionNode functionNode) {
+        endTime = System.currentTimeMillis();
+        Timing.accumulateTime(toString(), endTime - startTime);
+
+        if (post != null) {
+            functionNode.setState(post);
+        }
+
+        isFinished = true;
+    }
+
+    boolean isFinished() {
+        return isFinished;
+    }
+
+    long getStartTime() {
+        return startTime;
+    }
+
+    long getEndTime() {
+        return endTime;
+    }
+
+    abstract void transform(final Compiler compiler, final FunctionNode functionNode) throws CompilationException;
+
+    final void apply(final Compiler compiler, final FunctionNode functionNode) throws CompilationException {
+        if (!isApplicable(functionNode)) {
+            throw new CompilationException("compile phase not applicable: " + this);
+        }
+        begin(functionNode);
+        transform(compiler, functionNode);
+        end(functionNode);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java b/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java
new file mode 100644
index 0000000..5e62116
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java
@@ -0,0 +1,95 @@
+/*
+ * 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.codegen;
+
+/**
+ * Used to track split class compilation.
+ */
+public class CompileUnit {
+    /** Current class name */
+    private final String className;
+
+    /** Current class generator */
+    private final ClassEmitter classEmitter;
+
+    private long weight;
+
+    CompileUnit(final String className, final ClassEmitter classEmitter) {
+        this(className, classEmitter, 0L);
+    }
+
+    CompileUnit(final String className, final ClassEmitter classEmitter, final long initialWeight) {
+        this.className    = className;
+        this.classEmitter = classEmitter;
+        this.weight       = initialWeight;
+    }
+
+    /**
+     * Add weight to this compile unit
+     * @param w weight to add
+     */
+    void addWeight(final long w) {
+        this.weight += w;
+    }
+
+    /**
+     * Get the current weight of the compile unit.
+     * @return the unit's weight
+     */
+    long getWeight() {
+        return weight;
+    }
+
+    /**
+     * Check if this compile unit can hold {@code weight} more units of weight
+     * @param w weight to check if can be added
+     * @return true if weight fits in this compile unit
+     */
+    public boolean canHold(final long w) {
+        return (this.weight + w) < Splitter.SPLIT_THRESHOLD;
+    }
+
+    /**
+     * Get the class emitter for this compile unit
+     * @return class emitter
+     */
+    public ClassEmitter getClassEmitter() {
+        return classEmitter;
+    }
+
+    /**
+     * Get the class name for this compile unit
+     * @return the class name
+     */
+    public String getUnitClassName() {
+        return className;
+    }
+
+    @Override
+    public String toString() {
+        return "[classname=" + className + " weight=" + weight + '/' + Splitter.SPLIT_THRESHOLD + ']';
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
new file mode 100644
index 0000000..ca23c42
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
@@ -0,0 +1,463 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.DEFAULT_SCRIPT_NAME;
+import static jdk.nashorn.internal.codegen.CompilerConstants.LAZY;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import jdk.internal.dynalink.support.NameCodec;
+import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+import jdk.nashorn.internal.runtime.CodeInstaller;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.Timing;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Responsible for converting JavaScripts to java byte code. Main entry
+ * point for code generator. The compiler may also install classes given some
+ * predefined Code installation policy, given to it at construction time.
+ * @see CodeInstaller
+ */
+public final class Compiler {
+
+    /** Name of the scripts package */
+    public static final String SCRIPTS_PACKAGE = "jdk/nashorn/internal/scripts";
+
+    /** Name of the objects package */
+    public static final String OBJECTS_PACKAGE = "jdk/nashorn/internal/objects";
+
+    static final boolean LAZY_JIT = Options.getBooleanProperty("nashorn.compiler.lazy");
+
+    private final Map<String, byte[]> bytecode;
+
+    private final Set<CompileUnit> compileUnits;
+
+    private final ConstantData constantData;
+
+    private final FunctionNode functionNode;
+
+    private final CompilationSequence sequence;
+
+    private final ScriptEnvironment env;
+
+    private final String scriptName;
+
+    private boolean strict;
+
+    private CodeInstaller<ScriptEnvironment> installer;
+
+    /** logger for compiler, trampolines, splits and related code generation events
+     *  that affect classes */
+    public static final DebugLogger LOG = new DebugLogger("compiler");
+
+    /**
+     * This array contains names that need to be reserved at the start
+     * of a compile, to avoid conflict with variable names later introduced.
+     * See {@link CompilerConstants} for special names used for structures
+     * during a compile.
+     */
+    private static String[] RESERVED_NAMES = {
+        SCOPE.tag(),
+        THIS.tag()
+    };
+
+    /**
+     * This class makes it possible to do your own compilation sequence
+     * from the code generation package. There are predefined compilation
+     * sequences already
+     */
+    @SuppressWarnings("serial")
+    static class CompilationSequence extends LinkedList<CompilationPhase> {
+
+        CompilationSequence(final CompilationPhase... phases) {
+            super(Arrays.asList(phases));
+        }
+
+        CompilationSequence(final CompilationSequence sequence) {
+            this(sequence.toArray(new CompilationPhase[sequence.size()]));
+        }
+
+        CompilationSequence insertAfter(final CompilationPhase phase, final CompilationPhase newPhase) {
+            final CompilationSequence newSeq = new CompilationSequence();
+            for (final CompilationPhase elem : this) {
+                newSeq.add(phase);
+                if (elem.equals(phase)) {
+                    newSeq.add(newPhase);
+                }
+            }
+            assert newSeq.contains(newPhase);
+            return newSeq;
+        }
+
+        CompilationSequence insertBefore(final CompilationPhase phase, final CompilationPhase newPhase) {
+            final CompilationSequence newSeq = new CompilationSequence();
+            for (final CompilationPhase elem : this) {
+                if (elem.equals(phase)) {
+                    newSeq.add(newPhase);
+                }
+                newSeq.add(phase);
+            }
+            assert newSeq.contains(newPhase);
+            return newSeq;
+        }
+
+        CompilationSequence insertFirst(final CompilationPhase phase) {
+            final CompilationSequence newSeq = new CompilationSequence(this);
+            newSeq.addFirst(phase);
+            return newSeq;
+        }
+
+        CompilationSequence insertLast(final CompilationPhase phase) {
+            final CompilationSequence newSeq = new CompilationSequence(this);
+            newSeq.addLast(phase);
+            return newSeq;
+        }
+    }
+
+    /**
+     * Standard (non-lazy) compilation, that basically will take an entire script
+     * and JIT it at once. This can lead to long startup time and fewer type
+     * specializations
+     */
+    final static CompilationSequence SEQUENCE_NORMAL = new CompilationSequence(
+        CompilationPhase.CONSTANT_FOLDING_PHASE,
+        CompilationPhase.LOWERING_PHASE,
+        CompilationPhase.ATTRIBUTION_PHASE,
+        CompilationPhase.SPLITTING_PHASE,
+        CompilationPhase.TYPE_FINALIZATION_PHASE,
+        CompilationPhase.BYTECODE_GENERATION_PHASE);
+
+    final static CompilationSequence SEQUENCE_LAZY =
+        SEQUENCE_NORMAL.insertFirst(CompilationPhase.LAZY_INITIALIZATION_PHASE);
+
+    final static CompilationSequence SEQUENCE_DEFAULT =
+        LAZY_JIT ?
+            SEQUENCE_LAZY :
+            SEQUENCE_NORMAL;
+
+    private static String lazyTag(final FunctionNode functionNode) {
+        if (functionNode.isLazy()) {
+            return '$' + LAZY.tag() + '$' + functionNode.getName();
+        }
+        return "";
+    }
+
+    /**
+     * Constructor
+     *
+     * @param installer    code installer
+     * @param functionNode function node (in any available {@link CompilationState}) to compile
+     * @param sequence     {@link Compiler#CompilationSequence} of {@link CompilationPhase}s to apply as this compilation
+     * @param strict       should this compilation use strict mode semantics
+     */
+    //TODO support an array of FunctionNodes for batch lazy compilation
+    Compiler(final ScriptEnvironment env, final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode, final CompilationSequence sequence, final boolean strict) {
+        this.env           = env;
+        this.functionNode  = functionNode;
+        this.sequence      = sequence;
+        this.installer     = installer;
+        this.strict        = strict || functionNode.isStrictMode();
+        this.constantData  = new ConstantData();
+        this.compileUnits  = new HashSet<>();
+        this.bytecode      = new HashMap<>();
+
+        final StringBuilder sb = new StringBuilder();
+        sb.append(functionNode.uniqueName(DEFAULT_SCRIPT_NAME.tag() + lazyTag(functionNode))).
+                append('$').
+                append(safeSourceName(functionNode.getSource()));
+
+        this.scriptName = sb.toString();
+
+        LOG.info("Initializing compiler for '" + functionNode.getName() + "' scriptName = " + scriptName + ", root function: '" + functionNode.getName() + "'");
+        if (functionNode.isLazy()) {
+            LOG.info(">>> This is a lazy recompilation triggered by a trampoline");
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param installer    code installer
+     * @param functionNode function node (in any available {@link CompilationState}) to compile
+     * @param strict       should this compilation use strict mode semantics
+     */
+    public Compiler(final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode, final boolean strict) {
+        this(installer.getOwner(), installer, functionNode, SEQUENCE_DEFAULT, strict);
+    }
+
+    /**
+     * Constructor - compilation will use the same strict semantics as in script environment
+     *
+     * @param installer    code installer
+     * @param functionNode function node (in any available {@link CompilationState}) to compile
+     */
+    public Compiler(final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode) {
+        this(installer.getOwner(), installer, functionNode, SEQUENCE_DEFAULT, installer.getOwner()._strict);
+    }
+
+    /**
+     * Constructor - compilation needs no installer, but uses a script environment
+     * Used in "compile only" scenarios
+     * @param env a script environment
+     * @param functionNode functionNode to compile
+     */
+    public Compiler(final ScriptEnvironment env, final FunctionNode functionNode) {
+        this(env, null, functionNode, SEQUENCE_DEFAULT, env._strict);
+    }
+
+    /**
+     * Execute the compilation this Compiler was created with
+     * @throws CompilationException if something goes wrong
+     */
+    public void compile() throws CompilationException {
+        for (final String reservedName : RESERVED_NAMES) {
+            functionNode.uniqueName(reservedName);
+        }
+
+        for (final CompilationPhase phase : sequence) {
+            phase.apply(this, functionNode);
+            final String end = phase.toString() + " done for function '" + functionNode.getName() + "'";
+            if (Timing.isEnabled()) {
+                final long duration = phase.getEndTime() - phase.getStartTime();
+                LOG.info(end + " in " + duration + " ms");
+            } else {
+                LOG.info(end);
+            }
+        }
+    }
+
+    /**
+     * Install compiled classes into a given loader
+     * @return root script class - if there are several compile units they will also be installed
+     */
+    public Class<?> install() {
+        final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
+
+        assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " has no bytecode and cannot be installed";
+
+        Class<?> rootClass = null;
+
+        for (final Entry<String, byte[]> entry : bytecode.entrySet()) {
+            final String     className = entry.getKey();
+            LOG.fine("Installing class " + className);
+
+            final byte[]     code  = entry.getValue();
+            final Class<?>   clazz = installer.install(Compiler.binaryName(className), code);
+
+            if (rootClass == null && firstCompileUnitName().equals(className)) {
+                rootClass = clazz;
+            }
+
+            try {
+                final Source source = getSource();
+                final Object[] constants = getConstantData().toArray();
+                // Need doPrivileged because these fields are private
+                AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+                    @Override
+                    public Void run() throws Exception {
+                        //use reflection to write source and constants table to installed classes
+                        final Field sourceField = clazz.getDeclaredField(SOURCE.tag());
+                        final Field constantsField = clazz.getDeclaredField(CONSTANTS.tag());
+                        sourceField.setAccessible(true);
+                        constantsField.setAccessible(true);
+                        sourceField.set(null, source);
+                        constantsField.set(null, constants);
+                        return null;
+                    }
+                });
+            } catch (final PrivilegedActionException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        LOG.info("Installed root class: " + rootClass + " and " + bytecode.size() + " compile unit classes");
+        if (Timing.isEnabled()) {
+            final long duration = System.currentTimeMillis() - t0;
+            Timing.accumulateTime("[Code Installation]", duration);
+            LOG.info("Installation time: " + duration + " ms");
+        }
+
+        return rootClass;
+    }
+
+    Set<CompileUnit> getCompileUnits() {
+        return compileUnits;
+    }
+
+    boolean getStrictMode() {
+        return strict;
+    }
+
+    void setStrictMode(final boolean strict) {
+        this.strict = strict;
+    }
+
+    FunctionNode getFunctionNode() {
+        return functionNode;
+    }
+
+    ConstantData getConstantData() {
+        return constantData;
+    }
+
+    CodeInstaller<ScriptEnvironment> getCodeInstaller() {
+        return installer;
+    }
+
+    Source getSource() {
+        return functionNode.getSource();
+    }
+
+    void addClass(final String name, final byte[] code) {
+        bytecode.put(name, code);
+    }
+
+    ScriptEnvironment getEnv() {
+        return this.env;
+    }
+
+    private static String safeSourceName(final Source source) {
+        String baseName = new File(source.getName()).getName();
+
+        final int index = baseName.lastIndexOf(".js");
+        if (index != -1) {
+            baseName = baseName.substring(0, index);
+        }
+
+        baseName = baseName.replace('.', '_').replace('-', '_');
+        final String mangled = NameCodec.encode(baseName);
+
+        return mangled != null ? mangled : baseName;
+    }
+
+    private int nextCompileUnitIndex() {
+        return compileUnits.size() + 1;
+    }
+
+    String firstCompileUnitName() {
+        return SCRIPTS_PACKAGE + '/' + scriptName;
+    }
+
+    private String nextCompileUnitName() {
+        return firstCompileUnitName() + '$' + nextCompileUnitIndex();
+    }
+
+    CompileUnit addCompileUnit(final long initialWeight) {
+        return addCompileUnit(nextCompileUnitName(), initialWeight);
+    }
+
+    CompileUnit addCompileUnit(final String unitClassName) {
+        return addCompileUnit(unitClassName, 0L);
+    }
+
+    private CompileUnit addCompileUnit(final String unitClassName, final long initialWeight) {
+        final CompileUnit compileUnit = initCompileUnit(unitClassName, initialWeight);
+        compileUnits.add(compileUnit);
+        LOG.fine("Added compile unit " + compileUnit);
+        return compileUnit;
+    }
+
+    private CompileUnit initCompileUnit(final String unitClassName, final long initialWeight) {
+        final ClassEmitter classEmitter = new ClassEmitter(env, functionNode.getSource().getName(), unitClassName, strict);
+        final CompileUnit  compileUnit  = new CompileUnit(unitClassName, classEmitter, initialWeight);
+
+        classEmitter.begin();
+
+        final MethodEmitter initMethod = classEmitter.init(EnumSet.of(Flag.PRIVATE));
+        initMethod.begin();
+        initMethod.load(Type.OBJECT, 0);
+        initMethod.newInstance(jdk.nashorn.internal.scripts.JS.class);
+        initMethod.returnVoid();
+        initMethod.end();
+
+        return compileUnit;
+    }
+
+    CompileUnit findUnit(final long weight) {
+        for (final CompileUnit unit : compileUnits) {
+            if (unit.canHold(weight)) {
+                unit.addWeight(weight);
+                return unit;
+            }
+        }
+
+        return addCompileUnit(weight);
+    }
+
+    /**
+     * Convert a package/class name to a binary name.
+     *
+     * @param name Package/class name.
+     * @return Binary name.
+     */
+    public static String binaryName(final String name) {
+        return name.replace('/', '.');
+    }
+
+    /**
+     * Should we use integers for arithmetic operations as well?
+     * TODO: We currently generate no overflow checks so this is
+     * disabled
+     *
+     * @see #shouldUseIntegers()
+     *
+     * @return true if arithmetic operations should not widen integer
+     *   operands by default.
+     */
+    static boolean shouldUseIntegerArithmetic() {
+        return USE_INT_ARITH;
+    }
+
+    private static final boolean USE_INT_ARITH;
+
+    static {
+        USE_INT_ARITH  =  Options.getBooleanProperty("nashorn.compiler.intarithmetic");
+        assert !USE_INT_ARITH : "Integer arithmetic is not enabled";
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java
new file mode 100644
index 0000000..1d978d9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java
@@ -0,0 +1,694 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * This class represents constant names of variables, methods and fields in
+ * the compiler
+ */
+
+public enum CompilerConstants {
+    /** the __FILE__ variable */
+    __FILE__,
+
+    /** the __DIR__ variable */
+    __DIR__,
+
+    /** the __LINE__ variable */
+    __LINE__,
+
+    /** lazy prefix for classes of jitted methods */
+    LAZY("Lazy"),
+
+    /** leaf tag used for functions that require no scope */
+    LEAF("__leaf__"),
+
+    /** constructor name */
+    INIT("<init>"),
+
+    /** static initializer name */
+    CLINIT("<clinit>"),
+
+    /** eval name */
+    EVAL("eval"),
+
+    /** source name and class */
+    SOURCE("source", Source.class),
+
+    /** constants name and class */
+    CONSTANTS("constants", Object[].class),
+
+    /** strict mode field name and type */
+    STRICT_MODE("strictMode", boolean.class),
+
+    /** default script name */
+    DEFAULT_SCRIPT_NAME("Script"),
+
+    /** function prefix for anonymous functions */
+    FUNCTION_PREFIX("function$"),
+
+    /** method name for Java method that is script entry point */
+    RUN_SCRIPT("runScript"),
+
+    /**
+     * "this" name symbol for a parameter representing ECMAScript "this" in static methods that are compiled
+     * representations of ECMAScript functions. It is not assigned a slot, as its position in the method signature is
+     * dependent on other factors (most notably, callee can precede it).
+     */
+    THIS("this"),
+
+    /** this debugger symbol */
+    THIS_DEBUGGER("__this__"),
+
+    /** scope name, type and slot */
+    SCOPE("__scope__", ScriptObject.class, 2),
+
+    /** the return value variable name were intermediate results are stored for scripts */
+    SCRIPT_RETURN("__return__"),
+
+    /** the callee value variable when necessary */
+    CALLEE("__callee__", ScriptFunction.class),
+
+    /** the varargs variable when necessary */
+    VARARGS("__varargs__"),
+
+    /** the arguments vector when necessary and the slot */
+    ARGUMENTS("arguments", Object.class, 2),
+
+    /** prefix for iterators for for (x in ...) */
+    ITERATOR_PREFIX("$iter"),
+
+    /** prefix for tag variable used for switch evaluation */
+    SWITCH_TAG_PREFIX("$tag"),
+
+    /** prefix for all exceptions */
+    EXCEPTION_PREFIX("$exception"),
+
+    /** prefix for quick slots generated in Store */
+    QUICK_PREFIX("$quick"),
+
+    /** prefix for temporary variables */
+    TEMP_PREFIX("$temp"),
+
+    /** prefix for literals */
+    LITERAL_PREFIX("$lit"),
+
+    /** prefix for map */
+    MAP("$map", 1),
+
+    /** prefix for regexps */
+    REGEX_PREFIX("$regex"),
+
+    /** "this" used in non-static Java methods; always in slot 0 */
+    JAVA_THIS("this", 0),
+
+    /** init scope */
+    INIT_SCOPE("$scope", 2),
+
+    /** init arguments */
+    INIT_ARGUMENTS("$arguments", 3),
+
+    /** prefix for all ScriptObject subclasses with fields, @see ObjectGenerator */
+    JS_OBJECT_PREFIX("JO"),
+
+    /** name for allocate method in JO objects */
+    ALLOCATE("allocate"),
+
+    /** prefix for split methods, @see Splitter */
+    SPLIT_PREFIX("$split"),
+
+    /** prefix for split array method and slot */
+    SPLIT_ARRAY_ARG("split_array", 3),
+
+    /** get string from constant pool */
+    GET_STRING("$getString"),
+
+    /** get map */
+    GET_MAP("$getMap"),
+
+    /** get map */
+    SET_MAP("$setMap"),
+
+    /** get array prefix */
+    GET_ARRAY_PREFIX("$get"),
+
+    /** get array suffix */
+    GET_ARRAY_SUFFIX("$array");
+
+    private final String tag;
+    private final Class<?> type;
+    private final int slot;
+
+    private CompilerConstants() {
+        this.tag = name();
+        this.type = null;
+        this.slot = -1;
+    }
+
+    private CompilerConstants(final String tag) {
+        this(tag, -1);
+    }
+
+    private CompilerConstants(final String tag, final int slot) {
+        this(tag, null, slot);
+    }
+
+    private CompilerConstants(final String tag, final Class<?> type) {
+        this(tag, type, -1);
+    }
+
+    private CompilerConstants(final String tag, final Class<?> type, final int slot) {
+        this.tag  = tag;
+        this.type = type;
+        this.slot = slot;
+    }
+
+    /**
+     * Return the tag for this compile constant. Deliberately avoiding "name" here
+     * not to conflate with enum implementation. This is the master string for the
+     * constant - every constant has one.
+     *
+     * @return the tag
+     */
+    public final String tag() {
+        return tag;
+    }
+
+    /**
+     * Return the type for this compile constant
+     *
+     * @return type for this constant's instances, or null if N/A
+     */
+    public final Class<?> type() {
+        return type;
+    }
+
+    /**
+     * Return the slot for this compile constant
+     *
+     * @return byte code slot where constant is stored or -1 if N/A
+     */
+    public final int slot() {
+        return slot;
+    }
+
+    /**
+     * Return a descriptor for this compile constant. Only relevant if it has
+     * a type
+     *
+     * @return descriptor the descriptor
+     */
+    public final String descriptor() {
+        assert type != null : " asking for descriptor of typeless constant";
+        return typeDescriptor(type);
+    }
+
+    /**
+     * Get the internal class name for a type
+     *
+     * @param type a type
+     * @return  the internal name for this type
+     */
+    public static String className(final Class<?> type) {
+        return Type.getInternalName(type);
+    }
+
+    /**
+     * Get the method descriptor for a given method type collection
+     *
+     * @param rtype  return type
+     * @param ptypes parameter types
+     *
+     * @return internal descriptor for this method
+     */
+    public static String methodDescriptor(final Class<?> rtype, final Class<?>... ptypes) {
+        return Type.getMethodDescriptor(rtype, ptypes);
+    }
+
+    /**
+     * Get the type descriptor for a type
+     *
+     * @param clazz a type
+     *
+     * @return the internal descriptor for this type
+     */
+    public static String typeDescriptor(final Class<?> clazz) {
+        return Type.getDescriptor(clazz);
+    }
+
+    /**
+     * Create a call representing a void constructor for a given type. Don't
+     * attempt to look this up at compile time
+     *
+     * @param clazz the class
+     *
+     * @return Call representing void constructor for type
+     */
+    public static Call constructorNoLookup(final Class<?> clazz) {
+        return specialCallNoLookup(clazz, INIT.tag(), void.class);
+    }
+
+    /**
+     * Create a call representing a constructor for a given type. Don't
+     * attempt to look this up at compile time
+     *
+     * @param className the type class name
+     * @param ptypes    the parameter types for the constructor
+     *
+     * @return Call representing constructor for type
+     */
+    public static Call constructorNoLookup(final String className, final Class<?>... ptypes) {
+        return specialCallNoLookup(className, INIT.tag(), methodDescriptor(void.class, ptypes));
+    }
+
+    /**
+     * Create a call representing a constructor for a given type. Don't
+     * attempt to look this up at compile time
+     *
+     * @param clazz  the class name
+     * @param ptypes the parameter types for the constructor
+     *
+     * @return Call representing constructor for type
+     */
+    public static Call constructorNoLookup(final Class<?> clazz, final Class<?>... ptypes) {
+        return specialCallNoLookup(clazz, INIT.tag(), void.class, ptypes);
+    }
+
+    /**
+     * Create a call representing an invokespecial to a given method. Don't
+     * attempt to look this up at compile time
+     *
+     * @param className the class name
+     * @param name      the method name
+     * @param desc      the descriptor
+     *
+     * @return Call representing specified invokespecial call
+     */
+    public static Call specialCallNoLookup(final String className, final String name, final String desc) {
+        return new Call(null, className, name, desc) {
+            @Override
+            public MethodEmitter invoke(final MethodEmitter method) {
+                return method.invokespecial(className, name, descriptor);
+            }
+        };
+    }
+
+    /**
+     * Create a call representing an invokespecial to a given method. Don't
+     * attempt to look this up at compile time
+     *
+     * @param clazz  the class
+     * @param name   the method name
+     * @param rtype  the return type
+     * @param ptypes the parameter types
+     *
+     * @return Call representing specified invokespecial call
+     */
+    public static Call specialCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+        return specialCallNoLookup(className(clazz), name, methodDescriptor(rtype, ptypes));
+    }
+
+    /**
+     * Create a call representing an invokestatic to a given method. Don't
+     * attempt to look this up at compile time
+     *
+     * @param className the class name
+     * @param name      the method name
+     * @param desc      the descriptor
+     *
+     * @return Call representing specified invokestatic call
+     */
+    public static Call staticCallNoLookup(final String className, final String name, final String desc) {
+        return new Call(null, className, name, desc) {
+            @Override
+            public MethodEmitter invoke(final MethodEmitter method) {
+                return method.invokestatic(className, name, descriptor);
+            }
+        };
+    }
+
+    /**
+     * Create a call representing an invokestatic to a given method. Don't
+     * attempt to look this up at compile time
+     *
+     * @param clazz  the class
+     * @param name   the method name
+     * @param rtype  the return type
+     * @param ptypes the parameter types
+     *
+     * @return Call representing specified invokestatic call
+     */
+    public static Call staticCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+        return staticCallNoLookup(className(clazz), name, methodDescriptor(rtype, ptypes));
+    }
+
+    /**
+     * Create a call representing an invokevirtual to a given method. Don't
+     * attempt to look this up at compile time
+     *
+     * @param clazz  the class
+     * @param name   the method name
+     * @param rtype  the return type
+     * @param ptypes the parameter types
+     *
+     * @return Call representing specified invokevirtual call
+     */
+    public static Call virtualCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+        return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
+            @Override
+            public MethodEmitter invoke(final MethodEmitter method) {
+                return method.invokevirtual(className, name, descriptor);
+            }
+        };
+    }
+
+    /**
+     * Create a call representing an invokeinterface to a given method. Don't
+     * attempt to look this up at compile time
+     *
+     * @param clazz  the class
+     * @param name   the method name
+     * @param rtype  the return type
+     * @param ptypes the parameter types
+     *
+     * @return Call representing specified invokeinterface call
+     */
+    public static Call interfaceCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+        return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
+            @Override
+            public MethodEmitter invoke(final MethodEmitter method) {
+                return method.invokeinterface(className, name, descriptor);
+            }
+        };
+    }
+
+    /**
+     * Create a FieldAccess representing a virtual field, that can be subject to put
+     * or get operations
+     *
+     * @param className name of the class where the field is a member
+     * @param name      name of the field
+     * @param desc      type descriptor of the field
+     *
+     * @return a field access object giving access code generation method for the virtual field
+     */
+    public static FieldAccess virtualField(final String className, final String name, final String desc) {
+        return new FieldAccess(className, name, desc) {
+            @Override
+            public MethodEmitter get(final MethodEmitter method) {
+                return method.getField(className, name, descriptor);
+            }
+
+            @Override
+            public void put(final MethodEmitter method) {
+                method.putField(className, name, descriptor);
+            }
+        };
+    }
+
+    /**
+     * Create a FieldAccess representing a virtual field, that can be subject to put
+     * or get operations
+     *
+     * @param clazz class where the field is a member
+     * @param name  name of the field
+     * @param type  type of the field
+     *
+     * @return a field access object giving access code generation method for the virtual field
+     */
+    public static FieldAccess virtualField(final Class<?> clazz, final String name, final Class<?> type) {
+        return virtualField(className(clazz), name, typeDescriptor(type));
+    }
+
+    /**
+     * Create a FieldAccess representing a static field, that can be subject to put
+     * or get operations
+     *
+     * @param className name of the class where the field is a member
+     * @param name      name of the field
+     * @param desc      type descriptor of the field
+     *
+     * @return a field access object giving access code generation method for the static field
+     */
+    public static FieldAccess staticField(final String className, final String name, final String desc) {
+        return new FieldAccess(className, name, desc) {
+            @Override
+            public MethodEmitter get(final MethodEmitter method) {
+                return method.getStatic(className, name, descriptor);
+            }
+
+            @Override
+            public void put(final MethodEmitter method) {
+                method.putStatic(className, name, descriptor);
+            }
+        };
+    }
+
+    /**
+     * Create a FieldAccess representing a static field, that can be subject to put
+     * or get operations
+     *
+     * @param clazz class where the field is a member
+     * @param name  name of the field
+     * @param type  type of the field
+     *
+     * @return a field access object giving access code generation method for the virtual field
+     */
+    public static FieldAccess staticField(final Class<?> clazz, final String name, final Class<?> type) {
+        return staticField(className(clazz), name, typeDescriptor(type));
+    }
+
+    /**
+     * Create a static call, looking up the method handle for it at the same time
+     *
+     * @param clazz  the class
+     * @param name   the name of the method
+     * @param rtype  the return type of the method
+     * @param ptypes the parameter types of the method
+     *
+     * @return the call object representing the static call
+     */
+    public static Call staticCall(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+        return staticCall(MethodHandles.publicLookup(), clazz, name, rtype, ptypes);
+    }
+
+    /**
+     * Create a static call, given an explicit lookup, looking up the method handle for it at the same time
+     *
+     * @param lookup the lookup
+     * @param clazz  the class
+     * @param name   the name of the method
+     * @param rtype  the return type
+     * @param ptypes the parameter types
+     *
+     * @return the call object representing the static call
+     */
+    public static Call staticCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+        return new Call(MH.findStatic(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
+            @Override
+            public MethodEmitter invoke(final MethodEmitter method) {
+                return method.invokestatic(className, name, descriptor);
+            }
+        };
+    }
+
+    /**
+     * Create a virtual call, looking up the method handle for it at the same time
+     *
+     * @param clazz  the class
+     * @param name   the name of the method
+     * @param rtype  the return type of the method
+     * @param ptypes the parameter types of the method
+     *
+     * @return the call object representing the virtual call
+     */
+    public static Call virtualCall(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+        return virtualCall(MethodHandles.publicLookup(), clazz, name, rtype, ptypes);
+    }
+
+    /**
+     * Create a virtual call, given an explicit lookup, looking up the method handle for it at the same time
+     *
+     * @param lookup the lookup
+     * @param clazz  the class
+     * @param name   the name of the method
+     * @param rtype  the return type
+     * @param ptypes the parameter types
+     *
+     * @return the call object representing the virtual call
+     */
+    public static Call virtualCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+        return new Call(MH.findVirtual(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
+            @Override
+            public MethodEmitter invoke(final MethodEmitter method) {
+                return method.invokevirtual(className, name, descriptor);
+            }
+        };
+    }
+
+    /**
+     * Private class representing an access. This can generate code into a method code or
+     * a field access.
+     */
+    private abstract static class Access {
+        protected final MethodHandle methodHandle;
+        protected final String       className;
+        protected final String       name;
+        protected final String       descriptor;
+
+        /**
+         * Constructor
+         *
+         * @param methodHandle methodHandle or null if none
+         * @param className    class name for access
+         * @param name         field or method name for access
+         * @param descriptor   descriptor for access field or method
+         */
+        protected Access(final MethodHandle methodHandle, final String className, final String name, final String descriptor) {
+            this.methodHandle = methodHandle;
+            this.className    = className;
+            this.name         = name;
+            this.descriptor   = descriptor;
+        }
+
+        /**
+         * Get the method handle, or null if access hasn't been looked up
+         *
+         * @return method handle
+         */
+        public MethodHandle methodHandle() {
+            return methodHandle;
+        }
+
+        /**
+         * Get the class name of the access
+         *
+         * @return the class name
+         */
+        public String className() {
+            return className;
+        }
+
+        /**
+         * Get the field name or method name of the access
+         *
+         * @return the name
+         */
+        public String name() {
+            return name;
+        }
+
+        /**
+         * Get the descriptor of the method or field of the access
+         *
+         * @return the descriptor
+         */
+        public String descriptor() {
+            return descriptor;
+        }
+    }
+
+    /**
+     * Field access - this can be used for generating code for static or
+     * virtual field accesses
+     */
+    public abstract static class FieldAccess extends Access {
+        /**
+         * Constructor
+         *
+         * @param className  name of the class where the field is
+         * @param name       name of the field
+         * @param descriptor descriptor of the field
+         */
+        protected FieldAccess(final String className, final String name, final String descriptor) {
+            super(null, className, name, descriptor);
+        }
+
+        /**
+         * Generate get code for the field
+         *
+         * @param emitter a method emitter
+         *
+         * @return the method emitter
+         */
+        protected abstract MethodEmitter get(final MethodEmitter emitter);
+
+        /**
+         * Generate put code for the field
+         *
+         * @param emitter a method emitter
+         */
+        protected abstract void put(final MethodEmitter emitter);
+    }
+
+    /**
+     * Call - this can be used for generating code for different types of calls
+     */
+    public abstract static class Call extends Access {
+
+        /**
+         * Constructor
+         *
+         * @param className  class name for the method of the call
+         * @param name       method name
+         * @param descriptor method descriptor
+         */
+        protected Call(final String className, final String name, final String descriptor) {
+            super(null, className, name, descriptor);
+        }
+
+        /**
+         * Constructor
+         *
+         * @param methodHandle method handle for the call if resolved
+         * @param className    class name for the method of the call
+         * @param name         method name
+         * @param descriptor   method descriptor
+         */
+        protected Call(final MethodHandle methodHandle, final String className, final String name, final String descriptor) {
+            super(methodHandle, className, name, descriptor);
+        }
+
+        /**
+         * Generate invocation code for the method
+         *
+         * @param emitter a method emitter
+         *
+         * @return the method emitter
+         */
+        protected abstract MethodEmitter invoke(final MethodEmitter emitter);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Condition.java b/nashorn/src/jdk/nashorn/internal/codegen/Condition.java
new file mode 100644
index 0000000..80ed029
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Condition.java
@@ -0,0 +1,93 @@
+/*
+ * 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.codegen;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.IFEQ;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFGE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFGT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFLE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFLT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFNE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPEQ;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPNE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPEQ;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPGE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPGT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPLE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPLT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPNE;
+
+/**
+ * Condition enum used for all kinds of jumps, regardless of type
+ */
+enum Condition {
+    EQ,
+    NE,
+    LE,
+    LT,
+    GE,
+    GT;
+
+    static int toUnary(final Condition c) {
+        switch (c) {
+        case EQ:
+            return IFEQ;
+        case NE:
+            return IFNE;
+        case LE:
+            return IFLE;
+        case LT:
+            return IFLT;
+        case GE:
+            return IFGE;
+        case GT:
+            return IFGT;
+        default:
+            assert false;
+            return -1;
+        }
+    }
+
+    static int toBinary(final Condition c, final boolean isObject) {
+        switch (c) {
+        case EQ:
+            return isObject ? IF_ACMPEQ : IF_ICMPEQ;
+        case NE:
+            return isObject ? IF_ACMPNE : IF_ICMPNE;
+        case LE:
+            return IF_ICMPLE;
+        case LT:
+            return IF_ICMPLT;
+        case GE:
+            return IF_ICMPGE;
+        case GT:
+            return IF_ICMPGT;
+        default:
+            assert false;
+            return -1;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ConstantData.java b/nashorn/src/jdk/nashorn/internal/codegen/ConstantData.java
new file mode 100644
index 0000000..631cdb3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ConstantData.java
@@ -0,0 +1,165 @@
+/*
+ * 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.codegen;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Manages constants needed by code generation.  Objects are maintained in an
+ * interning maps to remove duplicates.
+ */
+class ConstantData {
+    /** Constant table. */
+    final List<Object> constants;
+
+    /** Constant table string interning map. */
+    final Map<String, Integer> stringMap;
+
+    /** Constant table object interning map. */
+    final Map<Object, Integer> objectMap;
+
+    private static class ArrayWrapper {
+        private final Object array;
+        private final int    hashCode;
+
+        public ArrayWrapper(final Object array) {
+            this.array    = array;
+            this.hashCode = calcHashCode();
+        }
+
+        /**
+         * Calculate a shallow hashcode for the array.
+         * @return Hashcode with elements factored in.
+         */
+        private int calcHashCode() {
+            final Class<?> cls = array.getClass();
+
+            if (cls == Object[].class) {
+                return Arrays.hashCode((Object[])array);
+            } else if (cls == double[].class) {
+                return Arrays.hashCode((double[])array);
+            } if (cls == long[].class) {
+                return Arrays.hashCode((long[])array);
+            } if (cls == int[].class) {
+                return Arrays.hashCode((int[])array);
+            }
+
+            throw new AssertionError("ConstantData doesn't support " + cls);
+        }
+
+        @Override
+        public boolean equals(final Object other) {
+            if (!(other instanceof ArrayWrapper)) {
+                return false;
+            }
+
+            final Object otherArray = ((ArrayWrapper)other).array;
+
+            if (array == otherArray) {
+                return true;
+            }
+
+            final Class<?> cls = array.getClass();
+
+            if (cls == otherArray.getClass()) {
+                if (cls == Object[].class) {
+                    return Arrays.equals((Object[])array, (Object[])otherArray);
+                } else if (cls == double[].class) {
+                    return Arrays.equals((double[])array, (double[])otherArray);
+                } else if (cls == long[].class) {
+                    return Arrays.equals((long[])array, (long[])otherArray);
+                } else if (cls == int[].class) {
+                    return Arrays.equals((int[])array, (int[])otherArray);
+                }
+            }
+
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return hashCode;
+        }
+    }
+
+    /**
+     * Constructor
+     */
+    ConstantData() {
+        this.constants = new ArrayList<>();
+        this.stringMap = new HashMap<>();
+        this.objectMap = new HashMap<>();
+    }
+
+    /**
+     * Add a string to the constant data
+     *
+     * @param string the string to add
+     * @return the index in the constant pool that the string was given
+     */
+    public int add(final String string) {
+        final Integer value = stringMap.get(string);
+
+        if (value != null) {
+            return value.intValue();
+        }
+
+        constants.add(string);
+        final int index = constants.size() - 1;
+        stringMap.put(string, index);
+
+        return index;
+    }
+
+    /**
+     * Add an object to the constant data
+     *
+     * @param object the string to add
+     * @return the index in the constant pool that the object was given
+     */
+    public int add(final Object object) {
+        final Object  entry = object.getClass().isArray() ? new ArrayWrapper(object) : object;
+        final Integer value = objectMap.get(entry);
+
+        if (value != null) {
+            return value.intValue();
+        }
+
+        constants.add(object);
+        final int index = constants.size() - 1;
+        objectMap.put(entry, index);
+
+        return index;
+    }
+
+    Object[] toArray() {
+        return constants.toArray();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Emitter.java b/nashorn/src/jdk/nashorn/internal/codegen/Emitter.java
new file mode 100644
index 0000000..b9feeeb
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Emitter.java
@@ -0,0 +1,49 @@
+/*
+ * 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.codegen;
+
+/**
+ * Interface for anything that interacts with a low level bytecode
+ * generation module, for example ASM.
+ * <p>
+ * This is pretty generic, i.e. it can be a ClassEmitter, MethodEmitter
+ * or potentially even more fine grained stuff.
+ *
+ */
+public interface Emitter {
+
+    /**
+     * Register the start of emission for this CodeEmitter
+     */
+    public void begin();
+
+    /**
+     * Register the end of emission for this CodeEmitter.
+     * This is typically required before generated code can
+     * be requested from it
+     */
+    public void end();
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
new file mode 100644
index 0000000..83e75cc
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
@@ -0,0 +1,191 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
+import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
+
+import java.util.Iterator;
+import java.util.List;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+
+/**
+ * Analyze an object's characteristics for appropriate code generation. This
+ * is used for functions and for objects. A field object take a set of values which
+ * to assign to the various fields in the object. This is done by the generated code
+ *
+ * @param <T> the value type for the fields being written on object creation, e.g. Node
+ * @see jdk.nashorn.internal.ir.Node
+ */
+public abstract class FieldObjectCreator<T> extends ObjectCreator {
+    /** array of corresponding values to symbols (null for no values) */
+    private final List<T> values;
+
+    /** call site flags to be used for invocations */
+    private final int     callSiteFlags;
+
+    /**
+     * Constructor
+     *
+     * @param codegen  code generator
+     * @param keys     keys for fields in object
+     * @param symbols  symbols for fields in object
+     * @param values   list of values corresponding to keys
+     */
+    FieldObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<T> values) {
+        this(codegen, keys, symbols, values, false, false);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param codegen      code generator
+     * @param keys         keys for fields in object
+     * @param symbols      symbols for fields in object
+     * @param values       values (or null where no value) to be written to the fields
+     * @param isScope      is this a scope object
+     * @param hasArguments does the created object have an "arguments" property
+     */
+    FieldObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<T> values, final boolean isScope, final boolean hasArguments) {
+        super(codegen, keys, symbols, isScope, hasArguments);
+        this.values        = values;
+        this.callSiteFlags = codegen.getCallSiteFlags();
+    }
+
+    /**
+     * Loads the scope on the stack through the passed method emitter.
+     * @param method the method emitter to use
+     */
+    protected void loadScope(final MethodEmitter method) {
+        method.loadScope();
+    }
+
+    /**
+     * Construct an object.
+     *
+     * @param method the method emitter
+     */
+    @Override
+    protected void makeObject(final MethodEmitter method) {
+        makeMap();
+
+        method._new(getClassName()).dup(); // create instance
+        loadMap(method); //load the map
+
+        if (isScope()) {
+            loadScope(method);
+
+            if (hasArguments()) {
+                method.loadArguments();
+                method.invoke(constructorNoLookup(getClassName(), PropertyMap.class, ScriptObject.class, ARGUMENTS.type()));
+            } else {
+                method.invoke(constructorNoLookup(getClassName(), PropertyMap.class, ScriptObject.class));
+            }
+        } else {
+            method.invoke(constructorNoLookup(getClassName(), PropertyMap.class));
+        }
+
+        // Set values.
+        final Iterator<Symbol> symbolIter = symbols.iterator();
+        final Iterator<String> keyIter    = keys.iterator();
+        final Iterator<T>      valueIter  = values.iterator();
+
+        while (symbolIter.hasNext()) {
+            final Symbol symbol = symbolIter.next();
+            final String key    = keyIter.next();
+            final T      value  = valueIter.next();
+
+            if (symbol != null && value != null) {
+                final int index = ArrayIndex.getArrayIndexNoThrow(key);
+
+                if (index < 0) {
+                    putField(method, key, symbol.getFieldIndex(), value);
+                } else {
+                    putSlot(method, index, value);
+                }
+            }
+        }
+    }
+
+    /**
+     * Technique for loading an initial value. Defined by anonymous subclasses in code gen.
+     *
+     * @param value Value to load.
+     */
+    protected abstract void loadValue(T value);
+
+    /**
+     * Determine the type of a value. Defined by anonymous subclasses in code gen.
+     *
+     * @param value Value to inspect.
+     *
+     * @return Value type.
+     */
+    protected abstract Type getValueType(T value);
+
+    /**
+     * Store a value in a field of the generated class object.
+     *
+     * @param method      Script method.
+     * @param key         Property key.
+     * @param fieldIndex  Field number.
+     * @param value       Value to store.
+     */
+    private void putField(final MethodEmitter method, final String key, final int fieldIndex, final T value) {
+        method.dup();
+
+        loadValue(value);
+
+        final Type valueType = getValueType(value);
+        // for example when we have a with scope
+        if (valueType.isObject() || valueType.isBoolean()) {
+            method.convert(OBJECT);
+        }
+
+        method.convert(OBJECT);
+        method.putField(getClassName(), ObjectClassGenerator.getFieldName(fieldIndex, Type.OBJECT), typeDescriptor(Object.class));
+    }
+
+    /**
+     * Store a value in an indexed slot of a generated class object.
+     *
+     * @param method Script method.
+     * @param index  Slot index.
+     * @param value  Value to store.
+     */
+    private void putSlot(final MethodEmitter method, final int index, final T value) {
+        method.dup();
+        method.load(index);
+        loadValue(value);
+        method.dynamicSetIndex(callSiteFlags);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
new file mode 100644
index 0000000..28dfda7
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java
@@ -0,0 +1,924 @@
+/*
+ * 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.codegen;
+
+import java.util.HashSet;
+import java.util.List;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.Assignment;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.CallNode.EvalArgs;
+import jdk.nashorn.internal.ir.CaseNode;
+import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.DoWhileNode;
+import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.IndexNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ReferenceNode;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.RuntimeNode.Request;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.ir.TernaryNode;
+import jdk.nashorn.internal.ir.ThrowNode;
+import jdk.nashorn.internal.ir.TypeOverride;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.WhileNode;
+import jdk.nashorn.internal.ir.WithNode;
+import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.Debug;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.JSType;
+
+/**
+ * Lower to more primitive operations. After lowering, an AST has symbols and
+ * types. Lowering may also add specialized versions of methods to the script if
+ * the optimizer is turned on.
+ *
+ * Any expression that requires temporary storage as part of computation will
+ * also be detected here and give a temporary symbol
+ *
+ * For any op that we process in FinalizeTypes it is an absolute guarantee
+ * that scope and slot information is correct. This enables e.g. AccessSpecialization
+ * and frame optimizations
+ */
+
+final class FinalizeTypes extends NodeOperatorVisitor {
+
+    private static final DebugLogger LOG = new DebugLogger("finalize");
+
+    FinalizeTypes() {
+    }
+
+    @Override
+    public Node leave(final CallNode callNode) {
+        final EvalArgs evalArgs = callNode.getEvalArgs();
+        if (evalArgs != null) {
+            evalArgs.setCode(evalArgs.getCode().accept(this));
+        }
+
+        // AccessSpecializer - call return type may change the access for this location
+        final Node function = callNode.getFunction();
+        if (function instanceof ReferenceNode) {
+            setTypeOverride(callNode, ((ReferenceNode)function).getReference().getType());
+        }
+        return callNode;
+    }
+
+    private Node leaveUnary(final UnaryNode unaryNode) {
+        unaryNode.setRHS(convert(unaryNode.rhs(), unaryNode.getType()));
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveADD(final UnaryNode unaryNode) {
+        return leaveUnary(unaryNode);
+    }
+
+    @Override
+    public Node leaveBIT_NOT(final UnaryNode unaryNode) {
+        return leaveUnary(unaryNode);
+    }
+
+    @Override
+    public Node leaveCONVERT(final UnaryNode unaryNode) {
+        assert unaryNode.rhs().tokenType() != TokenType.CONVERT : "convert(convert encountered. check its origin and remove it";
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveDECINC(final UnaryNode unaryNode) {
+        specialize(unaryNode);
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveNEW(final UnaryNode unaryNode) {
+        assert unaryNode.getSymbol() != null && unaryNode.getSymbol().getSymbolType().isObject();
+        ((CallNode)unaryNode.rhs()).setIsNew();
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveSUB(final UnaryNode unaryNode) {
+        return leaveUnary(unaryNode);
+    }
+
+    /**
+     * Add is a special binary, as it works not only on arithmetic, but for
+     * strings etc as well.
+     */
+    @Override
+    public Node leaveADD(final BinaryNode binaryNode) {
+        final Node lhs = binaryNode.lhs();
+        final Node rhs = binaryNode.rhs();
+
+        final Type type = binaryNode.getType();
+
+        if (type.isObject()) {
+            if (!isAddString(binaryNode)) {
+                return new RuntimeNode(binaryNode, Request.ADD);
+            }
+        }
+
+        binaryNode.setLHS(convert(lhs, type));
+        binaryNode.setRHS(convert(rhs, type));
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveAND(final BinaryNode binaryNode) {
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveASSIGN(final BinaryNode binaryNode) {
+        Type destType = specialize(binaryNode);
+        if (destType == null) {
+            destType = binaryNode.getType();
+        }
+        binaryNode.setRHS(convert(binaryNode.rhs(), destType));
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveASSIGN_ADD(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_BIT_AND(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_BIT_OR(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_DIV(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_MOD(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_MUL(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SAR(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SHL(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SHR(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SUB(final BinaryNode binaryNode) {
+        return leaveASSIGN(binaryNode);
+    }
+
+    @Override
+    public Node leaveBIT_AND(BinaryNode binaryNode) {
+        assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : binaryNode.getSymbol();
+        return leaveBinary(binaryNode, Type.INT, Type.INT);
+    }
+
+    @Override
+    public Node leaveBIT_OR(BinaryNode binaryNode) {
+        assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger();
+        return leaveBinary(binaryNode, Type.INT, Type.INT);
+    }
+
+    @Override
+    public Node leaveBIT_XOR(BinaryNode binaryNode) {
+        assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger();
+        return leaveBinary(binaryNode, Type.INT, Type.INT);
+    }
+
+    @Override
+    public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
+        assert binaryNode.getSymbol() != null;
+        binaryNode.setRHS(discard(binaryNode.rhs()));
+        // AccessSpecializer - the type of rhs, which is the remaining value of this node may have changed
+        // in that case, update the node type as well
+        propagateType(binaryNode, binaryNode.lhs().getType());
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveCOMMARIGHT(final BinaryNode binaryNode) {
+        assert binaryNode.getSymbol() != null;
+        binaryNode.setLHS(discard(binaryNode.lhs()));
+        // AccessSpecializer - the type of rhs, which is the remaining value of this node may have changed
+        // in that case, update the node type as well
+        propagateType(binaryNode, binaryNode.rhs().getType());
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveDIV(final BinaryNode binaryNode) {
+        return leaveBinaryArith(binaryNode);
+    }
+
+
+    @Override
+    public Node leaveEQ(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.EQ);
+    }
+
+    @Override
+    public Node leaveEQ_STRICT(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.EQ_STRICT);
+    }
+
+    @Override
+    public Node leaveGE(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.GE);
+    }
+
+    @Override
+    public Node leaveGT(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.GT);
+    }
+
+    @Override
+    public Node leaveLE(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.LE);
+    }
+
+    @Override
+    public Node leaveLT(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.LT);
+    }
+
+    @Override
+    public Node leaveMOD(final BinaryNode binaryNode) {
+        return leaveBinaryArith(binaryNode);
+    }
+
+    @Override
+    public Node leaveMUL(final BinaryNode binaryNode) {
+        return leaveBinaryArith(binaryNode);
+    }
+
+    @Override
+    public Node leaveNE(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.NE);
+    }
+
+    @Override
+    public Node leaveNE_STRICT(final BinaryNode binaryNode) {
+        return leaveCmp(binaryNode, Request.NE_STRICT);
+    }
+
+    @Override
+    public Node leaveOR(final BinaryNode binaryNode) {
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveSAR(final BinaryNode binaryNode) {
+        return leaveBinary(binaryNode, Type.INT, Type.INT);
+    }
+
+    @Override
+    public Node leaveSHL(final BinaryNode binaryNode) {
+        return leaveBinary(binaryNode, Type.INT, Type.INT);
+    }
+
+    @Override
+    public Node leaveSHR(final BinaryNode binaryNode) {
+        assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isLong();
+        return leaveBinary(binaryNode, Type.INT, Type.INT);
+    }
+
+    @Override
+    public Node leaveSUB(final BinaryNode binaryNode) {
+        return leaveBinaryArith(binaryNode);
+    }
+
+    @Override
+    public Node enter(final Block block) {
+        updateSymbols(block);
+        return block;
+    }
+
+    @Override
+    public Node leave(final CatchNode catchNode) {
+        final Node exceptionCondition = catchNode.getExceptionCondition();
+        if (exceptionCondition != null) {
+            catchNode.setExceptionCondition(convert(exceptionCondition, Type.BOOLEAN));
+        }
+        return catchNode;
+    }
+
+    @Override
+    public Node enter(final DoWhileNode doWhileNode) {
+        return enter((WhileNode)doWhileNode);
+    }
+
+    @Override
+    public Node leave(final DoWhileNode doWhileNode) {
+        return leave((WhileNode)doWhileNode);
+    }
+
+    @Override
+    public Node leave(final ExecuteNode executeNode) {
+        executeNode.setExpression(discard(executeNode.getExpression()));
+        return executeNode;
+    }
+
+    @Override
+    public Node leave(final ForNode forNode) {
+        final Node init   = forNode.getInit();
+        final Node test   = forNode.getTest();
+        final Node modify = forNode.getModify();
+
+        if (forNode.isForIn()) {
+            forNode.setModify(convert(forNode.getModify(), Type.OBJECT)); // NASHORN-400
+            return forNode;
+        }
+
+        if (init != null) {
+            forNode.setInit(discard(init));
+        }
+
+        if (test != null) {
+            forNode.setTest(convert(test, Type.BOOLEAN));
+        } else {
+            assert forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + getCurrentFunctionNode();
+        }
+
+        if (modify != null) {
+            forNode.setModify(discard(modify));
+        }
+
+        return forNode;
+    }
+
+    @Override
+    public Node enter(final FunctionNode functionNode) {
+        if (functionNode.isLazy()) {
+            return null;
+        }
+
+        // If the function doesn't need a callee, we ensure its __callee__ symbol doesn't get a slot. We can't do
+        // this earlier, as access to scoped variables, self symbol, etc. in previous phases can all trigger the
+        // need for the callee.
+        if (!functionNode.needsCallee()) {
+            functionNode.getCalleeNode().getSymbol().setNeedsSlot(false);
+        }
+        // Similar reasoning applies to __scope__ symbol: if the function doesn't need either parent scope or its
+        // own scope, we ensure it doesn't get a slot, but we can't determine whether it needs a scope earlier than
+        // this phase.
+        if (!(functionNode.needsScope() || functionNode.needsParentScope())) {
+            functionNode.getScopeNode().getSymbol().setNeedsSlot(false);
+        }
+
+        updateSymbols(functionNode);
+        return functionNode;
+    }
+
+    @Override
+    public Node leave(final IfNode ifNode) {
+        ifNode.setTest(convert(ifNode.getTest(), Type.BOOLEAN));
+        return ifNode;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Node enter(final LiteralNode literalNode) {
+        if (literalNode instanceof ArrayLiteralNode) {
+            final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode;
+            final Node[]           array            = arrayLiteralNode.getValue();
+            final Type             elementType      = arrayLiteralNode.getElementType();
+
+            for (int i = 0; i < array.length; i++) {
+                final Node element = array[i];
+                if (element != null) {
+                    array[i] = convert(element.accept(this), elementType);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node leave(final ReturnNode returnNode) {
+        final Node expr = returnNode.getExpression();
+        if (expr != null) {
+            returnNode.setExpression(convert(expr, getCurrentFunctionNode().getReturnType()));
+        }
+        return returnNode;
+    }
+
+    @Override
+    public Node leave(final RuntimeNode runtimeNode) {
+        final List<Node> args = runtimeNode.getArgs();
+        for (final Node arg : args) {
+            assert !arg.getType().isUnknown();
+        }
+        return runtimeNode;
+    }
+
+    @Override
+    public Node leave(final SwitchNode switchNode) {
+        final Node           expression  = switchNode.getExpression();
+        final List<CaseNode> cases       = switchNode.getCases();
+        final boolean        allInteger  = switchNode.getTag().getSymbolType().isInteger();
+
+        if (!allInteger) {
+            switchNode.setExpression(convert(expression, Type.OBJECT));
+            for (final CaseNode caseNode : cases) {
+                final Node test = caseNode.getTest();
+                if (test != null) {
+                    caseNode.setTest(convert(test, Type.OBJECT));
+                }
+            }
+        }
+
+        return switchNode;
+    }
+
+    @Override
+    public Node leave(final TernaryNode ternaryNode) {
+        ternaryNode.setLHS(convert(ternaryNode.lhs(), Type.BOOLEAN));
+        return ternaryNode;
+    }
+
+    @Override
+    public Node leave(final ThrowNode throwNode) {
+        throwNode.setExpression(convert(throwNode.getExpression(), Type.OBJECT));
+        return throwNode;
+    }
+
+    @Override
+    public Node leave(final VarNode varNode) {
+
+        final Node rhs = varNode.getInit();
+        if (rhs != null) {
+            Type destType = specialize(varNode);
+            if (destType == null) {
+                destType = varNode.getType();
+            }
+            assert varNode.hasType() : varNode + " doesn't have a type";
+            varNode.setInit(convert(rhs, destType));
+        }
+        return varNode;
+    }
+
+    @Override
+    public Node leave(final WhileNode whileNode) {
+        final Node test = whileNode.getTest();
+        if (test != null) {
+            whileNode.setTest(convert(test, Type.BOOLEAN));
+        }
+        return whileNode;
+    }
+
+    @Override
+    public Node leave(final WithNode withNode) {
+        withNode.setExpression(convert(withNode.getExpression(), Type.OBJECT));
+        return withNode;
+    }
+
+    private static void updateSymbolsLog(final FunctionNode functionNode, final Symbol symbol, final boolean loseSlot) {
+        if (!symbol.isScope()) {
+            LOG.finest("updateSymbols: " + symbol + " => scope, because all vars in " + functionNode.getName() + " are in scope");
+        }
+        if (loseSlot && symbol.hasSlot()) {
+            LOG.finest("updateSymbols: " + symbol + " => no slot, because all vars in " + functionNode.getName() + " are in scope");
+        }
+    }
+
+    /**
+     * Called after a block or function node (subclass of block) is finished. Guarantees
+     * that scope and slot information is correct for every symbol
+     * @param block block for which to to finalize type info.
+     */
+    private static void updateSymbols(final Block block) {
+        if (!block.needsScope()) {
+            return; // nothing to do
+        }
+
+        assert !(block instanceof FunctionNode) || block.getFunction() == block;
+
+        final FunctionNode functionNode   = block.getFunction();
+        final List<Symbol> symbols        = block.getFrame().getSymbols();
+        final boolean      allVarsInScope = functionNode.allVarsInScope();
+        final boolean      isVarArg       = functionNode.isVarArg();
+
+        for (final Symbol symbol : symbols) {
+            if (symbol.isInternal() || symbol.isThis()) {
+                continue;
+            }
+
+            if (symbol.isVar()) {
+                if (allVarsInScope || symbol.isScope()) {
+                    updateSymbolsLog(functionNode, symbol, true);
+                    symbol.setIsScope();
+                    symbol.setNeedsSlot(false);
+                } else {
+                    assert symbol.hasSlot() : symbol + " should have a slot only, no scope";
+                }
+            } else if (symbol.isParam() && (allVarsInScope || isVarArg || symbol.isScope())) {
+                updateSymbolsLog(functionNode, symbol, isVarArg);
+                symbol.setIsScope();
+                symbol.setNeedsSlot(!isVarArg);
+            }
+        }
+    }
+
+    /**
+     * Exit a comparison node and do the appropriate replacements. We need to introduce runtime
+     * nodes late for comparisons as types aren't known until the last minute
+     *
+     * Both compares and adds may turn into runtimes node at this level as when we first bump
+     * into the op in Attr, we may type it according to what we know there, which may be wrong later
+     *
+     * e.g. i (int) < 5 -> normal compare
+     *     i = object
+     *  then the post pass that would add the conversion to the 5 needs to
+     *
+     * @param binaryNode binary node to leave
+     * @param request    runtime request
+     * @return lowered cmp node
+     */
+    @SuppressWarnings("fallthrough")
+    private Node leaveCmp(final BinaryNode binaryNode, final RuntimeNode.Request request) {
+        final Node lhs    = binaryNode.lhs();
+        final Node rhs    = binaryNode.rhs();
+
+        Type widest = Type.widest(lhs.getType(), rhs.getType());
+
+        boolean newRuntimeNode = false, finalized = false;
+        switch (request) {
+        case EQ_STRICT:
+        case NE_STRICT:
+            if (lhs.getType().isBoolean() != rhs.getType().isBoolean()) {
+                newRuntimeNode = true;
+                widest = Type.OBJECT;
+                finalized = true;
+            }
+            //fallthru
+        default:
+            if (newRuntimeNode || widest.isObject()) {
+                final RuntimeNode runtimeNode = new RuntimeNode(binaryNode, request);
+                if (finalized) {
+                    runtimeNode.setIsFinal();
+                }
+                return runtimeNode;
+            }
+            break;
+        }
+
+        binaryNode.setLHS(convert(lhs, widest));
+        binaryNode.setRHS(convert(rhs, widest));
+
+        return binaryNode;
+    }
+
+    /**
+     * Compute the binary arithmetic type given the lhs and an rhs of a binary expression
+     * @param lhsType  the lhs type
+     * @param rhsType  the rhs type
+     * @return the correct binary type
+     */
+    private static Type binaryArithType(final Type lhsType, final Type rhsType) {
+        if (!Compiler.shouldUseIntegerArithmetic()) {
+            return Type.NUMBER;
+        }
+        return Type.widest(lhsType, rhsType, Type.NUMBER);
+    }
+
+    private Node leaveBinaryArith(final BinaryNode binaryNode) {
+        final Type type = binaryArithType(binaryNode.lhs().getType(), binaryNode.rhs().getType());
+        return leaveBinary(binaryNode, type, type);
+    }
+
+    private Node leaveBinary(final BinaryNode binaryNode, final Type lhsType, final Type rhsType) {
+        binaryNode.setLHS(convert(binaryNode.lhs(), lhsType));
+        binaryNode.setRHS(convert(binaryNode.rhs(), rhsType));
+        return binaryNode;
+    }
+
+    /**
+     * A symbol (and {@link Property}) can be tagged as "may be primitive". This is
+     * used a hint for dual fields that it is even worth it to try representing this
+     * field as something other than java.lang.Object.
+     *
+     * @param node node in which to tag symbols as primitive
+     * @param to   which primitive type to use for tagging
+     */
+    private static void setCanBePrimitive(final Node node, final Type to) {
+        final HashSet<Node> exclude = new HashSet<>();
+
+        node.accept(new NodeVisitor() {
+            private void setCanBePrimitive(final Symbol symbol) {
+                LOG.info("*** can be primitive symbol " + symbol + " " + Debug.id(symbol));
+                symbol.setCanBePrimitive(to);
+            }
+
+            @Override
+            public Node enter(final IdentNode identNode) {
+                if (!exclude.contains(identNode)) {
+                    setCanBePrimitive(identNode.getSymbol());
+                }
+                return null;
+            }
+
+            @Override
+            public Node enter(final AccessNode accessNode) {
+                setCanBePrimitive(accessNode.getProperty().getSymbol());
+                return null;
+            }
+
+            @Override
+            public Node enter(final IndexNode indexNode) {
+                exclude.add(indexNode.getBase()); //prevent array base node to be flagged as primitive, but k in a[k++] is fine
+                return indexNode;
+            }
+        });
+    }
+
+    private static Type specialize(final Assignment<?> assignment) {
+        final Node node = ((Node)assignment);
+        final Node lhs = assignment.getAssignmentDest();
+        final Node rhs = assignment.getAssignmentSource();
+
+        if (!canHaveCallSiteType(lhs)) {
+            return null;
+        }
+
+        final Type to;
+        if (node.isSelfModifying()) {
+            to = node.getWidestOperationType();
+        } else {
+            to = rhs.getType();
+        }
+
+        if (!isSupportedCallSiteType(to)) {
+            //meaningless to specialize to boolean or object
+            return null;
+        }
+
+        setTypeOverride(lhs, to);
+        propagateType(node, to);
+
+        return to;
+    }
+
+
+    /**
+     * Is this a node that can have its type overridden. This is true for
+     * AccessNodes, IndexNodes and IdentNodes
+     *
+     * @param node the node to check
+     * @return true if node can have a callsite type
+     */
+    private static boolean canHaveCallSiteType(final Node node) {
+        return node instanceof TypeOverride && ((TypeOverride)node).canHaveCallSiteType();
+    }
+
+    /**
+     * Is the specialization type supported. Currently we treat booleans as objects
+     * and have no special boolean type accessor, thus booleans are ignored.
+     * TODO - support booleans? NASHORN-590
+     *
+     * @param castTo the type to check
+     * @return true if call site type is supported
+     */
+    private static boolean isSupportedCallSiteType(final Type castTo) {
+        return castTo.isNumeric(); // don't specializable for boolean
+    }
+
+    /**
+     * Override the type of a node for e.g. access specialization of scope
+     * objects. Normally a variable can only get a wider type and narrower type
+     * sets are ignored. Not that a variable can still be on object type as
+     * per the type analysis, but a specific access may be narrower, e.g. if it
+     * is used in an arithmetic op. This overrides a type, regardless of
+     * type environment and is used primarily by the access specializer
+     *
+     * @param node    node for which to change type
+     * @param to      new type
+     */
+    private static void setTypeOverride(final Node node, final Type to) {
+        final Type from = node.getType();
+        if (!node.getType().equals(to)) {
+            LOG.info("Changing call override type for '" + node + "' from " + node.getType() + " to " + to);
+            if (!to.isObject() && from.isObject()) {
+                setCanBePrimitive(node, to);
+            }
+        }
+        LOG.info("Type override for lhs in '" + node + "' => " + to);
+        ((TypeOverride)node).setType(to);
+    }
+
+    /**
+     * Add an explicit conversion. This is needed when attribution has created types
+     * that do not mesh into an op type, e.g. a = b, where b is object and a is double
+     * at the end of Attr, needs explicit conversion logic.
+     *
+     * An explicit conversion can be one of the following:
+     *   + Convert a literal - just replace it with another literal
+     *   + Convert a scope object - just replace the type of the access, e.g. get()D->get()I
+     *   + Explicit convert placement, e.g. a = (double)b - all other cases
+     *
+     * No other part of the world after {@link Attr} may introduce new symbols. This
+     * is the only place.
+     *
+     * @param node node to convert
+     * @param to   destination type
+     * @return     conversion node
+     */
+    private Node convert(final Node node, final Type to) {
+        assert !to.isUnknown() : "unknown type for " + node + " class=" + node.getClass();
+        assert node != null : "node is null";
+        assert node.getSymbol() != null : "node " + node + " has no symbol!";
+        assert node.tokenType() != TokenType.CONVERT : "assert convert in convert " + node + " in " + getCurrentFunctionNode();
+
+        final Type from = node.getType();
+
+        if (Type.areEquivalent(from, to)) {
+            return node;
+        }
+
+        if (from.isObject() && to.isObject()) {
+            return node;
+        }
+
+        Node resultNode = node;
+
+        if (node instanceof LiteralNode && !to.isObject()) {
+            final LiteralNode<?> newNode = new LiteralNodeConstantEvaluator((LiteralNode<?>)node, to).eval();
+            if (newNode != null) {
+                resultNode = newNode;
+            }
+        } else {
+            if (canHaveCallSiteType(node) && isSupportedCallSiteType(to)) {
+                setTypeOverride(node, to);
+                return resultNode;
+            }
+            resultNode = new UnaryNode(node.getSource(), Token.recast(node.getToken(), TokenType.CONVERT), node);
+        }
+
+        LOG.info("CONVERT('" + node + "', " + to + ") => '" + resultNode + "'");
+
+        //This is the only place in this file that can create new temporaries
+        //FinalizeTypes may not introduce ANY node that is not a conversion.
+        getCurrentFunctionNode().newTemporary(getCurrentBlock().getFrame(), to, resultNode);
+        resultNode.copyTerminalFlags(node);
+
+        return resultNode;
+    }
+
+    private static Node discard(final Node node) {
+        node.setDiscard(true);
+
+        if (node.getSymbol() != null) {
+            final Node discard = new UnaryNode(node.getSource(), Token.recast(node.getToken(), TokenType.DISCARD), node);
+            //discard never has a symbol in the discard node - then it would be a nop
+            discard.copyTerminalFlags(node);
+            return discard;
+        }
+
+        // node has no result (symbol) so we can keep it the way it is
+        return node;
+    }
+
+    /**
+     * Whenever an expression like an addition or an assignment changes type, it
+     * may be that case that {@link Attr} created a symbol for an intermediate
+     * result of the expression, say for an addition. This also has to be updated
+     * if the expression type changes.
+     *
+     * Assignments use their lhs as node symbol, and in this case we can't modify
+     * it. Then {@link CodeGenerator#Store} needs to do an explicit conversion.
+     * This is happens very rarely.
+     *
+     * @param node
+     * @param to
+     */
+    private static void propagateType(final Node node, final Type to) {
+        final Symbol symbol = node.getSymbol();
+        if (symbol.isTemp()) {
+            symbol.setTypeOverride(to);
+            LOG.info("Type override for temporary in '" + node + "' => " + to);
+        }
+    }
+
+    /**
+     * Determine if the outcome of + operator is a string.
+     *
+     * @param node  Node to test.
+     * @return true if a string result.
+     */
+    private boolean isAddString(final Node node) {
+        if (node instanceof BinaryNode && node.isTokenType(TokenType.ADD)) {
+            final BinaryNode binaryNode = (BinaryNode)node;
+            final Node lhs = binaryNode.lhs();
+            final Node rhs = binaryNode.rhs();
+
+            return isAddString(lhs) || isAddString(rhs);
+        }
+
+        return node instanceof LiteralNode<?> && ((LiteralNode<?>)node).isString();
+    }
+
+    /**
+     * Whenever an explicit conversion is needed and the convertee is a literal, we can
+     * just change the literal
+     */
+    static class LiteralNodeConstantEvaluator extends FoldConstants.ConstantEvaluator<LiteralNode<?>> {
+        private final Type type;
+
+        LiteralNodeConstantEvaluator(final LiteralNode<?> parent, final Type type) {
+            super(parent);
+            this.type = type;
+        }
+
+        @Override
+        protected LiteralNode<?> eval() {
+            final Object value = ((LiteralNode<?>)parent).getValue();
+
+            LiteralNode<?> literalNode = null;
+
+            if (type.isString()) {
+                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toString(value));
+            } else if (type.isBoolean()) {
+                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toBoolean(value));
+            } else if (type.isInteger()) {
+                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toInt32(value));
+            } else if (type.isLong()) {
+                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toLong(value));
+            } else if (type.isNumber() || parent.getType().isNumeric() && !parent.getType().isNumber()) {
+                literalNode = LiteralNode.newInstance(source, token, finish, JSType.toNumber(value));
+            }
+
+            if (literalNode != null) {
+                //inherit literal symbol for attr.
+                literalNode.setSymbol(parent.getSymbol());
+            }
+
+            return literalNode;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java
new file mode 100644
index 0000000..4ea53a0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java
@@ -0,0 +1,281 @@
+/*
+ * 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.codegen;
+
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.EmptyNode;
+import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.TernaryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * Simple constant folding pass, executed before IR is starting to be lowered.
+ */
+final class FoldConstants extends NodeVisitor {
+
+    private static final DebugLogger LOG = new DebugLogger("fold");
+
+    FoldConstants() {
+    }
+
+    @Override
+    public Node leave(final UnaryNode unaryNode) {
+        final LiteralNode<?> literalNode = new UnaryNodeConstantEvaluator(unaryNode).eval();
+        if (literalNode != null) {
+            LOG.info("Unary constant folded " + unaryNode + " to " + literalNode);
+            return literalNode;
+        }
+        return unaryNode;
+    }
+
+    @Override
+    public Node leave(final BinaryNode binaryNode) {
+        final LiteralNode<?> literalNode = new BinaryNodeConstantEvaluator(binaryNode).eval();
+        if (literalNode != null) {
+            LOG.info("Binary constant folded " + binaryNode + " to " + literalNode);
+            return literalNode;
+        }
+        return binaryNode;
+    }
+
+    @Override
+    public Node leave(final IfNode ifNode) {
+        final Node test = ifNode.getTest();
+        if (test instanceof LiteralNode) {
+            final Block shortCut = ((LiteralNode<?>)test).isTrue() ? ifNode.getPass() : ifNode.getFail();
+            if (shortCut != null) {
+                return new ExecuteNode(shortCut);
+            }
+            return new EmptyNode(ifNode);
+        }
+        return ifNode;
+    }
+
+    @Override
+    public Node leave(final TernaryNode ternaryNode) {
+        final Node test = ternaryNode.lhs();
+        if (test instanceof LiteralNode) {
+            return ((LiteralNode<?>)test).isTrue() ? ternaryNode.rhs() : ternaryNode.third();
+        }
+        return ternaryNode;
+    }
+
+    /**
+     * Helper class to evaluate constant expressions at compile time This is
+     * also a simplifier used by BinaryNode visits, UnaryNode visits and
+     * conversions.
+     */
+    abstract static class ConstantEvaluator<T extends Node> {
+        protected T            parent;
+        protected final Source source;
+        protected final long   token;
+        protected final int    finish;
+
+        protected ConstantEvaluator(final T parent) {
+            this.parent = parent;
+            this.source = parent.getSource();
+            this.token  = parent.getToken();
+            this.finish = parent.getFinish();
+        }
+
+        /**
+         * Returns a literal node that replaces the given parent node, or null if replacement
+         * is impossible
+         * @return the literal node
+         */
+        protected abstract LiteralNode<?> eval();
+    }
+
+    private static class UnaryNodeConstantEvaluator extends ConstantEvaluator<UnaryNode> {
+        UnaryNodeConstantEvaluator(final UnaryNode parent) {
+            super(parent);
+        }
+
+        @Override
+        protected LiteralNode<?> eval() {
+            final Node rhsNode = parent.rhs();
+
+            if (!(rhsNode instanceof LiteralNode)) {
+                return null;
+            }
+
+            final LiteralNode<?> rhs = (LiteralNode<?>)rhsNode;
+            final boolean rhsInteger = rhs.getType().isInteger();
+
+            LiteralNode<?> literalNode;
+
+            switch (parent.tokenType()) {
+            case ADD:
+                if (rhsInteger) {
+                    literalNode = LiteralNode.newInstance(source, token, finish, rhs.getInt32());
+                } else {
+                    literalNode = LiteralNode.newInstance(source, token, finish, rhs.getNumber());
+                }
+                break;
+            case SUB:
+                if (rhsInteger && rhs.getInt32() != 0) { // @see test/script/basic/minuszero.js
+                    literalNode = LiteralNode.newInstance(source, token, finish, -rhs.getInt32());
+                } else {
+                    literalNode = LiteralNode.newInstance(source, token, finish, -rhs.getNumber());
+                }
+                break;
+            case NOT:
+                literalNode = LiteralNode.newInstance(source, token, finish, !rhs.getBoolean());
+                break;
+            case BIT_NOT:
+                literalNode = LiteralNode.newInstance(source, token, finish, ~rhs.getInt32());
+                break;
+            default:
+                return null;
+            }
+
+            return literalNode;
+        }
+    }
+
+    //TODO add AND and OR with one constant parameter (bitwise)
+    private static class BinaryNodeConstantEvaluator extends ConstantEvaluator<BinaryNode> {
+        BinaryNodeConstantEvaluator(final BinaryNode parent) {
+            super(parent);
+        }
+
+        @Override
+        protected LiteralNode<?> eval() {
+            LiteralNode<?> result;
+
+            result = reduceTwoLiterals();
+            if (result != null) {
+                return result;
+            }
+
+            result = reduceOneLiteral();
+            if (result != null) {
+                return result;
+            }
+
+            return null;
+        }
+
+        @SuppressWarnings("static-method")
+        private LiteralNode<?> reduceOneLiteral() {
+            //TODO handle patterns like AND, OR, numeric ops that can be strength reduced but not replaced by a single literal node etc
+            return null;
+        }
+
+        private LiteralNode<?> reduceTwoLiterals() {
+            if (!(parent.lhs() instanceof LiteralNode && parent.rhs() instanceof LiteralNode)) {
+                return null;
+            }
+
+            final LiteralNode<?> lhs = (LiteralNode<?>)parent.lhs();
+            final LiteralNode<?> rhs = (LiteralNode<?>)parent.rhs();
+
+            final Type widest = Type.widest(lhs.getType(), rhs.getType());
+
+            boolean isInteger = widest.isInteger();
+            boolean isLong    = widest.isLong();
+
+            double value;
+
+            switch (parent.tokenType()) {
+            case DIV:
+                value = lhs.getNumber() / rhs.getNumber();
+                break;
+            case ADD:
+                if ((lhs.isString() || rhs.isNumeric()) && (rhs.isString() || rhs.isNumeric())) {
+                    Object res = ScriptRuntime.ADD(lhs.getObject(), rhs.getObject());
+                    if (res instanceof Number) {
+                        value = ((Number)res).doubleValue();
+                        break;
+                    }
+                    assert res instanceof CharSequence : res + " was not a CharSequence, it was a " + res.getClass();
+                    return LiteralNode.newInstance(source, token, finish, res.toString());
+                }
+                return null;
+            case MUL:
+                value = lhs.getNumber() * rhs.getNumber();
+                break;
+            case MOD:
+                value = lhs.getNumber() % rhs.getNumber();
+                break;
+            case SUB:
+                value = lhs.getNumber() - rhs.getNumber();
+                break;
+            case SHR:
+                return LiteralNode.newInstance(source, token, finish, (lhs.getInt32() >>> rhs.getInt32()) & 0xffff_ffffL);
+            case SAR:
+                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() >> rhs.getInt32());
+            case SHL:
+                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() << rhs.getInt32());
+            case BIT_XOR:
+                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() ^ rhs.getInt32());
+            case BIT_AND:
+                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() & rhs.getInt32());
+            case BIT_OR:
+                return LiteralNode.newInstance(source, token, finish, lhs.getInt32() | rhs.getInt32());
+            case GE:
+                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.GE(lhs.getObject(), rhs.getObject()));
+            case LE:
+                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.LE(lhs.getObject(), rhs.getObject()));
+            case GT:
+                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.GT(lhs.getObject(), rhs.getObject()));
+            case LT:
+                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.LT(lhs.getObject(), rhs.getObject()));
+            case NE:
+                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.NE(lhs.getObject(), rhs.getObject()));
+            case NE_STRICT:
+                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.NE_STRICT(lhs.getObject(), rhs.getObject()));
+            case EQ:
+                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.EQ(lhs.getObject(), rhs.getObject()));
+            case EQ_STRICT:
+                return LiteralNode.newInstance(source, token, finish, ScriptRuntime.EQ_STRICT(lhs.getObject(), rhs.getObject()));
+            default:
+                return null;
+            }
+
+            isInteger &= value != 0.0 && JSType.isRepresentableAsInt(value);
+            isLong    &= value != 0.0 && JSType.isRepresentableAsLong(value);
+
+            if (isInteger) {
+                return LiteralNode.newInstance(source, token, finish, JSType.toInt32(value));
+            } else if (isLong) {
+                return LiteralNode.newInstance(source, token, finish, JSType.toLong(value));
+            }
+
+            return LiteralNode.newInstance(source, token, finish, value);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Frame.java b/nashorn/src/jdk/nashorn/internal/codegen/Frame.java
new file mode 100644
index 0000000..b72456b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Frame.java
@@ -0,0 +1,196 @@
+/*
+ * 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.codegen;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import jdk.nashorn.internal.ir.Symbol;
+
+/**
+ * Tracks the variable area state.
+ *
+ */
+public final class Frame {
+    /** Previous frame. */
+    private Frame previous;
+
+    /** Current variables. */
+    private final ArrayList<Symbol> symbols;
+
+    /** Number of slots in previous frame. */
+    private int baseCount;
+
+    /** Number of slots in this frame. */
+    private int count;
+
+    /**
+     * Constructor.
+     *
+     * @param previous frame, the parent variable frame
+     */
+    public Frame(final Frame previous) {
+        this.previous  = previous;
+        this.symbols   = new ArrayList<>();
+        this.baseCount = getBaseCount();
+        this.count     = 0;
+    }
+
+    /**
+     * Copy constructor
+     * @param frame
+     * @param symbols
+     */
+    private Frame(final Frame frame, final List<Symbol> symbols) {
+        this.previous  = frame.getPrevious() == null ? null : new Frame(frame.getPrevious(), frame.getPrevious().getSymbols());
+        this.symbols   = new ArrayList<>(frame.getSymbols());
+        this.baseCount = frame.getBaseCount();
+        this.count     = frame.getCount();
+    }
+
+    /**
+     * Copy the frame
+     *
+     * @return a new frame with the identical contents
+     */
+    public Frame copy() {
+        return new Frame(this, getSymbols());
+    }
+
+    /**
+     * Add a new variable to the frame.
+     * @param symbol Symbol representing variable.
+     */
+    public void addSymbol(final Symbol symbol) {
+        final int slot = symbol.getSlot();
+        if (slot < 0) {
+            symbols.add(symbol);
+            count += symbol.slotCount();
+        }
+    }
+
+    /**
+     * Realign slot numbering prior to code generation.
+     * @return Number of slots in frame.
+     */
+    public int realign() {
+        baseCount = getBaseCount();
+        count     = 0;
+
+        for (final Symbol symbol : symbols) {
+            if (symbol.hasSlot()) {
+                symbol.setSlot(baseCount + count);
+                count += symbol.slotCount();
+            }
+        }
+
+        return count;
+    }
+
+    /**
+     * Return the slot count of previous frames.
+     * @return Number of slots in previous frames.
+     */
+    private int getBaseCount() {
+        return previous != null ? previous.getSlotCount() : 0;
+    }
+
+    /**
+     * Determine the number of slots to top of frame.
+     * @return Number of slots in total.
+     */
+    public int getSlotCount() {
+        return baseCount + count;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        Frame f = this;
+        boolean hasPrev = false;
+        int pos = 0;
+
+        do {
+            if (hasPrev) {
+                sb.append("\n");
+            }
+
+            sb.append("#").
+                append(pos++).
+                append(" {baseCount:").
+                append(baseCount).
+                append(", ").
+                append("count:").
+                append(count).
+                append("} ");
+
+            for (final Symbol var : f.getSymbols()) {
+                sb.append('[').
+                    append(var.toString()).
+                    append(' ').
+                    append(var.hashCode()).
+                    append("] ");
+            }
+
+            f = f.getPrevious();
+            hasPrev = true;
+        } while (f != null);
+
+        return sb.toString();
+    }
+
+    /**
+     * Get variable count for this frame
+     * @return variable count
+     */
+    public int getCount() {
+        return count;
+    }
+
+    /**
+     * Get previous frame
+     * @return previous frame
+     */
+    public Frame getPrevious() {
+        return previous;
+    }
+
+    /**
+     * Set previous frame
+     * @param previous previous frame
+     */
+    public void setPrevious(final Frame previous) {
+        this.previous = previous;
+    }
+
+    /**
+     * Get symbols in frame
+     * @return a list of symbols in this frame
+     */
+    public List<Symbol> getSymbols() {
+        return Collections.unmodifiableList(symbols);
+    }
+ }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java b/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java
new file mode 100644
index 0000000..ded12b0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java
@@ -0,0 +1,213 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
+
+/**
+ * Class that generates function signatures for dynamic calls
+ */
+public final class FunctionSignature {
+
+    /** parameter types that ASM can understand */
+    private final Type[] paramTypes;
+
+    /** return type that ASM can understand */
+    private final Type returnType;
+
+    /** valid Java descriptor string for function */
+    private final String descriptor;
+
+    /** {@link MethodType} for function */
+    private final MethodType methodType;
+
+    /**
+     * Constructor
+     *
+     * Create a FunctionSignature given arguments as AST Nodes
+     *
+     * @param hasSelf   does the function have a self slot?
+     * @param hasCallee does the function need a callee variable
+     * @param retType   what is the return type
+     * @param args      argument list of AST Nodes
+     */
+    public FunctionSignature(final boolean hasSelf, final boolean hasCallee, final Type retType, final List<? extends Node> args) {
+        this(hasSelf, hasCallee, retType, FunctionSignature.typeArray(args));
+    }
+
+    /**
+     * Constructor
+     *
+     * Create a FunctionSignature given arguments as AST Nodes
+     *
+     * @param hasSelf does the function have a self slot?
+     * @param hasCallee does the function need a callee variable
+     * @param retType what is the return type
+     * @param nArgs   number of arguments
+     */
+    public FunctionSignature(final boolean hasSelf, final boolean hasCallee, final Type retType, final int nArgs) {
+        this(hasSelf, hasCallee, retType, FunctionSignature.objectArgs(nArgs));
+    }
+
+    /**
+     * Constructor
+     *
+     * Create a FunctionSignature given argument types only
+     *
+     * @param hasSelf   does the function have a self slot?
+     * @param hasCallee does the function have a callee slot?
+     * @param retType   what is the return type
+     * @param argTypes  argument list of AST Nodes
+     */
+    private FunctionSignature(final boolean hasSelf, final boolean hasCallee, final Type retType, final Type... argTypes) {
+        final boolean isVarArg;
+
+        int count = 1;
+
+        if (argTypes == null) {
+            isVarArg = true;
+        } else {
+            isVarArg = argTypes.length > LinkerCallSite.ARGLIMIT;
+            count    = isVarArg ? 1 : argTypes.length;
+        }
+
+        if (hasCallee) {
+            count++;
+        }
+        if (hasSelf) {
+            count++;
+        }
+
+        paramTypes = new Type[count];
+
+        int next = 0;
+        if (hasCallee) {
+            paramTypes[next++] = Type.typeFor(ScriptFunction.class);
+        }
+
+        if (hasSelf) {
+            paramTypes[next++] = Type.OBJECT;
+        }
+
+        if (isVarArg) {
+            paramTypes[next] = Type.OBJECT_ARRAY;
+        } else if (argTypes != null) {
+            for (int j = 0; next < count;) {
+                final Type type = argTypes[j++];
+                // TODO: for now, turn java/lang/String into java/lang/Object as we aren't as specific.
+                paramTypes[next++] = type.isObject() ? Type.OBJECT : type;
+            }
+        } else {
+            assert false : "isVarArgs cannot be false when argTypes are null";
+        }
+
+        this.returnType = retType;
+        this.descriptor = Type.getMethodDescriptor(returnType, paramTypes);
+
+        final List<Class<?>> paramTypeList = new ArrayList<>();
+        for (final Type paramType : paramTypes) {
+            paramTypeList.add(paramType.getTypeClass());
+        }
+
+        this.methodType = MH.type(returnType.getTypeClass(), paramTypeList.toArray(new Class[paramTypes.length]));
+    }
+
+    /**
+     * Create a function signature given a function node, using as much
+     * type information for parameters and return types that is availabe
+     *
+     * @param functionNode the function node
+     */
+    public FunctionSignature(final FunctionNode functionNode) {
+        this(
+            true,
+            functionNode.needsCallee(),
+            functionNode.getReturnType(),
+            (functionNode.isVarArg() && !functionNode.isScript()) ?
+                null :
+                functionNode.getParameters());
+    }
+
+    /**
+     * Internal function that converts an array of nodes to their Types
+     *
+     * @param args node arg list
+     *
+     * @return the array of types
+     */
+    private static Type[] typeArray(final List<? extends Node> args) {
+        if (args == null) {
+            return null;
+        }
+
+        final Type[] typeArray = new Type[args.size()];
+
+        int pos = 0;
+        for (final Node arg : args) {
+            typeArray[pos++] = arg.getType();
+        }
+
+        return typeArray;
+    }
+
+    @Override
+    public String toString() {
+        return descriptor;
+    }
+
+    /**
+     * @return the number of param types
+     */
+    public int size() {
+        return paramTypes.length;
+    }
+
+    /**
+     * Return the {@link MethodType} for this function signature
+     * @return the method type
+     */
+    public MethodType getMethodType() {
+        return methodType;
+    }
+
+    private static Type[] objectArgs(final int nArgs) {
+        final Type[] array = new Type[nArgs];
+        for (int i = 0; i < nArgs; i++) {
+            array[i] = Type.OBJECT;
+        }
+        return array;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Label.java b/nashorn/src/jdk/nashorn/internal/codegen/Label.java
new file mode 100644
index 0000000..9d28caa
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Label.java
@@ -0,0 +1,83 @@
+/*
+ * 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.codegen;
+
+import java.util.ArrayDeque;
+
+import jdk.nashorn.internal.codegen.types.Type;
+
+/**
+ * Abstraction for labels, separating a label from the underlying
+ * byte code emitter. Also augmenting label with e.g. a name
+ * for easier debugging and reading code
+ *
+ * see -Dnashorn.codegen.debug, --log=codegen
+ */
+public class Label extends jdk.internal.org.objectweb.asm.Label {
+    /** Name of this label */
+    private final String name;
+
+    /** Type stack at this label */
+    private ArrayDeque<Type> stack;
+
+    /**
+     * Constructor
+     *
+     * @param name name of this label
+     */
+    public Label(final String name) {
+        super();
+        this.name = name;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param label a label to clone
+     */
+    public Label(final Label label) {
+        super();
+        this.name = label.name;
+    }
+
+    ArrayDeque<Type> getStack() {
+        return stack;
+    }
+
+    void setStack(final ArrayDeque<Type> stack) {
+        this.stack = stack;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        String s = super.toString();
+        s = s.substring(1, s.length());
+        sb.append(name).append('_').append(Long.toHexString(Long.parseLong(s)));
+
+        return sb.toString();
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
new file mode 100644
index 0000000..7a83469
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
@@ -0,0 +1,975 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SCRIPT_RETURN;
+import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.List;
+import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.BaseNode;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BreakNode;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.CaseNode;
+import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ContinueNode;
+import jdk.nashorn.internal.ir.DoWhileNode;
+import jdk.nashorn.internal.ir.EmptyNode;
+import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.IndexNode;
+import jdk.nashorn.internal.ir.LabelNode;
+import jdk.nashorn.internal.ir.LabeledNode;
+import jdk.nashorn.internal.ir.LineNumberNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.ir.ThrowNode;
+import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.WhileNode;
+import jdk.nashorn.internal.ir.WithNode;
+import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * Lower to more primitive operations. After lowering, an AST still has no symbols
+ * and types, but several nodes have been turned into more low level constructs
+ * and control flow termination criteria have been computed.
+ *
+ * We do things like code copying/inlining of finallies here, as it is much
+ * harder and context dependent to do any code copying after symbols have been
+ * finalized.
+ */
+
+final class Lower extends NodeOperatorVisitor {
+
+    /**
+     * Nesting level stack. Currently just used for loops to avoid the problem
+     * with terminal bodies that end with throw/return but still do continues to
+     * outer loops or same loop.
+     */
+    private final Deque<Node> nesting;
+
+    private static final DebugLogger LOG = new DebugLogger("lower");
+
+    private Node lastStatement;
+
+    private List<Node> statements;
+
+    /**
+     * Constructor.
+     *
+     * @param compiler the compiler
+     */
+    Lower() {
+        this.nesting    = new ArrayDeque<>();
+        this.statements = new ArrayList<>();
+    }
+
+    @Override
+    public Node enter(final Block block) {
+        final Node       savedLastStatement = lastStatement;
+        final List<Node> savedStatements    = statements;
+
+        try {
+            this.statements = new ArrayList<>();
+            for (final Node statement : block.getStatements()) {
+                statement.accept(this);
+                /*
+                 * This is slightly unsound, for example if we have a loop with
+                 * a guarded statement like if (x) continue in the body and the
+                 * body ends with TERMINAL, e.g. return; we removed the continue
+                 * before we had the loop stack, as all we cared about was a
+                 * return last in the loop.
+                 *
+                 * @see NASHORN-285
+                 */
+                if (lastStatement != null && lastStatement.isTerminal()) {
+                    copyTerminal(block, lastStatement);
+                    break;
+                }
+            }
+            block.setStatements(statements);
+
+        } finally {
+            this.statements = savedStatements;
+            this.lastStatement = savedLastStatement;
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final BreakNode breakNode) {
+        return enterBreakOrContinue(breakNode);
+    }
+
+    @Override
+    public Node enter(final CallNode callNode) {
+        final Node function = markerFunction(callNode.getFunction());
+        callNode.setFunction(function);
+        checkEval(callNode); //check if this is an eval call and store the information
+        return callNode;
+    }
+
+    @Override
+    public Node leave(final CaseNode caseNode) {
+        caseNode.copyTerminalFlags(caseNode.getBody());
+        return caseNode;
+    }
+
+    @Override
+    public Node leave(final CatchNode catchNode) {
+        catchNode.copyTerminalFlags(catchNode.getBody());
+        addStatement(catchNode);
+        return catchNode;
+    }
+
+    @Override
+    public Node enter(final ContinueNode continueNode) {
+        return enterBreakOrContinue(continueNode);
+    }
+
+    @Override
+    public Node enter(final DoWhileNode doWhileNode) {
+        return enter((WhileNode)doWhileNode);
+    }
+
+    @Override
+    public Node leave(final DoWhileNode doWhileNode) {
+        return leave((WhileNode)doWhileNode);
+    }
+
+    @Override
+    public Node enter(final EmptyNode emptyNode) {
+        return null;
+    }
+
+    @Override
+    public Node leave(final ExecuteNode executeNode) {
+        final Node expr = executeNode.getExpression();
+
+        if (getCurrentFunctionNode().isScript()) {
+            if (!(expr instanceof Block)) {
+                if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) {
+                    executeNode.setExpression(new BinaryNode(executeNode.getSource(), Token.recast(executeNode.getToken(), TokenType.ASSIGN),
+                            getCurrentFunctionNode().getResultNode(),
+                            expr));
+                }
+            }
+        }
+
+        copyTerminal(executeNode, executeNode.getExpression());
+        addStatement(executeNode);
+
+        return executeNode;
+    }
+
+    @Override
+    public Node enter(final ForNode forNode) {
+        nest(forNode);
+        return forNode;
+    }
+
+    @Override
+    public Node leave(final ForNode forNode) {
+        final Node  test = forNode.getTest();
+        final Block body = forNode.getBody();
+
+        if (!forNode.isForIn() && test == null) {
+            setHasGoto(forNode);
+        }
+
+        final boolean escapes = controlFlowEscapes(body);
+        if (escapes) {
+            setTerminal(body, false);
+        }
+
+        // pop the loop from the loop context
+        unnest(forNode);
+
+        if (!forNode.isForIn() && conservativeAlwaysTrue(test)) {
+            forNode.setTest(null);
+            setTerminal(forNode, !escapes);
+        }
+
+        addStatement(forNode);
+
+        return forNode;
+    }
+
+    @Override
+    public Node enter(final FunctionNode functionNode) {
+        LOG.info("START FunctionNode: " + functionNode.getName());
+
+        if (functionNode.isLazy()) {
+            LOG.info("LAZY: " + functionNode.getName());
+            return null;
+        }
+
+        initFunctionNode(functionNode);
+
+        Node initialEvalResult = LiteralNode.newInstance(functionNode, ScriptRuntime.UNDEFINED);
+
+        nest(functionNode);
+
+        /*
+         * As we are evaluating a nested structure, we need to store the
+         * statement list for the surrounding block and restore it when the
+         * function is done
+         */
+        final List<Node> savedStatements = statements;
+        final Node savedLastStatement = lastStatement;
+
+        statements    = new ArrayList<>();
+        lastStatement = null;
+
+        // for initial eval result is the last declared function
+        for (final FunctionNode nestedFunction : functionNode.getFunctions()) {
+            final IdentNode ident = nestedFunction.getIdent();
+            if (ident != null && nestedFunction.isStatement()) {
+                initialEvalResult = new IdentNode(ident);
+            }
+        }
+
+        if (functionNode.needsSelfSymbol()) {
+            //function needs to start with var funcIdent = __callee_;
+            statements.add(functionNode.getSelfSymbolInit().accept(this));
+        }
+
+        try {
+            // Every nested function needs a definition in the outer function with its name. Add these.
+            for (final FunctionNode nestedFunction : functionNode.getFunctions()) {
+                final VarNode varNode = nestedFunction.getFunctionVarNode();
+                if (varNode != null) {
+                    final LineNumberNode lineNumberNode = nestedFunction.getFunctionVarLineNumberNode();
+                    if (lineNumberNode != null) {
+                        lineNumberNode.accept(this);
+                    }
+                    varNode.accept(this);
+                    varNode.setIsFunctionVarNode();
+                }
+            }
+
+            if (functionNode.isScript()) {
+                new ExecuteNode(functionNode.getSource(), functionNode.getFirstToken(), functionNode.getFinish(), initialEvalResult).accept(this);
+            }
+
+            //do the statements - this fills the block with code
+            for (final Node statement : functionNode.getStatements()) {
+                statement.accept(this);
+                //If there are unused terminated endpoints in the function, we need
+                // to add a "return undefined" in those places for correct semantics
+                LOG.info("Checking lastStatement="+lastStatement+" for terminal flags");
+                if (lastStatement != null && lastStatement.hasTerminalFlags()) {
+                    copyTerminal(functionNode, lastStatement);
+                    break;
+                }
+            }
+
+            functionNode.setStatements(statements);
+
+            if (!functionNode.isTerminal()) {
+                guaranteeReturn(functionNode);
+            }
+
+            //lower all nested functions
+            for (final FunctionNode nestedFunction : functionNode.getFunctions()) {
+                nestedFunction.accept(this);
+            }
+
+        } finally {
+            statements    = savedStatements;
+            lastStatement = savedLastStatement;
+        }
+
+        LOG.info("END FunctionNode: " + functionNode.getName());
+        unnest(functionNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final IfNode ifNode) {
+        return nest(ifNode);
+    }
+
+    @Override
+    public Node leave(final IfNode ifNode) {
+        final Node pass = ifNode.getPass();
+        final Node fail = ifNode.getFail();
+
+        if (pass.isTerminal() && fail != null && fail.isTerminal()) {
+            setTerminal(ifNode,  true);
+        }
+
+        addStatement(ifNode);
+        unnest(ifNode);
+
+        return ifNode;
+    }
+
+    @Override
+    public Node enter(LabelNode labelNode) {
+        final Block body = labelNode.getBody();
+        body.accept(this);
+        copyTerminal(labelNode, body);
+        addStatement(labelNode);
+        return null;
+    }
+
+    @Override
+    public Node enter(final LineNumberNode lineNumberNode) {
+        addStatement(lineNumberNode, false); // don't put it in lastStatement cache
+        return null;
+    }
+
+    @Override
+    public Node enter(final ReturnNode returnNode) {
+        final TryNode tryNode = returnNode.getTryChain();
+        final Node    expr    = returnNode.getExpression();
+
+        if (tryNode != null) {
+            //we are inside a try block - we don't necessarily have a result node yet. attr will do that.
+            if (expr != null) {
+                final Source source = getCurrentFunctionNode().getSource();
+
+                //we need to evaluate the result of the return in case it is complex while
+                //still in the try block, store it in a result value and return it afterwards
+                final long token        = returnNode.getToken();
+                final Node resultNode   = new IdentNode(getCurrentFunctionNode().getResultNode());
+                final Node assignResult = new BinaryNode(source, Token.recast(token, TokenType.ASSIGN), resultNode, expr);
+
+                //add return_in_try = expr; to try block
+                new ExecuteNode(source, token, Token.descPosition(token), assignResult).accept(this);
+
+                //splice in the finally code, inlining it here
+                if (copyFinally(tryNode, null)) {
+                    return null;
+                }
+
+                //make sure that the return node now returns 'return_in_try'
+                returnNode.setExpression(resultNode);
+            } else if (copyFinally(tryNode, null)) {
+                return null;
+            }
+        } else if (expr != null) {
+            returnNode.setExpression(expr.accept(this));
+        }
+
+        addStatement(returnNode);
+
+        return null;
+    }
+
+    @Override
+    public Node leave(final ReturnNode returnNode) {
+        addStatement(returnNode); //ReturnNodes are always terminal, marked as such in constructor
+        return returnNode;
+    }
+
+    @Override
+    public Node enter(final SwitchNode switchNode) {
+        nest(switchNode);
+        return switchNode;
+    }
+
+    @Override
+    public Node leave(final SwitchNode switchNode) {
+        unnest(switchNode);
+
+        final List<CaseNode> cases       = switchNode.getCases();
+        final CaseNode       defaultCase = switchNode.getDefaultCase();
+
+        boolean allTerminal = !cases.isEmpty();
+        for (final CaseNode caseNode : switchNode.getCases()) {
+            allTerminal &= caseNode.isTerminal();
+        }
+
+        if (allTerminal && defaultCase != null && defaultCase.isTerminal()) {
+            setTerminal(switchNode, true);
+        }
+
+        addStatement(switchNode);
+
+        return switchNode;
+    }
+
+    @Override
+    public Node leave(final ThrowNode throwNode) {
+        addStatement(throwNode); //ThrowNodes are always terminal, marked as such in constructor
+        return throwNode;
+    }
+
+    @Override
+    public Node enter(final TryNode tryNode) {
+        final Block  finallyBody = tryNode.getFinallyBody();
+        final long   token       = tryNode.getToken();
+        final int    finish      = tryNode.getFinish();
+
+        nest(tryNode);
+
+        if (finallyBody == null) {
+            //do nothing if no finally exists
+            return tryNode;
+        }
+
+        /*
+         * We have a finally clause.
+         *
+         * Transform to do finally tail duplication as follows:
+         *
+         * <pre>
+         *  try {
+         *    try_body
+         *  } catch e1 {
+         *    catchbody_1
+         *  }
+         *  ...
+         *  } catch en {
+         *    catchbody_n
+         *  } finally {
+         *    finally_body
+         *  }
+         *
+         *  (where e1 ... en are optional)
+         *
+         *  turns into
+         *
+         *  try {
+         *    try {
+         *      try_body
+         *    } catch e1 {
+         *      catchbody1
+         *      //nothing inlined explicitly here, return, break other
+         *      //terminals may inline the finally body
+         *      ...
+         *    } catch en {
+         *      catchbody2
+         *      //nothing inlined explicitly here, return, break other
+         *      //terminals may inline the finally body
+         *    }
+         *  } catch all ex {
+         *      finally_body_inlined
+         *      rethrow ex
+         *  }
+         *  finally_body_inlined
+         * </pre>
+         *
+         * If tries are catches are terminal, visitors for return, break &
+         * continue will handle the tail duplications. Throw needs to be
+         * treated specially with the catchall as described in the above
+         * ASCII art.
+         *
+         * If the try isn't terminal we do the finally_body_inlined at the
+         * end. If the try is terminated with continue/break/return the
+         * existing visitor logic will inline the finally before that
+         * operation. if the try is terminated with a throw, the catches e1
+         * ... en will have a chance to process the exception. If the
+         * appropriate catch e1..en is non terminal we fall through to the
+         * last finally_body_inlined. if the catch e1...en IS terminal with
+         * continue/break/return existing visitor logic will fix it. If they
+         * are terminal with another throw it goes to the catchall and the
+         * finally_body_inlined marked (*) will fix it before rethrowing
+         * whatever problem there was for identical semantic.
+         */
+        final Source source = getCurrentFunctionNode().getSource();
+
+        // if try node does not contain a catch we can skip creation of a new
+        // try node and just append our synthetic catch to the existing try node.
+        if (!tryNode.getCatchBlocks().isEmpty()) {
+            // insert an intermediate try-catch* node, where we move the body and all catch blocks.
+            // the original try node become a try-finally container for the new try-catch* node.
+            // because we don't clone (to avoid deep copy), we have to fix the block chain in the end.
+            final TryNode innerTryNode;
+            innerTryNode = new TryNode(source, token, finish, tryNode.getNext());
+            innerTryNode.setBody(tryNode.getBody());
+            innerTryNode.setCatchBlocks(tryNode.getCatchBlocks());
+
+            // set outer tryNode's body to innerTryNode
+            final Block outerBody;
+            outerBody = new Block(source, token, finish, tryNode.getBody().getParent(), getCurrentFunctionNode());
+            outerBody.setStatements(new ArrayList<Node>(Arrays.asList(innerTryNode)));
+            tryNode.setBody(outerBody);
+            tryNode.setCatchBlocks(null);
+
+            // now before we go on, we have to fix the block parents
+            // (we repair the block tree after the insertion so that all references are intact)
+            innerTryNode.getBody().setParent(tryNode.getBody());
+            for (final Block block : innerTryNode.getCatchBlocks()) {
+                block.setParent(tryNode.getBody());
+            }
+        }
+
+        // create a catch-all that inlines finally and rethrows
+
+        final Block catchBlock      = new Block(source, token, finish, getCurrentBlock(), getCurrentFunctionNode());
+        //this catch block should get define symbol
+
+        final Block catchBody       = new Block(source, token, finish, catchBlock, getCurrentFunctionNode());
+        final Node  catchAllFinally = finallyBody.clone();
+
+        catchBody.addStatement(new ExecuteNode(source, finallyBody.getToken(), finallyBody.getFinish(), catchAllFinally));
+        setTerminal(catchBody, true);
+
+        final CatchNode catchAllNode;
+        final IdentNode exception;
+
+        exception    = new IdentNode(source, token, finish, getCurrentFunctionNode().uniqueName("catch_all"));
+        catchAllNode = new CatchNode(source, token, finish, new IdentNode(exception), null, catchBody);
+        catchAllNode.setIsSyntheticRethrow();
+
+        catchBlock.addStatement(catchAllNode);
+
+        // replace all catches of outer tryNode with the catch-all
+        tryNode.setCatchBlocks(new ArrayList<>(Arrays.asList(catchBlock)));
+
+        /*
+         * We leave the finally block for the original try in place for now
+         * so that children visitations will work. It is removed and placed
+         * afterwards in the else case below, after all children are visited
+         */
+
+        return tryNode;
+    }
+
+    @Override
+    public Node leave(final TryNode tryNode) {
+        final Block finallyBody   = tryNode.getFinallyBody();
+
+        boolean allTerminal = tryNode.getBody().isTerminal() && (finallyBody == null || finallyBody.isTerminal());
+
+        for (final Block catchBlock : tryNode.getCatchBlocks()) {
+            allTerminal &= catchBlock.isTerminal();
+        }
+
+        tryNode.setIsTerminal(allTerminal);
+
+        addStatement(tryNode);
+        unnest(tryNode);
+
+        // if finally body is present, place it after the tryNode
+        if (finallyBody != null) {
+            tryNode.setFinallyBody(null);
+            addStatement(finallyBody);
+        }
+
+        return tryNode;
+    }
+
+    @Override
+    public Node leave(final VarNode varNode) {
+        addStatement(varNode);
+        return varNode;
+    }
+
+    @Override
+    public Node enter(final WhileNode whileNode) {
+        return nest(whileNode);
+    }
+
+    @Override
+    public Node leave(final WhileNode whileNode) {
+        final Node test = whileNode.getTest();
+
+        if (test == null) {
+            setHasGoto(whileNode);
+        }
+
+        final Block   body    = whileNode.getBody();
+        final boolean escapes = controlFlowEscapes(body);
+        if (escapes) {
+            setTerminal(body, false);
+        }
+
+        Node node = whileNode;
+
+        if (body.isTerminal()) {
+            if (whileNode instanceof DoWhileNode) {
+                setTerminal(whileNode, true);
+            } else if (conservativeAlwaysTrue(test)) {
+                node = new ForNode(whileNode.getSource(), whileNode.getToken(), whileNode.getFinish());
+                ((ForNode)node).setBody(body);
+                ((ForNode)node).accept(this);
+                setTerminal(node, !escapes);
+            }
+        }
+
+        // pop the loop from the loop context
+        unnest(whileNode);
+        addStatement(node);
+
+        return node;
+    }
+
+    @Override
+    public Node leave(final WithNode withNode) {
+        if (withNode.getBody().isTerminal()) {
+            setTerminal(withNode,  true);
+        }
+        addStatement(withNode);
+
+        return withNode;
+    }
+
+    @Override
+    public Node leaveDELETE(final UnaryNode unaryNode) {
+        final Node rhs = unaryNode.rhs();
+        if (rhs instanceof IdentNode || rhs instanceof BaseNode) {
+            return unaryNode;
+        }
+        addStatement(new ExecuteNode(rhs));
+        return LiteralNode.newInstance(unaryNode, true);
+    }
+
+    /**
+     * Given a function node that is a callee in a CallNode, replace it with
+     * the appropriate marker function. This is used by {@link CodeGenerator}
+     * for fast scope calls
+     *
+     * @param function function called by a CallNode
+     * @return transformed node to marker function or identity if not ident/access/indexnode
+     */
+    private static Node markerFunction(final Node function) {
+        if (function instanceof IdentNode) {
+            return new IdentNode((IdentNode)function) {
+                @Override
+                public boolean isFunction() {
+                    return true;
+                }
+            };
+        } else if (function instanceof AccessNode) {
+            return new AccessNode((AccessNode)function) {
+                @Override
+                public boolean isFunction() {
+                    return true;
+                }
+            };
+        } else if (function instanceof IndexNode) {
+            return new IndexNode((IndexNode)function) {
+                @Override
+                public boolean isFunction() {
+                    return true;
+                }
+            };
+        }
+
+        return function;
+    }
+
+    /**
+     * Calculate a synthetic eval location for a node for the stacktrace, for example src#17<eval>
+     * @param node a node
+     * @return eval location
+     */
+    private static String evalLocation(final IdentNode node) {
+        return new StringBuilder().
+            append(node.getSource().getName()).
+            append('#').
+            append(node.getSource().getLine(node.position())).
+            append("<eval>").
+            toString();
+    }
+
+    /**
+     * Check whether a call node may be a call to eval. In that case we
+     * clone the args in order to create the following construct in
+     * {@link CodeGenerator}
+     *
+     * <pre>
+     * if (calledFuntion == buildInEval) {
+     *    eval(cloned arg);
+     * } else {
+     *    cloned arg;
+     * }
+     * </pre>
+     *
+     * @param callNode call node to check if it's an eval
+     */
+    private void checkEval(final CallNode callNode) {
+        if (callNode.getFunction() instanceof IdentNode) {
+
+            final List<Node> args   = callNode.getArgs();
+            final IdentNode  callee = (IdentNode)callNode.getFunction();
+
+            // 'eval' call with at least one argument
+            if (args.size() >= 1 && EVAL.tag().equals(callee.getName())) {
+                final CallNode.EvalArgs evalArgs =
+                    new CallNode.EvalArgs(
+                        args.get(0).clone().accept(this), //clone as we use this for the "is eval case". original evaluated separately for "is not eval case"
+                        getCurrentFunctionNode().getThisNode(),
+                        evalLocation(callee),
+                        getCurrentFunctionNode().isStrictMode());
+                callNode.setEvalArgs(evalArgs);
+            }
+        }
+    }
+
+    private static boolean conservativeAlwaysTrue(final Node node) {
+        return node == null || ((node instanceof LiteralNode) && Boolean.TRUE.equals(((LiteralNode<?>)node).getValue()));
+    }
+
+    /**
+     * Helper that given a loop body makes sure that it is not terminal if it
+     * has a continue that leads to the loop header or to outer loops' loop
+     * headers. This means that, even if the body ends with a terminal
+     * statement, we cannot tag it as terminal
+     *
+     * @param loopBody the loop body to check
+     * @return true if control flow may escape the loop
+     */
+    private boolean controlFlowEscapes(final Node loopBody) {
+        final List<Node> escapes = new ArrayList<>();
+
+        loopBody.accept(new NodeVisitor() {
+            @Override
+            public Node leave(final BreakNode node) {
+                escapes.add(node);
+                return node;
+            }
+
+            @Override
+            public Node leave(final ContinueNode node) {
+                // all inner loops have been popped.
+                if (nesting.contains(node.getTargetNode())) {
+                    escapes.add(node);
+                }
+                return node;
+            }
+        });
+
+        return !escapes.isEmpty();
+    }
+
+    private void guaranteeReturn(final FunctionNode functionNode) {
+        Node resultNode;
+
+        if (functionNode.isScript()) {
+            resultNode = functionNode.getResultNode(); // the eval result, symbol assigned in Attr
+        } else {
+            if (lastStatement != null && lastStatement.isTerminal() || lastStatement instanceof ReturnNode) {
+                return; //already in place or not needed, as it should be for a non-undefined returning function
+            }
+            resultNode = LiteralNode.newInstance(functionNode, ScriptRuntime.UNDEFINED);
+        }
+
+        //create a return statement
+        final Node returnNode = new ReturnNode(functionNode.getSource(), functionNode.getLastToken(), functionNode.getFinish(), resultNode, null);
+        returnNode.accept(this);
+    }
+
+
+    private Node nest(final Node node) {
+        LOG.info("Nesting: " + node);
+        LOG.indent();
+        nesting.push(node);
+        return node;
+    }
+
+    private void unnest(final Node node) {
+        LOG.unindent();
+        assert nesting.getFirst() == node : "inconsistent nesting order : " + nesting.getFirst() + " != " + node;
+        LOG.info("Unnesting: " + nesting);
+        nesting.pop();
+    }
+
+    private static void setTerminal(final Node node, final boolean isTerminal) {
+        LOG.info("terminal = " + isTerminal + " for " + node);
+        node.setIsTerminal(isTerminal);
+    }
+
+    private static void setHasGoto(final Node node) { //, final boolean hasGoto) {
+        LOG.info("hasGoto = true for " + node);
+        node.setHasGoto();
+    }
+
+    private static void copyTerminal(final Node node, final Node sourceNode) {
+        LOG.info("copy terminal flags " + sourceNode + " -> " + node);
+        node.copyTerminalFlags(sourceNode);
+    }
+
+    private void addStatement(final Node statement, final boolean storeInLastStatement) {
+        LOG.info("add statement = " + statement + " (lastStatement = " + lastStatement + ")");
+        statements.add(statement);
+        if (storeInLastStatement) {
+            lastStatement = statement;
+        }
+    }
+
+    private void addStatement(final Node statement) {
+        addStatement(statement, true);
+    }
+
+    /**
+     * Determine if Try block is inside target block.
+     *
+     * @param tryNode Try node to test.
+     * @param target  Target block.
+     *
+     * @return true if try block is inside the target, false otherwise.
+     */
+    private boolean isNestedTry(final TryNode tryNode, final Block target) {
+        for (Block current = getCurrentBlock(); current != target; current = current.getParent()) {
+            if (tryNode.getBody() == current) {
+                return true;
+            }
+
+            for (final Block catchBlock : tryNode.getCatchBlocks()) {
+                if (catchBlock == current) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Clones the body of the try finallys up to the target block.
+     *
+     * @param node       first try node in the chain.
+     * @param targetNode target block of the break/continue statement or null for return
+     *
+     * @return true if terminates.
+     */
+    private boolean copyFinally(final TryNode node, final Node targetNode) {
+        Block target = null;
+
+        if (targetNode instanceof Block) {
+            target = (Block)targetNode;
+        }
+
+        for (TryNode tryNode = node; tryNode != null; tryNode = tryNode.getNext()) {
+            if (target != null && !isNestedTry(tryNode, target)) {
+                return false;
+            }
+
+            Block finallyBody = tryNode.getFinallyBody();
+            if (finallyBody == null) {
+                continue;
+            }
+
+            finallyBody = (Block)finallyBody.clone();
+            final boolean hasTerminalFlags = finallyBody.hasTerminalFlags();
+
+            new ExecuteNode(finallyBody.getSource(), finallyBody.getToken(), finallyBody.getFinish(), finallyBody).accept(this);
+
+            if (hasTerminalFlags) {
+                getCurrentBlock().copyTerminalFlags(finallyBody);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private Node enterBreakOrContinue(final LabeledNode labeledNode) {
+        final TryNode tryNode = labeledNode.getTryChain();
+        if (tryNode != null && copyFinally(tryNode, labeledNode.getTargetNode())) {
+            return null;
+        }
+        addStatement(labeledNode);
+        return null;
+    }
+
+
+    /**
+     * An internal expression has a symbol that is tagged internal. Check if
+     * this is such a node
+     *
+     * @param expression expression to check for internal symbol
+     * @return true if internal, false otherwise
+     */
+    private static boolean isInternalExpression(final Node expression) {
+        final Symbol symbol = expression.getSymbol();
+        return symbol != null && symbol.isInternal();
+    }
+
+    /**
+     * Is this an assignment to the special variable that hosts scripting eval
+     * results?
+     *
+     * @param expression expression to check whether it is $evalresult = X
+     * @return true if an assignment to eval result, false otherwise
+     */
+    private boolean isEvalResultAssignment(final Node expression) {
+        Node e = expression;
+        if (e.tokenType() == TokenType.DISCARD) {
+            e = ((UnaryNode)expression).rhs();
+        }
+        final Node resultNode = getCurrentFunctionNode().getResultNode();
+        return e instanceof BinaryNode && ((BinaryNode)e).lhs().equals(resultNode);
+    }
+
+    /**
+     * Prepare special function nodes.
+     * TODO : only create those that are needed.
+     * TODO : make sure slot numbering is not hardcoded in {@link CompilerConstants} - now creation order is significant
+     */
+    private static void initFunctionNode(final FunctionNode functionNode) {
+        final Source source = functionNode.getSource();
+        final long token    = functionNode.getToken();
+        final int  finish   = functionNode.getFinish();
+
+        functionNode.setThisNode(new IdentNode(source, token, finish, THIS.tag()));
+        functionNode.setScopeNode(new IdentNode(source, token, finish, SCOPE.tag()));
+        functionNode.setResultNode(new IdentNode(source, token, finish, SCRIPT_RETURN.tag()));
+        functionNode.setCalleeNode(new IdentNode(source, token, finish, CALLEE.tag()));
+        if (functionNode.isVarArg()) {
+            functionNode.setVarArgsNode(new IdentNode(source, token, finish, VARARGS.tag()));
+            if (functionNode.needsArguments()) {
+                functionNode.setArgumentsNode(new IdentNode(source, token, finish, ARGUMENTS.tag()));
+            }
+        }
+    }
+
+}
+
+
+
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
new file mode 100644
index 0000000..00f3f80
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
@@ -0,0 +1,122 @@
+/*
+ * 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.codegen;
+
+import java.util.ArrayList;
+import java.util.List;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.AccessorProperty;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+
+/**
+ * Class that creates PropertyMap sent to script object constructors.
+ */
+public class MapCreator {
+    /** Object structure for objects associated with this map */
+    private final Class<?> structure;
+
+    /** key set for object map */
+    private final String[] keys;
+
+    /** corresponding symbol set for object map */
+    private final Symbol[] symbols;
+
+    /**
+     * Constructor
+     *
+     * @param structure structure to generate map for (a JO subclass)
+     * @param keys      list of keys for map
+     * @param symbols   list of symbols for map
+     */
+    MapCreator(final Class<?> structure, final List<String> keys, final List<Symbol> symbols) {
+        final int size   = keys.size();
+
+        this.structure = structure;
+        this.keys      = keys.toArray(new String[size]);
+        this.symbols   = symbols.toArray(new Symbol[size]);
+    }
+
+    /**
+     * Constructs a property map based on a set of fields.
+     *
+     * @param hasArguments does the created object have an "arguments" property
+     *
+     * @return New map populated with accessor properties.
+     */
+    PropertyMap makeMap(final boolean hasArguments) {
+        final List<Property> properties = new ArrayList<>();
+
+        assert keys != null;
+
+        for (int i = 0; i < keys.length; i++) {
+            final String key    = keys[i];
+            final Symbol symbol = symbols[i];
+
+            if (symbol != null && !ArrayIndex.isIndexKey(key)) {
+                properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), structure, symbol.getFieldIndex()));
+            }
+        }
+
+        return PropertyMap.newMap(structure, properties);
+    }
+
+    /**
+     * Compute property flags given local state of a field. May be overridden and extended,
+     *
+     * @param symbol       symbol to check
+     * @param hasArguments does the created object have an "arguments" property
+     *
+     * @return flags to use for fields
+     */
+    protected int getPropertyFlags(final Symbol symbol, final boolean hasArguments) {
+        int flags = 0;
+
+        if (symbol.isParam()) {
+            flags |= Property.IS_ALWAYS_OBJECT | Property.IS_PARAMETER;
+        }
+
+        if (hasArguments) {
+            flags |= Property.IS_ALWAYS_OBJECT | Property.HAS_ARGUMENTS;
+        }
+
+        if (symbol.isScope()) {
+            flags |= Property.NOT_CONFIGURABLE;
+        }
+
+        if (symbol.canBePrimitive()) {
+            flags |= Property.CAN_BE_PRIMITIVE;
+        }
+
+        if (symbol.canBeUndefined()) {
+            flags |= Property.CAN_BE_UNDEFINED;
+        }
+
+        return flags;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
new file mode 100644
index 0000000..4cd0f52
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
@@ -0,0 +1,2275 @@
+/*
+ * 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.codegen;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ATHROW;
+import static jdk.internal.org.objectweb.asm.Opcodes.CHECKCAST;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP2;
+import static jdk.internal.org.objectweb.asm.Opcodes.GETFIELD;
+import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.GOTO;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFEQ;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFGE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFGT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFLE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFLT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFNE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFNONNULL;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFNULL;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPEQ;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPNE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPEQ;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPNE;
+import static jdk.internal.org.objectweb.asm.Opcodes.INSTANCEOF;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.NEW;
+import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD;
+import static jdk.internal.org.objectweb.asm.Opcodes.PUTSTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
+import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.THIS_DEBUGGER;
+import static jdk.nashorn.internal.codegen.CompilerConstants.className;
+import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticField;
+import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
+
+import java.io.PrintStream;
+import java.lang.reflect.Array;
+import java.util.ArrayDeque;
+import java.util.EnumSet;
+import java.util.Iterator;
+import jdk.internal.dynalink.support.NameCodec;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.codegen.CompilerConstants.FieldAccess;
+import jdk.nashorn.internal.codegen.types.ArrayType;
+import jdk.nashorn.internal.codegen.types.BitwiseType;
+import jdk.nashorn.internal.codegen.types.NumericType;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.ArgumentSetter;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.Scope;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * This is the main function responsible for emitting method code
+ * in a class. It maintains a type stack and keeps track of control
+ * flow to make sure that the registered instructions don't violate
+ * byte code verification.
+ *
+ * Running Nashorn with -ea will assert as soon as a type stack
+ * becomes corrupt, for easier debugging
+ *
+ * Running Nashorn with -Dnashorn.codegen.debug=true will print
+ * all generated bytecode and labels to stderr, for easier debugging,
+ * including bytecode stack contents
+ */
+public class MethodEmitter implements Emitter {
+    /** The ASM MethodVisitor we are plugged into */
+    private final MethodVisitor method;
+
+    /** Current type stack for current evaluation */
+    private ArrayDeque<Type> stack;
+
+    /** Parent classEmitter representing the class of this method */
+    private final ClassEmitter classEmitter;
+
+    /** FunctionNode representing this method, or null if none exists */
+    private FunctionNode functionNode;
+
+    /** SplitNode representing the current split, or null if none exists */
+    private SplitNode splitNode;
+
+    /** The script environment */
+    private final ScriptEnvironment env;
+
+    /** Threshold in chars for when string constants should be split */
+    static final int LARGE_STRING_THRESHOLD = 32 * 1024;
+
+    /** Debug flag, should we dump all generated bytecode along with stacks? */
+    private static final DebugLogger LOG   = new DebugLogger("codegen", "nashorn.codegen.debug");
+    private static final boolean     DEBUG = LOG.isEnabled();
+
+    /** dump stack on a particular line, or -1 if disabled */
+    private static final int DEBUG_TRACE_LINE;
+
+    static {
+        final String tl = Options.getStringProperty("nashorn.codegen.debug.trace", "-1");
+        int line = -1;
+        try {
+            line = Integer.parseInt(tl);
+        } catch (final NumberFormatException e) {
+            //fallthru
+        }
+        DEBUG_TRACE_LINE = line;
+    }
+
+    /** Bootstrap for normal indy:s */
+    private static final Handle LINKERBOOTSTRAP  = new Handle(H_INVOKESTATIC, Bootstrap.BOOTSTRAP.className(), Bootstrap.BOOTSTRAP.name(), Bootstrap.BOOTSTRAP.descriptor());
+
+    /** Bootstrap for runtime node indy:s */
+    private static final Handle RUNTIMEBOOTSTRAP = new Handle(H_INVOKESTATIC, RuntimeCallSite.BOOTSTRAP.className(), RuntimeCallSite.BOOTSTRAP.name(), RuntimeCallSite.BOOTSTRAP.descriptor());
+
+    /**
+     * Constructor - internal use from ClassEmitter only
+     * @see ClassEmitter#method
+     *
+     * @param classEmitter the class emitter weaving the class this method is in
+     * @param method       a method visitor
+     */
+    MethodEmitter(final ClassEmitter classEmitter, final MethodVisitor method) {
+        this(classEmitter, method, null);
+    }
+
+    /**
+     * Constructor - internal use from ClassEmitter only
+     * @see ClassEmitter#method
+     *
+     * @param classEmitter the class emitter weaving the class this method is in
+     * @param method       a method visitor
+     * @param functionNode a function node representing this method
+     */
+    MethodEmitter(final ClassEmitter classEmitter, final MethodVisitor method, final FunctionNode functionNode) {
+        this.env          = classEmitter.getEnv();
+        this.classEmitter = classEmitter;
+        this.method       = method;
+        this.functionNode = functionNode;
+        this.stack        = null;
+    }
+
+    /**
+     * Begin a method
+     * @see Emitter
+     */
+    @Override
+    public void begin() {
+        classEmitter.beginMethod(this);
+        stack = new ArrayDeque<>();
+        method.visitCode();
+    }
+
+    /**
+     * End a method
+     * @see Emitter
+     */
+    @Override
+    public void end() {
+        method.visitMaxs(0, 0);
+        method.visitEnd();
+
+        classEmitter.endMethod(this);
+    }
+
+    @Override
+    public String toString() {
+        return "methodEmitter: " + (functionNode == null ? method : functionNode.getName()).toString() + ' ' + stack;
+    }
+
+    /**
+     * Push a type to the existing stack
+     * @param type the type
+     */
+    private void pushType(final Type type) {
+        if (type != null) {
+            stack.push(type);
+        }
+    }
+
+    /**
+     * Pop a type from the existing stack
+     *
+     * @param expected expected type - will assert if wrong
+     *
+     * @return the type that was retrieved
+     */
+    private Type popType(final Type expected) {
+        final Type type = stack.pop();
+        assert type.isObject() && expected.isObject() ||
+            type.isEquivalentTo(expected) : type + " is not compatible with " + expected;
+        return type;
+    }
+
+    /**
+     * Pop a type from the existing stack, no matter what it is.
+     *
+     * @return the type
+     */
+    private Type popType() {
+        return stack.pop();
+    }
+
+    /**
+     * Pop a type from the existing stack, ensuring that it is numeric,
+     * assert if not
+     *
+     * @return the type
+     */
+    private NumericType popNumeric() {
+        final Type type = stack.pop();
+        assert type.isNumeric() : type + " is not numeric";
+        return (NumericType)type;
+    }
+
+    /**
+     * Pop a type from the existing stack, ensuring that it is an integer type
+     * (integer or long), assert if not
+     *
+     * @return the type
+     */
+    private BitwiseType popInteger() {
+        final Type type = stack.pop();
+        assert type.isInteger() || type.isLong() : type + " is not an integer or long";
+        return (BitwiseType)type;
+    }
+
+    /**
+     * Pop a type from the existing stack, ensuring that it is an array type,
+     * assert if not
+     *
+     * @return the type
+     */
+    private ArrayType popArray() {
+        final Type type = stack.pop();
+        assert type.isArray() : type;
+        return (ArrayType)type;
+    }
+
+    /**
+     * Peek a given number of slots from the top of the stack and return the
+     * type in that slot
+     *
+     * @param pos the number of positions from the top, 0 is the top element
+     *
+     * @return the type at position "pos" on the stack
+     */
+    final Type peekType(final int pos) {
+        final Iterator<Type> iter = stack.iterator();
+        for (int i = 0; i < pos; i++) {
+            iter.next();
+        }
+        return iter.next();
+    }
+
+    /**
+     * Peek at the type at the top of the stack
+     *
+     * @return the type at the top of the stack
+     */
+    final Type peekType() {
+        return stack.peek();
+    }
+
+    /**
+     * Generate code a for instantiating a new object and push the
+     * object type on the stack
+     *
+     * @param classDescriptor class descriptor for the object type
+     *
+     * @return the method emitter
+     */
+    MethodEmitter _new(final String classDescriptor) {
+        debug("new", classDescriptor);
+        method.visitTypeInsn(NEW, classDescriptor);
+        pushType(Type.OBJECT);
+        return this;
+    }
+
+    /**
+     * Generate code a for instantiating a new object and push the
+     * object type on the stack
+     *
+     * @param clazz class type to instatiate
+     *
+     * @return the method emitter
+     */
+    MethodEmitter _new(final Class<?> clazz) {
+        return _new(className(clazz));
+    }
+
+    /**
+     * Generate code to call the empty constructor for a class
+     *
+     * @param clazz class type to instatiate
+     *
+     * @return the method emitter
+     */
+    MethodEmitter newInstance(final Class<?> clazz) {
+        return invoke(constructorNoLookup(clazz));
+    }
+
+    /**
+     * Perform a dup, that is, duplicate the top element and
+     * push the duplicate down a given number of positions
+     * on the stack. This is totally type agnostic.
+     *
+     * @param depth the depth on which to put the copy
+     *
+     * @return the method emitter, or null if depth is illegal and
+     *  has no instruction equivalent.
+     */
+    MethodEmitter dup(final int depth) {
+        if (peekType().dup(method, depth) == null) {
+            return null;
+        }
+
+        debug("dup", depth);
+
+        switch (depth) {
+        case 0:
+            pushType(peekType());
+            break;
+        case 1: {
+            final Type p0 = popType();
+            final Type p1 = popType();
+            pushType(p0);
+            pushType(p1);
+            pushType(p0);
+            break;
+        }
+        case 2: {
+            final Type p0 = popType();
+            final Type p1 = popType();
+            final Type p2 = popType();
+            pushType(p0);
+            pushType(p2);
+            pushType(p1);
+            pushType(p0);
+            break;
+        }
+        default:
+            assert false : "illegal dup depth = " + depth;
+            return null;
+        }
+
+        return this;
+    }
+
+    /**
+     * Perform a dup2, that is, duplicate the top element if it
+     * is a category 2 type, or two top elements if they are category
+     * 1 types, and push them on top of the stack
+     *
+     * @return the method emitter
+     */
+    MethodEmitter dup2() {
+        debug("dup2");
+
+        if (peekType().isCategory2()) {
+            pushType(peekType());
+        } else {
+            final Type type = get2();
+            pushType(type);
+            pushType(type);
+            pushType(type);
+            pushType(type);
+        }
+        method.visitInsn(DUP2);
+        return this;
+    }
+
+    /**
+     * Duplicate the top element on the stack and push it
+     *
+     * @return the method emitter
+     */
+    MethodEmitter dup() {
+        return dup(0);
+    }
+
+    /**
+     * Pop the top element of the stack and throw it away
+     *
+     * @return the method emitter
+     */
+    MethodEmitter pop() {
+        debug("pop", peekType());
+        popType().pop(method);
+        return this;
+    }
+
+    /**
+     * Pop the top element of the stack if category 2 type, or the two
+     * top elements of the stack if category 1 types
+     *
+     * @return the method emitter
+     */
+    MethodEmitter pop2() {
+        if (peekType().isCategory2()) {
+            popType();
+        } else {
+            get2n();
+        }
+        return this;
+    }
+
+    /**
+     * Swap the top two elements of the stack. This is totally
+     * type agnostic and works for all types
+     *
+     * @return the method emitter
+     */
+    MethodEmitter swap() {
+        debug("swap");
+
+        final Type p0 = popType();
+        final Type p1 = popType();
+        p0.swap(method, p1);
+
+        pushType(p0);
+        pushType(p1);
+        debug("after ", p0, p1);
+        return this;
+    }
+
+    /**
+     * Add a local variable. This is a nop if the symbol has no slot
+     *
+     * @param symbol symbol for the local variable
+     * @param start  start of scope
+     * @param end    end of scope
+     */
+    void localVariable(final Symbol symbol, final Label start, final Label end) {
+        if (!symbol.hasSlot()) {
+            return;
+        }
+
+        String name = symbol.getName();
+
+        if (name.equals(THIS.tag())) {
+            name = THIS_DEBUGGER.tag();
+        }
+
+        method.visitLocalVariable(name, symbol.getSymbolType().getDescriptor(), null, start, end, symbol.getSlot());
+    }
+
+    /**
+     * Create a new string builder, call the constructor and push the instance to the stack.
+     *
+     * @return the method emitter
+     */
+    MethodEmitter newStringBuilder() {
+        return invoke(constructorNoLookup(StringBuilder.class)).dup();
+    }
+
+    /**
+     * Pop a string and a StringBuilder from the top of the stack and call the append
+     * function of the StringBuilder, appending the string. Pushes the StringBuilder to
+     * the stack when finished.
+     *
+     * @return the method emitter
+     */
+    MethodEmitter stringBuilderAppend() {
+        convert(Type.STRING);
+        return invoke(virtualCallNoLookup(StringBuilder.class, "append", StringBuilder.class, String.class));
+    }
+
+    /**
+     * Associate a variable with a given range
+     *
+     * @param name  name of the variable
+     * @param start start
+     * @param end   end
+     */
+    void markerVariable(final String name, final Label start, final Label end) {
+        method.visitLocalVariable(name, Type.OBJECT.getDescriptor(), null, start, end, 0);
+    }
+
+    /**
+     * Pops two integer types from the stack, performs a bitwise and and pushes
+     * the result
+     *
+     * @return the method emitter
+     */
+    MethodEmitter and() {
+        debug("and");
+        pushType(get2i().and(method));
+        return this;
+    }
+
+    /**
+     * Pops two integer types from the stack, performs a bitwise or and pushes
+     * the result
+     *
+     * @return the method emitter
+     */
+    MethodEmitter or() {
+        debug("or");
+        pushType(get2i().or(method));
+        return this;
+    }
+
+    /**
+     * Pops two integer types from the stack, performs a bitwise xor and pushes
+     * the result
+     *
+     * @return the method emitter
+     */
+    MethodEmitter xor() {
+        debug("xor");
+        pushType(get2i().xor(method));
+        return this;
+    }
+
+    /**
+     * Pops two integer types from the stack, performs a bitwise logic shift right and pushes
+     * the result. The shift count, the first element, must be INT.
+     *
+     * @return the method emitter
+     */
+    MethodEmitter shr() {
+        debug("shr");
+        popType(Type.INT);
+        pushType(popInteger().shr(method));
+        return this;
+    }
+
+    /**
+     * Pops two integer types from the stack, performs a bitwise shift left and and pushes
+     * the result. The shift count, the first element, must be INT.
+     *
+     * @return the method emitter
+     */
+    MethodEmitter shl() {
+        debug("shl");
+        popType(Type.INT);
+        pushType(popInteger().shl(method));
+        return this;
+    }
+
+    /**
+     * Pops two integer types from the stack, performs a bitwise arithetic shift right and pushes
+     * the result. The shift count, the first element, must be INT.
+     *
+     * @return the method emitter
+     */
+    MethodEmitter sar() {
+        debug("sar");
+        popType(Type.INT);
+        pushType(popInteger().sar(method));
+        return this;
+    }
+
+    /**
+     * Pops a numeric type from the stack, negates it and pushes the result
+     *
+     * @return the method emitter
+     */
+    MethodEmitter neg() {
+        debug("neg");
+        pushType(popNumeric().neg(method));
+        return this;
+    }
+
+    /**
+     * Add label for the start of a catch block and push the exception to the
+     * stack
+     *
+     * @param recovery label pointing to start of catch block
+     */
+    void _catch(final Label recovery) {
+        stack.clear();
+        stack.push(Type.OBJECT);
+        label(recovery);
+    }
+
+    /**
+     * Start a try/catch block.
+     *
+     * @param entry          start label for try
+     * @param exit           end label for try
+     * @param recovery       start label for catch
+     * @param typeDescriptor type descriptor for exception
+     */
+    void _try(final Label entry, final Label exit, final Label recovery, final String typeDescriptor) {
+        method.visitTryCatchBlock(entry, exit, recovery, typeDescriptor);
+    }
+
+    /**
+     * Start a try/catch block.
+     *
+     * @param entry    start label for try
+     * @param exit     end label for try
+     * @param recovery start label for catch
+     * @param clazz    exception class
+     */
+    void _try(final Label entry, final Label exit, final Label recovery, final Class<?> clazz) {
+        method.visitTryCatchBlock(entry, exit, recovery, CompilerConstants.className(clazz));
+    }
+
+    /**
+     * Start a try/catch block. The catch is "Throwable" - i.e. catch-all
+     *
+     * @param entry    start label for try
+     * @param exit     end label for try
+     * @param recovery start label for catch
+     */
+    void _try(final Label entry, final Label exit, final Label recovery) {
+        _try(entry, exit, recovery, (String)null);
+    }
+
+
+    /**
+     * Load the constants array
+     * @param unitClassName name of the compile unit from which to load constants
+     * @return this method emitter
+     */
+    MethodEmitter loadConstants(final String unitClassName) {
+        getStatic(unitClassName, CONSTANTS.tag(), CONSTANTS.descriptor());
+        assert peekType().isArray() : peekType();
+        return this;
+    }
+
+    /**
+     * Push the undefined value for the given type, i.e.
+     * UNDEFINED or UNDEFINEDNUMBER. Currently we have no way of
+     * representing UNDEFINED for INTs and LONGs, so they are not
+     * allowed to be local variables (yet)
+     *
+     * @param type the type for which to push UNDEFINED
+     * @return the method emitter
+     */
+    MethodEmitter loadUndefined(final Type type) {
+        debug("load undefined " + type);
+        pushType(type.loadUndefined(method));
+        return this;
+    }
+
+    /**
+     * Push the empty value for the given type, i.e. EMPTY.
+     *
+     * @param type the type
+     * @return the method emitter
+     */
+    MethodEmitter loadEmpty(final Type type) {
+        debug("load empty " + type);
+        pushType(type.loadEmpty(method));
+        return this;
+    }
+
+    /**
+     * Push null to stack
+     *
+     * @return the method emitter
+     */
+    MethodEmitter loadNull() {
+        debug("aconst_null");
+        pushType(Type.OBJECT.ldc(method, null));
+        return this;
+    }
+
+    /**
+     * Push a handle representing this class top stack
+     *
+     * @param className name of the class
+     *
+     * @return the method emitter
+     */
+    MethodEmitter loadType(final String className) {
+        debug("load type", className);
+        method.visitLdcInsn(jdk.internal.org.objectweb.asm.Type.getObjectType(className));
+        pushType(Type.OBJECT);
+        return this;
+    }
+
+    /**
+     * Push a boolean constant to the stack.
+     *
+     * @param b value of boolean
+     *
+     * @return the method emitter
+     */
+    MethodEmitter load(final boolean b) {
+        debug("load boolean", b);
+        pushType(Type.BOOLEAN.ldc(method, b));
+        return this;
+    }
+
+    /**
+     * Push an int constant to the stack
+     *
+     * @param i value of the int
+     *
+     * @return the method emitter
+     */
+    MethodEmitter load(final int i) {
+        debug("load int", i);
+        pushType(Type.INT.ldc(method, i));
+        return this;
+    }
+
+    /**
+     * Push a double constant to the stack
+     *
+     * @param d value of the double
+     *
+     * @return the method emitter
+     */
+    MethodEmitter load(final double d) {
+        debug("load double", d);
+        pushType(Type.NUMBER.ldc(method, d));
+        return this;
+    }
+
+    /**
+     * Push an long constant to the stack
+     *
+     * @param l value of the long
+     *
+     * @return the method emitter
+     */
+    MethodEmitter load(final long l) {
+        debug("load long", l);
+        pushType(Type.LONG.ldc(method, l));
+        return this;
+    }
+
+    /**
+     * Fetch the length of an array.
+     * @return Array length.
+     */
+    MethodEmitter arraylength() {
+        debug("arraylength");
+        popType(Type.OBJECT);
+        pushType(Type.OBJECT_ARRAY.arraylength(method));
+        return this;
+    }
+
+    /**
+     * Push a String constant to the stack
+     *
+     * @param s value of the String
+     *
+     * @return the method emitter
+     */
+    MethodEmitter load(final String s) {
+        debug("load string", s);
+
+        if (s == null) {
+            loadNull();
+            return this;
+        }
+
+        //NASHORN-142 - split too large string
+        final int length = s.length();
+        if (length > LARGE_STRING_THRESHOLD) {
+
+            _new(StringBuilder.class);
+            dup();
+            load(length);
+            invoke(constructorNoLookup(StringBuilder.class, int.class));
+
+            for (int n = 0; n < length; n += LARGE_STRING_THRESHOLD) {
+                final String part = s.substring(n, Math.min(n + LARGE_STRING_THRESHOLD, length));
+                load(part);
+                stringBuilderAppend();
+            }
+
+            invoke(virtualCallNoLookup(StringBuilder.class, "toString", String.class));
+
+            return this;
+        }
+
+        pushType(Type.OBJECT.ldc(method, s));
+        return this;
+    }
+
+    /**
+     * Push an local variable to the stack. If the symbol representing
+     * the local variable doesn't have a slot, this is a NOP
+     *
+     * @param symbol the symbol representing the local variable.
+     *
+     * @return the method emitter
+     */
+    MethodEmitter load(final Symbol symbol) {
+        assert symbol != null;
+        if (symbol.hasSlot()) {
+            final int slot = symbol.getSlot();
+            debug("load symbol", symbol.getName(), " slot=", slot);
+            final Type type = symbol.getSymbolType().load(method, slot);
+            pushType(type == Type.OBJECT && symbol.isThis() ? Type.THIS : type);
+        } else if (symbol.isParam()) {
+            assert !symbol.isScope();
+            assert functionNode.isVarArg() : "Non-vararg functions have slotted parameters";
+            final int index = symbol.getFieldIndex();
+            if (functionNode.needsArguments()) {
+                // ScriptObject.getArgument(int) on arguments
+                debug("load symbol", symbol.getName(), " arguments index=", index);
+                loadArguments();
+                load(index);
+                ScriptObject.GET_ARGUMENT.invoke(this);
+            } else {
+                // array load from __varargs__
+                debug("load symbol", symbol.getName(), " array index=", index);
+                loadVarArgs();
+                load(symbol.getFieldIndex());
+                arrayload();
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Push a local variable to the stack, given an explicit bytecode slot
+     * This is used e.g. for stub generation where we know where items like
+     * "this" and "scope" reside.
+     *
+     * @param type  the type of the variable
+     * @param slot  the slot the variable is in
+     *
+     * @return the method emitter
+     */
+    MethodEmitter load(final Type type, final int slot) {
+        debug("explicit load", type, slot);
+        final Type loadType = type.load(method, slot);
+        pushType(loadType == Type.OBJECT && isThisSlot(slot) ? Type.THIS : loadType);
+        return this;
+    }
+
+    private boolean isThisSlot(final int slot) {
+        if(functionNode == null) {
+            return slot == CompilerConstants.JAVA_THIS.slot();
+        }
+        final int thisSlot = functionNode.getThisNode().getSymbol().getSlot();
+        assert !functionNode.needsCallee() || thisSlot == 1; // needsCallee -> thisSlot == 1
+        assert functionNode.needsCallee() || thisSlot == 0; // !needsCallee -> thisSlot == 0
+        return slot == thisSlot;
+    }
+
+    /**
+     * Push the this object to the stack.
+     *
+     * @return the method emitter
+     */
+    MethodEmitter loadThis() {
+        load(functionNode.getThisNode().getSymbol());
+        return this;
+    }
+
+    /**
+     * Push the scope object to the stack.
+     *
+     * @return the method emitter
+     */
+    MethodEmitter loadScope() {
+        if (peekType() == Type.SCOPE) {
+            dup();
+            return this;
+        }
+        load(functionNode.getScopeNode().getSymbol());
+        return this;
+    }
+
+    /**
+     * Push the return object to the stack.
+     *
+     * @return the method emitter
+     */
+    MethodEmitter loadResult() {
+        load(functionNode.getResultNode().getSymbol());
+        return this;
+    }
+
+
+    /**
+     * Push a method handle to the stack
+     *
+     * @param className  class name
+     * @param methodName method name
+     * @param descName   descriptor
+     * @param flags      flags that describe this handle, e.g. invokespecial new, or invoke virtual
+     *
+     * @return the method emitter
+     */
+    MethodEmitter loadHandle(final String className, final String methodName, final String descName, final EnumSet<Flag> flags) {
+        debug("load handle ");
+        pushType(Type.OBJECT.ldc(method, new Handle(Flag.getValue(flags), className, methodName, descName)));
+        return this;
+    }
+
+    /**
+     * Push the varargs object to the stack
+     *
+     * @return the method emitter
+     */
+    MethodEmitter loadVarArgs() {
+        debug("load var args " + functionNode.getVarArgsNode().getSymbol());
+        return load(functionNode.getVarArgsNode().getSymbol());
+    }
+
+    /**
+     * Push the arguments array to the stack
+     *
+     * @return the method emitter
+     */
+    MethodEmitter loadArguments() {
+        debug("load arguments ", functionNode.getArgumentsNode().getSymbol());
+        assert functionNode.getArgumentsNode().getSymbol().getSlot() != 0;
+        return load(functionNode.getArgumentsNode().getSymbol());
+    }
+
+    /**
+     * Push the callee object to the stack
+     *
+     * @return the method emitter
+     */
+    MethodEmitter loadCallee() {
+        final Symbol calleeSymbol = functionNode.getCalleeNode().getSymbol();
+        debug("load callee ", calleeSymbol);
+        assert calleeSymbol.getSlot() == 0 : "callee has wrong slot " + calleeSymbol.getSlot() + " in " + functionNode.getName();
+
+        return load(calleeSymbol);
+    }
+
+    /**
+     * Pop the scope from the stack and store it in its predefined slot
+     */
+    void storeScope() {
+        debug("store scope");
+        store(functionNode.getScopeNode().getSymbol());
+    }
+
+    /**
+     * Pop the return from the stack and store it in its predefined slot
+     */
+    void storeResult() {
+        debug("store result");
+        store(functionNode.getResultNode().getSymbol());
+    }
+
+    /**
+     * Pop the arguments array from the stack and store it in its predefined slot
+     */
+    void storeArguments() {
+        debug("store arguments");
+        store(functionNode.getArgumentsNode().getSymbol());
+    }
+
+    /**
+     * Load an element from an array, determining type automatically
+     * @return the method emitter
+     */
+    MethodEmitter arrayload() {
+        debug("Xaload");
+        popType(Type.INT);
+        pushType(popArray().aload(method));
+        return this;
+    }
+
+    /**
+     * Pop a value, an index and an array from the stack and store
+     * the value at the given index in the array.
+     */
+    void arraystore() {
+        debug("Xastore");
+        final Type value = popType();
+        final Type index = popType(Type.INT);
+        assert index.isInteger() : "array index is not integer, but " + index;
+        final ArrayType array = popArray();
+
+        assert value.isEquivalentTo(array.getElementType()) : "Storing "+value+" into "+array;
+        assert array.isObject();
+        array.astore(method);
+    }
+
+    /**
+     * Pop a value from the stack and store it in a local variable represented
+     * by the given symbol. If the symbol has no slot, this is a NOP
+     *
+     * @param symbol symbol to store stack to
+     */
+    void store(final Symbol symbol) {
+        assert symbol != null : "No symbol to store";
+        if (symbol.hasSlot()) {
+            final int slot = symbol.getSlot();
+            debug("store symbol", symbol.getName(), " slot=", slot);
+            popType(symbol.getSymbolType()).store(method, slot);
+        } else if (symbol.isParam()) {
+            assert !symbol.isScope();
+            assert functionNode.isVarArg() : "Non-vararg functions have slotted parameters";
+            final int index = symbol.getFieldIndex();
+            if (functionNode.needsArguments()) {
+                debug("store symbol", symbol.getName(), " arguments index=", index);
+                loadArguments();
+                load(index);
+                ArgumentSetter.SET_ARGUMENT.invoke(this);
+            } else {
+                // varargs without arguments object - just do array store to __varargs__
+                debug("store symbol", symbol.getName(), " array index=", index);
+                loadVarArgs();
+                load(index);
+                ArgumentSetter.SET_ARRAY_ELEMENT.invoke(this);
+            }
+        }
+    }
+
+    /**
+     * Pop a value from the stack and store it in a given local variable
+     * slot.
+     *
+     * @param type the type to pop
+     * @param slot the slot
+     */
+    void store(final Type type, final int slot) {
+        popType(type);
+        type.store(method, slot);
+    }
+
+    /**
+     * Increment/Decrement a local integer by the given value.
+     *
+     * @param slot the int slot
+     * @param increment the amount to increment
+     */
+    void iinc(final int slot, final int increment) {
+        debug("iinc");
+        method.visitIincInsn(slot, increment);
+    }
+
+    /**
+     * Pop an exception object from the stack and generate code
+     * for throwing it
+     */
+    public void athrow() {
+        debug("athrow");
+        final Type receiver = popType(Type.OBJECT);
+        assert receiver.isObject();
+        method.visitInsn(ATHROW);
+        stack = null;
+    }
+
+    /**
+     * Pop an object from the stack and perform an instanceof
+     * operation, given a classDescriptor to compare it to.
+     * Push the boolean result 1/0 as an int to the stack
+     *
+     * @param classDescriptor descriptor of the class to type check against
+     *
+     * @return the method emitter
+     */
+    MethodEmitter _instanceof(final String classDescriptor) {
+        debug("instanceof", classDescriptor);
+        popType(Type.OBJECT);
+        method.visitTypeInsn(INSTANCEOF, classDescriptor);
+        pushType(Type.INT);
+        return this;
+    }
+
+    /**
+     * Pop an object from the stack and perform an instanceof
+     * operation, given a classDescriptor to compare it to.
+     * Push the boolean result 1/0 as an int to the stack
+     *
+     * @param clazz the type to check instanceof against
+     *
+     * @return the method emitter
+     */
+    MethodEmitter _instanceof(final Class<?> clazz) {
+        return _instanceof(CompilerConstants.className(clazz));
+    }
+
+    /**
+     * Perform a checkcast operation on the object at the top of the
+     * stack.
+     *
+     * @param classDescriptor descriptor of the class to type check against
+     *
+     * @return the method emitter
+     */
+    MethodEmitter checkcast(final String classDescriptor) {
+        debug("checkcast", classDescriptor);
+        assert peekType().isObject();
+        method.visitTypeInsn(CHECKCAST, classDescriptor);
+        return this;
+    }
+
+    /**
+     * Perform a checkcast operation on the object at the top of the
+     * stack.
+     *
+     * @param clazz class to checkcast against
+     *
+     * @return the method emitter
+     */
+    MethodEmitter checkcast(final Class<?> clazz) {
+        return checkcast(CompilerConstants.className(clazz));
+    }
+
+    /**
+     * Instantiate a new array given a length that is popped
+     * from the stack and the array type
+     *
+     * @param arrayType the type of the array
+     *
+     * @return the method emitter
+     */
+    MethodEmitter newarray(final ArrayType arrayType) {
+        debug("newarray ", "arrayType=" + arrayType);
+        popType(Type.INT); //LENGTH
+        pushType(arrayType.newarray(method));
+        return this;
+    }
+
+    /**
+     * Instantiate a multidimensional array with a given number of dimensions.
+     * On the stack are dim lengths of the sub arrays.
+     *
+     * @param arrayType type of the array
+     * @param dims      number of dimensions
+     *
+     * @return the method emitter
+     */
+    MethodEmitter multinewarray(final ArrayType arrayType, final int dims) {
+        debug("multianewarray ", arrayType, dims);
+        for (int i = 0; i < dims; i++) {
+            popType(Type.INT); //LENGTH
+        }
+        pushType(arrayType.newarray(method, dims));
+        return this;
+    }
+
+    /**
+     * Helper function to pop and type check the appropriate arguments
+     * from the stack given a method signature
+     *
+     * @param signature method signature
+     *
+     * @return return type of method
+     */
+    private Type fixParamStack(final String signature) {
+        final Type[] params = Type.getMethodArguments(signature);
+        for (int i = params.length - 1; i >= 0; i--) {
+            popType(params[i]);
+        }
+        final Type returnType = Type.getMethodReturnType(signature);
+        return returnType;
+    }
+
+    /**
+     * Generate an invocation to a Call structure
+     * @see CompilerConstants
+     *
+     * @param call the call object
+     *
+     * @return the method emitter
+     */
+    MethodEmitter invoke(final Call call) {
+        return call.invoke(this);
+    }
+
+    private MethodEmitter invoke(final int opcode, final String className, final String methodName, final String methodDescriptor, final boolean hasReceiver) {
+        final Type returnType = fixParamStack(methodDescriptor);
+
+        if (hasReceiver) {
+            popType(Type.OBJECT);
+        }
+
+        method.visitMethodInsn(opcode, className, methodName, methodDescriptor);
+
+        if (returnType != null) {
+            pushType(returnType);
+        }
+
+        return this;
+    }
+
+    /**
+     * Pop receiver from stack, perform an invoke special
+     *
+     * @param className        class name
+     * @param methodName       method name
+     * @param methodDescriptor descriptor
+     *
+     * @return the method emitter
+     */
+    MethodEmitter invokespecial(final String className, final String methodName, final String methodDescriptor) {
+        debug("invokespecial", className + "." + methodName + methodDescriptor);
+        return invoke(INVOKESPECIAL, className, methodName, methodDescriptor, true);
+    }
+
+    /**
+     * Pop receiver from stack, perform an invoke virtual, push return value if any
+     *
+     * @param className        class name
+     * @param methodName       method name
+     * @param methodDescriptor descriptor
+     *
+     * @return the method emitter
+     */
+    MethodEmitter invokevirtual(final String className, final String methodName, final String methodDescriptor) {
+        debug("invokevirtual", className + "." + methodName + methodDescriptor + " " + stack);
+        return invoke(INVOKEVIRTUAL, className, methodName, methodDescriptor, true);
+    }
+
+    /**
+     * Perform an invoke static and push the return value if any
+     *
+     * @param className        class name
+     * @param methodName       method name
+     * @param methodDescriptor descriptor
+     *
+     * @return the method emitter
+     */
+    MethodEmitter invokestatic(final String className, final String methodName, final String methodDescriptor) {
+        debug("invokestatic", className + "." + methodName + methodDescriptor);
+        invoke(INVOKESTATIC, className, methodName, methodDescriptor, false);
+        return this;
+    }
+
+    /**
+     * Perform an invoke static and replace the return type if we know better, e.g. Global.allocate
+     * that allocates an array should return an ObjectArray type as a NativeArray counts as that
+     *
+     * @param className        class name
+     * @param methodName       method name
+     * @param methodDescriptor descriptor
+     * @param returnType       return type override
+     *
+     * @return the method emitter
+     */
+    MethodEmitter invokeStatic(final String className, final String methodName, final String methodDescriptor, final Type returnType) {
+        invokestatic(className, methodName, methodDescriptor);
+        popType();
+        pushType(returnType);
+        return this;
+    }
+
+    /**
+     * Pop receiver from stack, perform an invoke interface and push return value if any
+     *
+     * @param className        class name
+     * @param methodName       method name
+     * @param methodDescriptor descriptor
+     *
+     * @return the method emitter
+     */
+    MethodEmitter invokeinterface(final String className, final String methodName, final String methodDescriptor) {
+        debug("invokeinterface", className + "." + methodName + methodDescriptor);
+        return invoke(INVOKEINTERFACE, className, methodName, methodDescriptor, true);
+    }
+
+    /**
+     * Generate a lookup switch, popping the switch value from the stack
+     *
+     * @param defaultLabel default label
+     * @param values       case values for the table
+     * @param table        default label
+     */
+    void lookupswitch(final Label defaultLabel, final int[] values, final Label[] table) {
+        debug("lookupswitch", peekType());
+        popType(Type.INT);
+        method.visitLookupSwitchInsn(defaultLabel, values, table);
+    }
+
+    /**
+     * Generate a table switch
+     * @param lo            low value
+     * @param hi            high value
+     * @param defaultLabel  default label
+     * @param table         label table
+     */
+    void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label[] table) {
+        debug("tableswitch", peekType());
+        popType(Type.INT);
+        method.visitTableSwitchInsn(lo, hi, defaultLabel, table);
+    }
+
+    /**
+     * Abstraction for performing a conditional jump of any type
+     *
+     * @see MethodEmitter.Condition
+     *
+     * @param cond      the condition to test
+     * @param trueLabel the destination label is condition is true
+     */
+    void conditionalJump(final Condition cond, final Label trueLabel) {
+        conditionalJump(cond, cond != Condition.GT && cond != Condition.GE, trueLabel);
+    }
+
+    /**
+     * Abstraction for performing a conditional jump of any type,
+     * including a dcmpg/dcmpl semantic for doubles.
+     *
+     * @param cond      the condition to test
+     * @param isCmpG    is this a dcmpg for numbers, false if it's a dcmpl
+     * @param trueLabel the destination label if condition is true
+     */
+    void conditionalJump(final Condition cond, final boolean isCmpG, final Label trueLabel) {
+        if (peekType().isCategory2()) {
+            debug("[ld]cmp isCmpG=" + isCmpG);
+            pushType(get2n().cmp(method, isCmpG));
+            jump(Condition.toUnary(cond), trueLabel, 1);
+        } else {
+            debug("if" + cond);
+            jump(Condition.toBinary(cond, peekType().isObject()), trueLabel, 2);
+        }
+    }
+
+    /**
+     * Perform a non void return, popping the type from the stack
+     *
+     * @param type the type for the return
+     */
+    void _return(final Type type) {
+        debug("return", type);
+        assert stack.size() == 1 : "Only return value on stack allowed at return point - depth=" + stack.size() + " stack = " + stack;
+        final Type stackType = peekType();
+        if (!Type.areEquivalent(type, stackType)) {
+            convert(type);
+        }
+        popType(type)._return(method);
+        stack = null;
+    }
+
+    /**
+     * Perform a return using the stack top value as the guide for the type
+     */
+    void _return() {
+        _return(peekType());
+    }
+
+    /**
+     * Perform a void return.
+     */
+    void returnVoid() {
+        debug("return [void]");
+        assert stack.isEmpty() : stack;
+        method.visitInsn(RETURN);
+        stack = null;
+    }
+
+    /**
+     * Goto, possibly when splitting is taking place. If
+     * a splitNode exists, we need to handle the case that the
+     * jump target is another method
+     *
+     * @param label destination label
+     */
+    void splitAwareGoto(final Label label) {
+
+        if (splitNode != null) {
+            final int index = splitNode.getExternalTargets().indexOf(label);
+
+            if (index > -1) {
+                loadScope();
+                checkcast(Scope.class);
+                load(index + 1);
+                invoke(Scope.SET_SPLIT_STATE);
+                loadUndefined(Type.OBJECT);
+                _return(functionNode.getReturnType());
+                return;
+            }
+        }
+
+        _goto(label);
+    }
+
+    /**
+     * Perform a comparison of two number types that are popped from the stack
+     *
+     * @param isCmpG is this a dcmpg semantic, false if it's a dcmpl semantic
+     *
+     * @return the method emitter
+     */
+    MethodEmitter cmp(final boolean isCmpG) {
+        pushType(get2n().cmp(method, isCmpG));
+        return this;
+    }
+
+    /**
+     * Helper function for jumps, conditional or not
+     * @param opcode  opcode for jump
+     * @param label   destination
+     * @param n       elements on stack to compare, 0-2
+     */
+    private void jump(final int opcode, final Label label, final int n) {
+        for (int i = 0; i < n; i++) {
+            assert peekType().isInteger() || peekType().isBoolean() || peekType().isObject() : "expecting integer type or object for jump, but found " + peekType();
+            popType();
+        }
+        mergeStackTo(label);
+        method.visitJumpInsn(opcode, label);
+    }
+
+    /**
+     * Generate an if_acmpeq
+     *
+     * @param label label to true case
+     */
+    void if_acmpeq(final Label label) {
+        debug("if_acmpeq", label);
+        jump(IF_ACMPEQ, label, 2);
+    }
+
+    /**
+     * Generate an if_acmpne
+     *
+     * @param label label to true case
+     */
+    void if_acmpne(final Label label) {
+        debug("if_acmpne", label);
+        jump(IF_ACMPNE, label, 2);
+    }
+
+    /**
+     * Generate an ifnull
+     *
+     * @param label label to true case
+     */
+    void ifnull(final Label label) {
+        debug("ifnull", label);
+        jump(IFNULL, label, 1);
+    }
+
+    /**
+     * Generate an ifnonnull
+     *
+     * @param label label to true case
+     */
+    void ifnonnull(final Label label) {
+        debug("ifnonnull", label);
+        jump(IFNONNULL, label, 1);
+    }
+
+    /**
+     * Generate an ifeq
+     *
+     * @param label label to true case
+     */
+    void ifeq(final Label label) {
+        debug("ifeq ", label);
+        jump(IFEQ, label, 1);
+    }
+
+    /**
+     * Generate an if_icmpeq
+     *
+     * @param label label to true case
+     */
+    void if_icmpeq(final Label label) {
+        debug("if_icmpeq", label);
+        jump(IF_ICMPEQ, label, 2);
+    }
+
+    /**
+     * Generate an if_ne
+     *
+     * @param label label to true case
+     */
+    void ifne(final Label label) {
+        debug("ifne", label);
+        jump(IFNE, label, 1);
+    }
+
+    /**
+     * Generate an if_icmpne
+     *
+     * @param label label to true case
+     */
+    void if_icmpne(final Label label) {
+        debug("if_icmpne", label);
+        jump(IF_ICMPNE, label, 2);
+    }
+
+    /**
+     * Generate an iflt
+     *
+     * @param label label to true case
+     */
+    void iflt(final Label label) {
+        debug("iflt", label);
+        jump(IFLT, label, 1);
+    }
+
+    /**
+     * Generate an ifle
+     *
+     * @param label label to true case
+     */
+    void ifle(final Label label) {
+        debug("ifle", label);
+        jump(IFLE, label, 1);
+    }
+
+    /**
+     * Generate an ifgt
+     *
+     * @param label label to true case
+     */
+    void ifgt(final Label label) {
+        debug("ifgt", label);
+        jump(IFGT, label, 1);
+    }
+
+    /**
+     * Generate an ifge
+     *
+     * @param label label to true case
+     */
+    void ifge(final Label label) {
+        debug("ifge", label);
+        jump(IFGE, label, 1);
+    }
+
+    /**
+     * Unconditional jump to a label
+     *
+     * @param label destination label
+     */
+    void _goto(final Label label) {
+        debug("goto", label);
+        jump(GOTO, label, 0);
+        stack = null;
+    }
+
+    /**
+     * Examine two stacks and make sure they are of the same size and their
+     * contents are equivalent to each other
+     * @param s0 first stack
+     * @param s1 second stack
+     *
+     * @return true if stacks are equivalent, false otherwise
+     */
+    private boolean stacksEquivalent(final ArrayDeque<Type> s0, final ArrayDeque<Type> s1) {
+        if (s0.size() != s1.size()) {
+            debug("different stack sizes", s0, s1);
+            return false;
+        }
+
+        final Type[] s0a = s0.toArray(new Type[s0.size()]);
+        final Type[] s1a = s1.toArray(new Type[s1.size()]);
+        for (int i = 0; i < s0.size(); i++) {
+            if (!s0a[i].isEquivalentTo(s1a[i])) {
+                debug("different stack element", s0a[i], s1a[i]);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * A join in control flow - helper function that makes sure all entry stacks
+     * discovered for the join point so far are equivalent
+     * @param label
+     */
+    private void mergeStackTo(final Label label) {
+        final ArrayDeque<Type> labelStack = label.getStack();
+        //debug(labelStack == null ? " >> Control flow - first visit " + label : " >> Control flow - JOIN with " + labelStack + " at " + label);
+        if (labelStack == null) {
+            assert stack != null;
+            label.setStack(stack.clone());
+            return;
+        }
+        assert stacksEquivalent(stack, labelStack) : "stacks " + stack + " is not equivalent with " + labelStack + " at join point";
+    }
+
+    /**
+     * Register a new label, enter it here.
+     *
+     * @param label the label
+     */
+    void label(final Label label) {
+        /*
+         * If stack == null, this means that we came here not through a fallthrough.
+         * E.g. a label after an athrow. Then we create a new stack if one doesn't exist
+         * for this location already.
+         */
+        if (stack == null) {
+            stack = label.getStack();
+            if (stack == null) {
+                stack = new ArrayDeque<>(); //we don't have a stack at this point.
+            }
+        }
+        debug_label(label);
+
+        mergeStackTo(label); //we have to merge our stack to whatever is in the label
+
+        method.visitLabel(label);
+    }
+
+    /**
+     * Pop element from stack, convert to given type
+     *
+     * @param to type to convert to
+     *
+     * @return the method emitter
+     */
+    MethodEmitter convert(final Type to) {
+        final Type type = peekType().convert(method, to);
+        if (type != null) {
+            if (peekType() != to) {
+                debug("convert", peekType(), "->", to);
+            }
+            popType();
+            pushType(type);
+        }
+        return this;
+    }
+
+    /**
+     * Helper function - expect two types that are equivalent
+     *
+     * @return common type
+     */
+    private Type get2() {
+        final Type p0 = popType();
+        final Type p1 = popType();
+        assert p0.isEquivalentTo(p1) : "expecting equivalent types on stack but got " + p0 + " and " + p1;
+        return p0;
+    }
+
+    /**
+     * Helper function - expect two types that are integer types and equivalent
+     *
+     * @return common type
+     */
+    private BitwiseType get2i() {
+        final BitwiseType p0 = popInteger();
+        final BitwiseType p1 = popInteger();
+        assert p0.isEquivalentTo(p1) : "expecting equivalent types on stack but got " + p0 + " and " + p1;
+        return p0;
+    }
+
+    /**
+     * Helper function - expect two types that are numbers and equivalent
+     *
+     * @return common type
+     */
+    private NumericType get2n() {
+        final NumericType p0 = popNumeric();
+        final NumericType p1 = popNumeric();
+        assert p0.isEquivalentTo(p1) : "expecting equivalent types on stack but got " + p0 + " and " + p1;
+        return p0;
+    }
+
+    /**
+     * Pop two numbers, perform addition and push result
+     *
+     * @return the method emitter
+     */
+    MethodEmitter add() {
+        debug("add");
+        pushType(get2().add(method));
+        return this;
+    }
+
+    /**
+     * Pop two numbers, perform subtraction and push result
+     *
+     * @return the method emitter
+     */
+    MethodEmitter sub() {
+        debug("sub");
+        pushType(get2n().sub(method));
+        return this;
+    }
+
+    /**
+     * Pop two numbers, perform multiplication and push result
+     *
+     * @return the method emitter
+     */
+    MethodEmitter mul() {
+        debug("mul ");
+        pushType(get2n().mul(method));
+        return this;
+    }
+
+    /**
+     * Pop two numbers, perform division and push result
+     *
+     * @return the method emitter
+     */
+    MethodEmitter div() {
+        debug("div");
+        pushType(get2n().div(method));
+        return this;
+    }
+
+    /**
+     * Pop two numbers, calculate remainder and push result
+     *
+     * @return the method emitter
+     */
+    MethodEmitter rem() {
+        debug("rem");
+        pushType(get2n().rem(method));
+        return this;
+    }
+
+    /**
+     * Retrieve the top <tt>count</tt> types on the stack without modifying it.
+     *
+     * @param count number of types to return
+     * @return array of Types
+     */
+    protected Type[] getTypesFromStack(final int count) {
+        final Iterator<Type> iter  = stack.iterator();
+        final Type[]         types = new Type[count];
+
+        for (int i = count - 1; i >= 0; i--) {
+            types[i] = iter.next();
+        }
+
+        return types;
+    }
+
+    /**
+     * Helper function to generate a function signature based on stack contents
+     * and argument count and return type
+     *
+     * @param returnType return type
+     * @param argCount   argument count
+     *
+     * @return function signature for stack contents
+     */
+    private String getDynamicSignature(final Type returnType, final int argCount) {
+        final Iterator<Type> iter       = stack.iterator();
+        final Type[]         paramTypes = new Type[argCount];
+
+        for (int i = argCount - 1; i >= 0; i--) {
+            paramTypes[i] = iter.next();
+        }
+        final String descriptor = Type.getMethodDescriptor(returnType, paramTypes);
+        for (int i = 0; i < argCount; i++) {
+            popType(paramTypes[argCount - i - 1]);
+        }
+
+        return descriptor;
+    }
+
+    /**
+     * Generate a dynamic new
+     *
+     * @param argCount  number of arguments
+     * @param flags     callsite flags
+     *
+     * @return the method emitter
+     */
+    MethodEmitter dynamicNew(final int argCount, final int flags) {
+        debug("dynamic_new", "argcount=" + argCount);
+        final String signature = getDynamicSignature(Type.OBJECT, argCount);
+        method.visitInvokeDynamicInsn("dyn:new", signature, LINKERBOOTSTRAP, flags);
+        pushType(Type.OBJECT); //TODO fix result type
+        return this;
+    }
+
+    /**
+     * Generate a dynamic call
+     *
+     * @param returnType return type
+     * @param argCount   number of arguments
+     * @param flags      callsite flags
+     *
+     * @return the method emitter
+     */
+    MethodEmitter dynamicCall(final Type returnType, final int argCount, final int flags) {
+        debug("dynamic_call", "args=" + argCount, "returnType=" + returnType);
+        final String signature = getDynamicSignature(returnType, argCount); // +1 because the function itself is the 1st parameter for dynamic calls (what you call - call target)
+        debug("   signature", signature);
+        method.visitInvokeDynamicInsn("dyn:call", signature, LINKERBOOTSTRAP, flags);
+        pushType(returnType);
+
+        return this;
+    }
+
+    /**
+     * Generate a dynamic call for a runtime node
+     *
+     * @param name       tag for the invoke dynamic for this runtime node
+     * @param returnType return type
+     * @param request    RuntimeNode request
+     *
+     * @return the method emitter
+     */
+    MethodEmitter dynamicRuntimeCall(final String name, final Type returnType, final RuntimeNode.Request request) {
+        debug("dynamic_runtime_call", name, "args=" + request.getArity(), "returnType=" + returnType);
+        final String signature = getDynamicSignature(returnType, request.getArity());
+        debug("   signature", signature);
+        method.visitInvokeDynamicInsn(name, signature, RUNTIMEBOOTSTRAP);
+        pushType(returnType);
+
+        return this;
+    }
+
+    /**
+     * Generate dynamic getter. Pop scope from stack. Push result
+     *
+     * @param valueType type of the value to set
+     * @param name      name of property
+     * @param flags     call site flags
+     * @param isMethod  should it prefer retrieving methods
+     *
+     * @return the method emitter
+     */
+    MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod) {
+        debug("dynamic_get", name, valueType);
+
+        Type type = valueType;
+        if (type.isObject() || type.isBoolean()) {
+            type = Type.OBJECT; //promote e.g strings to object generic setter
+        }
+
+        popType(Type.SCOPE);
+        method.visitInvokeDynamicInsn((isMethod ? "dyn:getMethod|getProp|getElem:" : "dyn:getProp|getElem|getMethod:") +
+                NameCodec.encode(name), Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags);
+
+        pushType(type);
+
+        convert(valueType); //most probably a nop
+
+        return this;
+    }
+
+    /**
+     * Generate dynamic setter. Pop receiver and property from stack.
+     *
+     * @param valueType the type of the value to set
+     * @param name      name of property
+     * @param flags     call site flags
+     */
+     void dynamicSet(final Type valueType, final String name, final int flags) {
+        debug("dynamic_set", name, peekType());
+
+        Type type = valueType;
+        if (type.isObject() || type.isBoolean()) { //promote strings to objects etc
+            type = Type.OBJECT;
+            convert(Type.OBJECT); //TODO bad- until we specialize boolean setters,
+        }
+
+        popType(type);
+        popType(Type.SCOPE);
+
+        method.visitInvokeDynamicInsn("dyn:setProp|setElem:" + NameCodec.encode(name), methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags);
+    }
+
+     /**
+     * Dynamic getter for indexed structures. Pop index and receiver from stack,
+     * generate appropriate signatures based on types
+     *
+     * @param result result type for getter
+     * @param flags call site flags for getter
+     * @param isMethod should it prefer retrieving methods
+     *
+     * @return the method emitter
+     */
+    MethodEmitter dynamicGetIndex(final Type result, final int flags, final boolean isMethod) {
+        debug("dynamic_get_index", peekType(1) + "[" + peekType() + "]");
+
+        Type resultType = result;
+        if (result.isBoolean()) {
+            resultType = Type.OBJECT; // INT->OBJECT to avoid another dimension of cross products in the getters. TODO
+        }
+
+        Type index = peekType();
+        if (index.isObject() || index.isBoolean()) {
+            index = Type.OBJECT; //e.g. string->object
+            convert(Type.OBJECT);
+        }
+        popType();
+
+        popType(Type.OBJECT);
+
+        final String signature = Type.getMethodDescriptor(resultType, Type.OBJECT /*e.g STRING->OBJECT*/, index);
+
+        method.visitInvokeDynamicInsn(isMethod ? "dyn:getMethod|getElem|getProp" : "dyn:getElem|getProp|getMethod",
+                signature, LINKERBOOTSTRAP, flags);
+        pushType(resultType);
+
+        if (result.isBoolean()) {
+            convert(Type.BOOLEAN);
+        }
+
+        return this;
+    }
+
+    /**
+     * Dynamic setter for indexed structures. Pop value, index and receiver from
+     * stack, generate appropriate signature based on types
+     *
+     * @param flags call site flags for setter
+     */
+    void dynamicSetIndex(final int flags) {
+        debug("dynamic_set_index", peekType(2) + "[" + peekType(1) + "] =", peekType());
+
+        Type value = peekType();
+        if (value.isObject() || value.isBoolean()) {
+            value = Type.OBJECT; //e.g. STRING->OBJECT - one descriptor for all object types
+            convert(Type.OBJECT);
+        }
+        popType();
+
+        Type index = peekType();
+        if (index.isObject() || index.isBoolean()) {
+            index = Type.OBJECT; //e.g. string->object
+            convert(Type.OBJECT);
+        }
+        popType(index);
+
+        final Type receiver = popType(Type.OBJECT);
+        assert receiver.isObject();
+
+        method.visitInvokeDynamicInsn("dyn:setElem|setProp", methodDescriptor(void.class, receiver.getTypeClass(), index.getTypeClass(), value.getTypeClass()), LINKERBOOTSTRAP, flags);
+    }
+
+    /**
+     * Load a key value in the proper form.
+     *
+     * @param key
+     */
+    //TODO move this and break it apart
+    MethodEmitter loadKey(final Object key) {
+        if (key instanceof IdentNode) {
+            method.visitLdcInsn(((IdentNode) key).getName());
+        } else if (key instanceof LiteralNode) {
+            method.visitLdcInsn(((LiteralNode<?>)key).getString());
+        } else {
+            method.visitLdcInsn(JSType.toString(key));
+        }
+        pushType(Type.OBJECT); //STRING
+        return this;
+    }
+
+     @SuppressWarnings("fallthrough")
+     private static Type fieldType(final String desc) {
+         switch (desc) {
+         case "Z":
+         case "B":
+         case "C":
+         case "S":
+         case "I":
+             return Type.INT;
+         case "F":
+             assert false;
+         case "D":
+             return Type.NUMBER;
+         case "J":
+             return Type.LONG;
+         default:
+             assert desc.startsWith("[") || desc.startsWith("L") : desc + " is not an object type";
+             switch (desc.charAt(0)) {
+             case 'L':
+                 return Type.OBJECT;
+             case '[':
+                 return Type.typeFor(Array.newInstance(fieldType(desc.substring(1)).getTypeClass(), 0).getClass());
+             default:
+                 assert false;
+             }
+             return Type.OBJECT;
+         }
+     }
+
+     /**
+      * Generate get for a field access
+      *
+      * @param fa the field access
+      *
+      * @return the method emitter
+      */
+    MethodEmitter getField(final FieldAccess fa) {
+        return fa.get(this);
+    }
+
+     /**
+      * Generate set for a field access
+      *
+      * @param fa the field access
+      */
+    void putField(final FieldAccess fa) {
+        fa.put(this);
+    }
+
+    /**
+     * Get the value of a non-static field, pop the receiver from the stack,
+     * push value to the stack
+     *
+     * @param className        class
+     * @param fieldName        field name
+     * @param fieldDescriptor  field descriptor
+     *
+     * @return the method emitter
+     */
+    MethodEmitter getField(final String className, final String fieldName, final String fieldDescriptor) {
+        debug("getfield", "receiver=" + peekType(), className + "." + fieldName + fieldDescriptor);
+        final Type receiver = popType();
+        assert receiver.isObject();
+        method.visitFieldInsn(GETFIELD, className, fieldName, fieldDescriptor);
+        pushType(fieldType(fieldDescriptor));
+        return this;
+    }
+
+    /**
+     * Get the value of a static field, push it to the stack
+     *
+     * @param className        class
+     * @param fieldName        field name
+     * @param fieldDescriptor  field descriptor
+     *
+     * @return the method emitter
+     */
+    MethodEmitter getStatic(final String className, final String fieldName, final String fieldDescriptor) {
+        debug("getstatic", className + "." + fieldName + "." + fieldDescriptor);
+        method.visitFieldInsn(GETSTATIC, className, fieldName, fieldDescriptor);
+        pushType(fieldType(fieldDescriptor));
+        return this;
+    }
+
+    /**
+     * Pop value and field from stack and write to a non-static field
+     *
+     * @param className       class
+     * @param fieldName       field name
+     * @param fieldDescriptor field descriptor
+     */
+    void putField(final String className, final String fieldName, final String fieldDescriptor) {
+        debug("putfield", "receiver=" + peekType(1), "value=" + peekType());
+        popType(fieldType(fieldDescriptor));
+        popType(Type.OBJECT);
+        method.visitFieldInsn(PUTFIELD, className, fieldName, fieldDescriptor);
+    }
+
+    /**
+     * Pop value from stack and write to a static field
+     *
+     * @param className       class
+     * @param fieldName       field name
+     * @param fieldDescriptor field descriptor
+     */
+    void putStatic(final String className, final String fieldName, final String fieldDescriptor) {
+        debug("putfield", "value=" + peekType());
+        popType(fieldType(fieldDescriptor));
+        method.visitFieldInsn(PUTSTATIC, className, fieldName, fieldDescriptor);
+    }
+
+    /**
+     * Register line number at a label
+     *
+     * @param line  line number
+     * @param label label
+     */
+    void lineNumber(final int line, final Label label) {
+        method.visitLineNumber(line, label);
+    }
+
+    /*
+     * Debugging below
+     */
+
+    private final FieldAccess ERR_STREAM       = staticField(System.class, "err", PrintStream.class);
+    private final Call        PRINT            = virtualCallNoLookup(PrintStream.class, "print", void.class, Object.class);
+    private final Call        PRINTLN          = virtualCallNoLookup(PrintStream.class, "println", void.class, Object.class);
+    private final Call        PRINT_STACKTRACE = virtualCallNoLookup(Throwable.class, "printStackTrace", void.class);
+
+    /**
+     * Emit a System.err.print statement of whatever is on top of the bytecode stack
+     */
+     void print() {
+         getField(ERR_STREAM);
+         swap();
+         convert(Type.OBJECT);
+         invoke(PRINT);
+     }
+
+    /**
+     * Emit a System.err.println statement of whatever is on top of the bytecode stack
+     */
+     void println() {
+         getField(ERR_STREAM);
+         swap();
+         convert(Type.OBJECT);
+         invoke(PRINTLN);
+     }
+
+     /**
+      * Emit a System.err.print statement
+      * @param string string to print
+      */
+     void print(final String string) {
+         getField(ERR_STREAM);
+         load(string);
+         invoke(PRINT);
+     }
+
+     /**
+      * Emit a System.err.println statement
+      * @param string string to print
+      */
+     void println(final String string) {
+         getField(ERR_STREAM);
+         load(string);
+         invoke(PRINTLN);
+     }
+
+     /**
+      * Print a stacktrace to S
+      */
+     void stacktrace() {
+         _new(Throwable.class);
+         dup();
+         invoke(constructorNoLookup(Throwable.class));
+         invoke(PRINT_STACKTRACE);
+     }
+
+    private static int linePrefix = 0;
+
+    /**
+     * Debug function that outputs generated bytecode and stack contents
+     *
+     * @param args debug information to print
+     */
+    private void debug(final Object... args) {
+        debug(30, args);
+    }
+
+    /**
+     * Debug function that outputs generated bytecode and stack contents
+     * for a label - indentation is currently the only thing that differs
+     *
+     * @param args debug information to print
+     */
+    private void debug_label(final Object... args) {
+        debug(26, args);
+    }
+
+    private void debug(final int padConstant, final Object... args) {
+        if (DEBUG) {
+            final StringBuilder sb = new StringBuilder();
+            int pad;
+
+            sb.append('#');
+            sb.append(++linePrefix);
+
+            pad = 5 - sb.length();
+            while (pad > 0) {
+                sb.append(' ');
+                pad--;
+            }
+
+            if (!stack.isEmpty()) {
+                sb.append("{");
+                sb.append(stack.size());
+                sb.append(":");
+                for (final Iterator<Type> iter = stack.iterator(); iter.hasNext();) {
+                    final Type t = iter.next();
+
+                    if (t == Type.SCOPE) {
+                        sb.append("scope");
+                    } else if (t == Type.THIS) {
+                        sb.append("this");
+                    } else if (t.isObject()) {
+                        String desc = t.getDescriptor();
+                        int i;
+                        for (i = 0; desc.charAt(i) == '[' && i < desc.length(); i++) {
+                            sb.append('[');
+                        }
+                        desc = desc.substring(i);
+                        final int slash = desc.lastIndexOf('/');
+                        if (slash != -1) {
+                            desc = desc.substring(slash + 1, desc.length() - 1);
+                        }
+                        if ("Object".equals(desc)) {
+                            sb.append('O');
+                        } else {
+                            sb.append(desc);
+                        }
+                    } else {
+                        sb.append(t.getDescriptor());
+                    }
+
+                    if (iter.hasNext()) {
+                        sb.append(' ');
+                    }
+                }
+                sb.append('}');
+                sb.append(' ');
+            }
+
+            pad = padConstant - sb.length();
+            while (pad > 0) {
+                sb.append(' ');
+                pad--;
+            }
+
+            for (final Object arg : args) {
+                sb.append(arg);
+                sb.append(' ');
+            }
+
+            if (env != null) { //early bootstrap code doesn't have inited context yet
+                LOG.info(sb.toString());
+                if (DEBUG_TRACE_LINE == linePrefix) {
+                    new Throwable().printStackTrace(LOG.getOutputStream());
+                }
+            }
+
+        }
+    }
+
+    /**
+     * Set the current function node being emitted
+     * @param functionNode the function node
+     */
+    void setFunctionNode(final FunctionNode functionNode) {
+        this.functionNode = functionNode;
+    }
+
+    /**
+     * Get the split node for this method emitter, if this is code
+     * generation due to splitting large methods
+     *
+     * @return split node
+     */
+    SplitNode getSplitNode() {
+        return splitNode;
+    }
+
+    /**
+     * Set the split node for this method emitter
+     * @param splitNode split node
+     */
+    void setSplitNode(final SplitNode splitNode) {
+        this.splitNode = splitNode;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Namespace.java b/nashorn/src/jdk/nashorn/internal/codegen/Namespace.java
new file mode 100644
index 0000000..02fdb94
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Namespace.java
@@ -0,0 +1,101 @@
+/*
+ * 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.codegen;
+
+import java.util.HashMap;
+
+/**
+ * A name space hierarchy, where each level holds a name directory with
+ * names that may be unique for each level.
+ */
+
+public class Namespace {
+    /** Parent namespace. */
+    private final Namespace parent;
+
+    /** Name directory - version count for each name */
+    private final HashMap<String, Integer> directory;
+
+    /**
+     * Constructor
+     */
+    public Namespace() {
+        this(null);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param parent parent name space
+     */
+    public Namespace(final Namespace parent) {
+        this.parent    = parent;
+        directory = new HashMap<>();
+    }
+
+    /**
+     * Return the parent Namespace of this space.
+     *
+     * @return parent name space
+     */
+    public Namespace getParent() {
+        return parent;
+    }
+
+    private HashMap<String, Integer> getDirectory() {
+        return directory;
+    }
+
+    /**
+     * Create a uniqueName name in the namespace in the form base$n where n varies
+     * .
+     * @param base Base of name.  Base will be returned if uniqueName.
+     *
+     * @return Generated uniqueName name.
+     */
+    public String uniqueName(final String base) {
+        for (Namespace namespace = this; namespace != null; namespace = namespace.getParent()) {
+            final HashMap<String, Integer> namespaceDirectory = namespace.getDirectory();
+            final Integer                  counter            = namespaceDirectory.get(base);
+
+            if (counter != null) {
+                final int count = counter + 1;
+                namespaceDirectory.put(base, count);
+
+                return base + "$" + count;
+            }
+        }
+
+        directory.put(base, 0);
+
+        return base;
+    }
+
+    @Override
+    public String toString() {
+        return directory.toString();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
new file mode 100644
index 0000000..6e032e2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
@@ -0,0 +1,762 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.Compiler.SCRIPTS_PACKAGE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.ALLOCATE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_ARGUMENTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_SCOPE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.JAVA_THIS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_PREFIX;
+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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.runtime.AccessorProperty;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.FunctionScope;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Generates the ScriptObject subclass structure with fields for a user objects.
+ */
+public final class ObjectClassGenerator {
+
+    /**
+     * Marker for scope parameters.
+     */
+    static final String SCOPE_MARKER = "P";
+
+    /**
+     * Debug field logger
+     * Should we print debugging information for fields when they are generated and getters/setters are called?
+     */
+    public static final DebugLogger LOG          = new DebugLogger("fields", "nashorn.fields.debug");
+
+    /**
+     * is field debugging enabled. Several modules in codegen and properties use this, hence
+     * public access.
+     */
+    public static final boolean     DEBUG_FIELDS = LOG.isEnabled();
+
+    /**
+     * Should the runtime only use java.lang.Object slots for fields? If this is false, the representation
+     * will be a primitive 64-bit long value used for all primitives and a java.lang.Object for references.
+     * This introduces a larger number of method handles in the system, as we need to have different getters
+     * and setters for the different fields. Currently this introduces significant overhead in Hotspot.
+     *
+     * This is engineered to plug into the TaggedArray implementation, when it's done.
+     */
+    public static final boolean OBJECT_FIELDS_ONLY = !Options.getBooleanProperty("nashorn.fields.dual");
+
+    /** The field types in the system */
+    private static final List<Type> FIELD_TYPES = new LinkedList<>();
+
+    /** What type is the primitive type in dual representation */
+    public static final Type PRIMITIVE_TYPE = Type.LONG;
+
+    /**
+     * The list of field types that we support - one type creates one field. This is currently either
+     * LONG + OBJECT or just OBJECT for classic mode.
+     */
+    static {
+        if (!OBJECT_FIELDS_ONLY) {
+            System.err.println("WARNING!!! Running with primitive fields - there is untested functionality!");
+            FIELD_TYPES.add(PRIMITIVE_TYPE);
+        }
+        FIELD_TYPES.add(Type.OBJECT);
+    }
+
+    /** The context */
+    private final Context context;
+
+    /**
+     * The list of available accessor types in width order. This order is used for type guesses narrow{@literal ->} wide
+     *  in the dual--fields world
+     */
+    public static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
+            Arrays.asList(
+                Type.INT,
+                Type.LONG,
+                Type.NUMBER,
+                Type.OBJECT));
+
+    //these are hard coded for speed and so that we can switch on them
+    private static final int TYPE_INT_INDEX    = 0; //getAccessorTypeIndex(int.class);
+    private static final int TYPE_LONG_INDEX   = 1; //getAccessorTypeIndex(long.class);
+    private static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class);
+    private static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class);
+
+    /**
+     * Constructor
+     *
+     * @param context a context
+     */
+    public ObjectClassGenerator(final Context context) {
+        this.context = context;
+        assert context != null;
+    }
+
+    /**
+     * Given a type of an accessor, return its index in [0..getNumberOfAccessorTypes())
+     *
+     * @param type the type
+     *
+     * @return the accessor index, or -1 if no accessor of this type exists
+     */
+    public static int getAccessorTypeIndex(final Type type) {
+        return getAccessorTypeIndex(type.getTypeClass());
+    }
+
+    /**
+     * Given a class of an accessor, return its index in [0..getNumberOfAccessorTypes())
+     *
+     * Note that this is hardcoded with respect to the dynamic contents of the accessor
+     * types array for speed. Hotspot got stuck with this as 5% of the runtime in
+     * a benchmark when it looped over values and increased an index counter. :-(
+     *
+     * @param type the type
+     *
+     * @return the accessor index, or -1 if no accessor of this type exists
+     */
+    public static int getAccessorTypeIndex(final Class<?> type) {
+        if (type == int.class) {
+            return 0;
+        } else if (type == long.class) {
+            return 1;
+        } else if (type == double.class) {
+            return 2;
+        } else if (!type.isPrimitive()) {
+            return 3;
+        }
+        return -1;
+    }
+
+    /**
+     * Return the number of accessor types available.
+     *
+     * @return number of accessor types in system
+     */
+    public static int getNumberOfAccessorTypes() {
+        return ACCESSOR_TYPES.size();
+    }
+
+    /**
+     * Return the accessor type based on its index in [0..getNumberOfAccessorTypes())
+     * Indexes are ordered narrower{@literal ->}wider / optimistic{@literal ->}pessimistic. Invalidations always
+     * go to a type of higher index
+     *
+     * @param index accessor type index
+     *
+     * @return a type corresponding to the index.
+     */
+
+    public static Type getAccessorType(final int index) {
+        return ACCESSOR_TYPES.get(index);
+    }
+
+    /**
+     * Returns the class name for JavaScript objects with fieldCount fields.
+     *
+     * @param fieldCount Number of fields to allocate.
+     *
+     * @return The class name.
+     */
+    public static String getClassName(final int fieldCount) {
+        return fieldCount != 0 ? SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.tag() + fieldCount :
+                                 SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.tag();
+    }
+
+    /**
+     * Returns the class name for JavaScript scope with fieldCount fields and
+     * paramCount parameters.
+     *
+     * @param fieldCount Number of fields to allocate.
+     * @param paramCount Number of parameters to allocate
+     *
+     * @return The class name.
+     */
+    public static String getClassName(final int fieldCount, final int paramCount) {
+        return SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.tag() + fieldCount + SCOPE_MARKER + paramCount;
+    }
+
+    /**
+     * Returns the name of a field based on number and type.
+     *
+     * @param fieldIndex Ordinal of field.
+     * @param type       Type of field.
+     *
+     * @return The field name.
+     */
+    public static String getFieldName(final int fieldIndex, final Type type) {
+        return type.getDescriptor().substring(0, 1) + fieldIndex;
+    }
+
+    /**
+     * In the world of Object fields, we also have no undefined SwitchPoint, to reduce as much potential
+     * MethodHandle overhead as possible. In that case, we explicitly need to assign undefined to fields
+     * when we initialize them.
+     *
+     * @param init       constructor to generate code in
+     * @param className  name of class
+     * @param fieldNames fields to initialize to undefined, where applicable
+     */
+    private static void initializeToUndefined(final MethodEmitter init, final String className, final List<String> fieldNames) {
+        if (fieldNames.isEmpty()) {
+            return;
+        }
+
+        // always initialize fields to undefined, even with --dual-fields. Then it's ok to
+        // remember things like "widest set type" in properties, and if it's object, don't
+        // add any special "return undefined" getters, saving an invalidation
+        init.load(Type.OBJECT, JAVA_THIS.slot());
+        init.loadUndefined(Type.OBJECT);
+
+        final Iterator<String> iter = fieldNames.iterator();
+        while (iter.hasNext()) {
+            final String fieldName = iter.next();
+            if (iter.hasNext()) {
+                init.dup2();
+            }
+            init.putField(className, fieldName, Type.OBJECT.getDescriptor());
+        }
+    }
+
+    /**
+     * Generate the byte codes for a JavaScript object class or scope.
+     * Class name is a function of number of fields and number of param
+     * fields
+     *
+     * @param descriptor Descriptor pulled from class name.
+     *
+     * @return Byte codes for generated class.
+     */
+    public byte[] generate(final String descriptor) {
+        final String[] counts     = descriptor.split(SCOPE_MARKER);
+        final int      fieldCount = Integer.valueOf(counts[0]);
+
+        if (counts.length == 1) {
+            return generate(fieldCount);
+        }
+
+        final int paramCount = Integer.valueOf(counts[1]);
+
+        return generate(fieldCount, paramCount);
+    }
+
+    /**
+     * Generate the byte codes for a JavaScript object class with fieldCount fields.
+     *
+     * @param fieldCount Number of fields in the JavaScript object.
+     *
+     * @return Byte codes for generated class.
+     */
+    public byte[] generate(final int fieldCount) {
+        final String       className    = getClassName(fieldCount);
+        final String       superName    = className(ScriptObject.class);
+        final ClassEmitter classEmitter = newClassEmitter(className, superName);
+        final List<String> initFields   = addFields(classEmitter, fieldCount);
+
+        final MethodEmitter init = newInitMethod(classEmitter);
+        initializeToUndefined(init, className, initFields);
+        init.returnVoid();
+        init.end();
+
+        newEmptyInit(classEmitter, className);
+        newAllocate(classEmitter, className);
+
+        return toByteArray(classEmitter);
+    }
+
+    /**
+     * Generate the byte codes for a JavaScript scope class with fieldCount fields
+     * and paramCount parameters.
+     *
+     * @param fieldCount Number of fields in the JavaScript scope.
+     * @param paramCount Number of parameters in the JavaScript scope
+     * .
+     * @return Byte codes for generated class.
+     */
+    public byte[] generate(final int fieldCount, final int paramCount) {
+        final String className          = getClassName(fieldCount, paramCount);
+        final String superName          = className(FunctionScope.class);
+        final ClassEmitter classEmitter = newClassEmitter(className, superName);
+        final List<String> initFields   = addFields(classEmitter, fieldCount);
+
+        final MethodEmitter init = newInitScopeMethod(classEmitter);
+        initializeToUndefined(init, className, initFields);
+        init.returnVoid();
+        init.end();
+
+        final MethodEmitter initWithArguments = newInitScopeWithArgumentsMethod(classEmitter);
+        initializeToUndefined(initWithArguments, className, initFields);
+        initWithArguments.returnVoid();
+        initWithArguments.end();
+
+        return toByteArray(classEmitter);
+    }
+
+    /**
+     * Generates the needed fields.
+     *
+     * @param classEmitter Open class emitter.
+     * @param fieldCount   Number of fields.
+     *
+     * @return List fields that need to be initialized.
+     */
+    private static List<String> addFields(final ClassEmitter classEmitter, final int fieldCount) {
+        final List<String> initFields = new LinkedList<>();
+
+        for (int i = 0; i < fieldCount; i++) {
+            for (final Type type : FIELD_TYPES) {
+                final String fieldName = getFieldName(i, type);
+                classEmitter.field(fieldName, type.getTypeClass());
+
+                if (type == Type.OBJECT) {
+                    initFields.add(fieldName);
+                }
+            }
+        }
+
+        return initFields;
+    }
+
+    /**
+     * Allocate and initialize a new class emitter.
+     *
+     * @param className Name of JavaScript class.
+     *
+     * @return Open class emitter.
+     */
+    private ClassEmitter newClassEmitter(final String className, final String superName) {
+        final ClassEmitter classEmitter = new ClassEmitter(context.getEnv(), className, superName);
+        classEmitter.begin();
+
+        return classEmitter;
+    }
+
+    /**
+     * Allocate and initialize a new <init> method.
+     *
+     * @param classEmitter  Open class emitter.
+     *
+     * @return Open method emitter.
+     */
+    private static MethodEmitter newInitMethod(final ClassEmitter classEmitter) {
+        final MethodEmitter init = classEmitter.init(PropertyMap.class);
+        init.begin();
+        init.load(Type.OBJECT, JAVA_THIS.slot());
+        init.load(Type.OBJECT, MAP.slot());
+        init.invoke(constructorNoLookup(ScriptObject.class, PropertyMap.class));
+
+        return init;
+    }
+
+    /**
+     * Allocate and initialize a new <init> method for scopes.
+     * @param classEmitter  Open class emitter.
+     * @return Open method emitter.
+     */
+    private static MethodEmitter newInitScopeMethod(final ClassEmitter classEmitter) {
+        final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class);
+        init.begin();
+        init.load(Type.OBJECT, JAVA_THIS.slot());
+        init.load(Type.OBJECT, MAP.slot());
+        init.load(Type.OBJECT, INIT_SCOPE.slot());
+        init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class));
+
+        return init;
+    }
+
+    /**
+     * Allocate and initialize a new <init> method for scopes with arguments.
+     * @param classEmitter  Open class emitter.
+     * @return Open method emitter.
+     */
+    private static MethodEmitter newInitScopeWithArgumentsMethod(final ClassEmitter classEmitter) {
+        final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class, Object.class);
+        init.begin();
+        init.load(Type.OBJECT, JAVA_THIS.slot());
+        init.load(Type.OBJECT, MAP.slot());
+        init.load(Type.OBJECT, INIT_SCOPE.slot());
+        init.load(Type.OBJECT, INIT_ARGUMENTS.slot());
+        init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class, Object.class));
+
+        return init;
+    }
+
+    /**
+     * Add an empty <init> method to the JavaScript class.
+     *
+     * @param classEmitter Open class emitter.
+     * @param className    Name of JavaScript class.
+     */
+    private static void newEmptyInit(final ClassEmitter classEmitter, final String className) {
+        final MethodEmitter emptyInit = classEmitter.init();
+        emptyInit.begin();
+        emptyInit.load(Type.OBJECT, JAVA_THIS.slot());
+        emptyInit.loadNull();
+        emptyInit.invoke(constructorNoLookup(className, PropertyMap.class));
+        emptyInit.returnVoid();
+        emptyInit.end();
+    }
+
+    /**
+     * Add an empty <init> method to the JavaScript class.
+     *
+     * @param classEmitter Open class emitter.
+     * @param className    Name of JavaScript class.
+     */
+    private static void newAllocate(final ClassEmitter classEmitter, final String className) {
+        final MethodEmitter allocate = classEmitter.method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), ALLOCATE.tag(), ScriptObject.class, PropertyMap.class);
+        allocate.begin();
+        allocate._new(className);
+        allocate.dup();
+        allocate.load(Type.typeFor(PropertyMap.class), 0);
+        allocate.invoke(constructorNoLookup(className, PropertyMap.class));
+        allocate._return();
+        allocate.end();
+    }
+
+    /**
+     * Collects the byte codes for a generated JavaScript class.
+     *
+     * @param classEmitter Open class emitter.
+     * @return Byte codes for the class.
+     */
+    private byte[] toByteArray(final ClassEmitter classEmitter) {
+        classEmitter.end();
+
+        final byte[] code = classEmitter.toByteArray();
+        final ScriptEnvironment env = context.getEnv();
+
+        if (env._print_code) {
+            env.getErr().println(ClassEmitter.disassemble(code));
+        }
+
+        if (env._verify_code) {
+            context.verify(code);
+        }
+
+        return code;
+    }
+
+    /** Double to long bits, used with --dual-fields for primitive double values */
+    private static final MethodHandle PACK_DOUBLE =
+        MH.explicitCastArguments(MH.findStatic(MethodHandles.publicLookup(), Double.class, "doubleToRawLongBits", MH.type(long.class, double.class)), MH.type(long.class, double.class));
+
+    /** double bits to long, used with --dual-fields for primitive double values */
+    private static MethodHandle UNPACK_DOUBLE =
+        MH.findStatic(MethodHandles.publicLookup(), Double.class, "longBitsToDouble", MH.type(double.class, long.class));
+
+    /** object conversion quickies with JS semantics - used for return value and parameter filter */
+    private static MethodHandle[] CONVERT_OBJECT = {
+        JSType.TO_INT32.methodHandle(),
+        JSType.TO_UINT32.methodHandle(),
+        JSType.TO_NUMBER.methodHandle(),
+        null
+    };
+
+    /**
+     * Given a primitiveGetter (optional for non dual fields) and an objectSetter that retrieve
+     * the primitive and object version of a field respectively, return one with the correct
+     * method type and the correct filters. For example, if the value is stored as a double
+     * and we want an Object getter, in the dual fields world we'd pick the primitiveGetter,
+     * which reads a long, use longBitsToDouble on the result to unpack it, and then change the
+     * return type to Object, boxing it. In the objects only world there are only object fields,
+     * primtives are boxed when asked for them and we don't need to bother with primitive encoding
+     * (or even undefined, which if forType==null) representation, so we just return whatever is
+     * in the object field. The object field is always initiated to Undefined, so here, where we have
+     * the representation for Undefined in all our bits, this is not a problem.
+     * <p>
+     * Representing undefined in a primitive is hard, for an int there aren't enough bits, for a long
+     * we could limit the width of a representation, and for a double (as long as it is stored as long,
+     * as all NaNs will turn into QNaN on ia32, which is one bit pattern, we should use a special NaN).
+     * Naturally we could have special undefined values for all types which mean "go look in a wider field",
+     * but the guards needed on every getter took too much time.
+     * <p>
+     * To see how this is used, look for example in {@link AccessorProperty#getGetter}
+     * <p>
+     * @param forType         representation of the underlying type in the field, null if undefined
+     * @param type            type to retrieve it as
+     * @param primitiveGetter getter to read the primitive version of this field (null if Objects Only)
+     * @param objectGetter    getter to read the object version of this field
+     *
+     * @return getter for the given representation that returns the given type
+     */
+    public static MethodHandle createGetter(final Class<?> forType, final Class<?> type, final MethodHandle primitiveGetter, final MethodHandle objectGetter) {
+        final int fti = forType == null ? -1 : getAccessorTypeIndex(forType);
+        final int ti  = getAccessorTypeIndex(type);
+
+        if (fti == TYPE_OBJECT_INDEX || OBJECT_FIELDS_ONLY) {
+            if (ti == TYPE_OBJECT_INDEX) {
+                return objectGetter;
+            }
+
+            return MH.filterReturnValue(objectGetter, CONVERT_OBJECT[ti]);
+        }
+
+        assert !OBJECT_FIELDS_ONLY;
+        if (forType == null) {
+            return GET_UNDEFINED[ti];
+        }
+
+        final MethodType pmt = primitiveGetter.type();
+
+        switch (fti) {
+        case TYPE_INT_INDEX:
+        case TYPE_LONG_INDEX:
+            switch (ti) {
+            case TYPE_INT_INDEX:
+                //get int while an int, truncating cast of long value
+                return MH.explicitCastArguments(primitiveGetter, pmt.changeReturnType(int.class));
+            case TYPE_LONG_INDEX:
+                return primitiveGetter;
+            default:
+                return MH.asType(primitiveGetter, pmt.changeReturnType(type));
+            }
+        case TYPE_DOUBLE_INDEX:
+            final MethodHandle getPrimitiveAsDouble = MH.filterReturnValue(primitiveGetter, UNPACK_DOUBLE);
+            switch (ti) {
+            case TYPE_INT_INDEX:
+            case TYPE_LONG_INDEX:
+                return MH.explicitCastArguments(getPrimitiveAsDouble, pmt.changeReturnType(type));
+            case TYPE_DOUBLE_INDEX:
+                return getPrimitiveAsDouble;
+            default:
+                return MH.asType(getPrimitiveAsDouble, pmt.changeReturnType(Object.class));
+            }
+        default:
+            assert false;
+            return null;
+        }
+    }
+
+    private static final MethodHandle IS_TYPE_GUARD = findOwnMH("isType", boolean.class, Class.class, Object.class);
+
+    @SuppressWarnings("unused")
+    private static boolean isType(final Class<?> boxedForType, final Object x) {
+        return x.getClass() == boxedForType;
+    }
+
+    private static Class<? extends Number> getBoxedType(final Class<?> forType) {
+        if (forType == int.class) {
+            return Integer.class;
+        }
+
+        if (forType == long.class) {
+            return Long.class;
+        }
+
+        if (forType == double.class) {
+            return Double.class;
+        }
+
+        assert false;
+        return null;
+    }
+
+    /**
+     * If we are setting boxed types (because the compiler couldn't determine which they were) to
+     * a primitive field, we can reuse the primitive field getter, as long as we are setting an element
+     * of the same boxed type as the primitive type representation
+     *
+     * @param forType           the current type
+     * @param primitiveSetter   primitive setter for the current type with an element of the current type
+     * @param objectSetter      the object setter
+     *
+     * @return method handle that checks if the element to be set is of the currenttype, even though it's boxed
+     *  and instead of using the generic object setter, that would blow up the type and invalidate the map,
+     *  unbox it and call the primitive setter instead
+     */
+    public static MethodHandle createGuardBoxedPrimitiveSetter(final Class<?> forType, final MethodHandle primitiveSetter, final MethodHandle objectSetter) {
+        final Class<? extends Number> boxedForType = getBoxedType(forType);
+        //object setter that checks for primitive if current type is primitive
+
+        return MH.guardWithTest(
+            MH.insertArguments(
+                MH.dropArguments(
+                    IS_TYPE_GUARD,
+                    1,
+                    Object.class),
+                0,
+                boxedForType),
+                MH.asType(
+                    primitiveSetter,
+                    objectSetter.type()),
+                objectSetter);
+    }
+
+    /**
+     * This is similar to the {@link ObjectClassGenerator#createGetter} function. Performs
+     * the necessary operations to massage a setter operand of type {@code type} to
+     * fit into the primitive field (if primitive and dual fields is enabled) or into
+     * the object field (box if primitive and dual fields is disabled)
+     *
+     * @param forType         representation of the underlying object
+     * @param type            representation of field to write, and setter signature
+     * @param primitiveSetter setter that writes to the primitive field (null if Objects Only)
+     * @param objectSetter    setter that writes to the object field
+     *
+     * @return the setter for the given representation that takes a {@code type}
+     */
+    public static MethodHandle createSetter(final Class<?> forType, final Class<?> type, final MethodHandle primitiveSetter, final MethodHandle objectSetter) {
+        assert forType != null;
+
+        final int fti = getAccessorTypeIndex(forType);
+        final int ti  = getAccessorTypeIndex(type);
+
+        if (fti == TYPE_OBJECT_INDEX || OBJECT_FIELDS_ONLY) {
+            if (ti == TYPE_OBJECT_INDEX) {
+                return objectSetter;
+            }
+
+            return MH.asType(objectSetter, objectSetter.type().changeParameterType(1, type));
+        }
+
+        assert !OBJECT_FIELDS_ONLY;
+
+        final MethodType pmt = primitiveSetter.type();
+
+        switch (fti) {
+        case TYPE_INT_INDEX:
+        case TYPE_LONG_INDEX:
+            switch (ti) {
+            case TYPE_INT_INDEX:
+                return MH.asType(primitiveSetter, pmt.changeParameterType(1, int.class));
+            case TYPE_LONG_INDEX:
+                return primitiveSetter;
+            case TYPE_DOUBLE_INDEX:
+                return MH.filterArguments(primitiveSetter, 1, PACK_DOUBLE);
+            default:
+                return objectSetter;
+            }
+        case TYPE_DOUBLE_INDEX:
+            if (ti == TYPE_OBJECT_INDEX) {
+                return objectSetter;
+            }
+            return MH.asType(MH.filterArguments(primitiveSetter, 1, PACK_DOUBLE), pmt.changeParameterType(1, type));
+        default:
+            assert false;
+            return null;
+        }
+    }
+
+    //
+    // Provide generic getters and setters for undefined types. If a type is undefined, all
+    // and marshals the set to the correct setter depending on the type of the value being set.
+    // Note that there are no actual undefined versions of int, long and double in JavaScript,
+    // but executing toInt32, toLong and toNumber always returns a working result, 0, 0L or NaN
+    //
+
+    /** The value of Undefined cast to an int32 */
+    public static final int    UNDEFINED_INT    = 0;
+    /** The value of Undefined cast to a long */
+    public static final long   UNDEFINED_LONG   = 0L;
+    /** The value of Undefined cast to a double */
+    public static final double UNDEFINED_DOUBLE = Double.NaN;
+
+    /**
+     * Compute type name for correct undefined getter
+     * @param type the type
+     * @return name of getter
+     */
+    private static String typeName(final Type type) {
+        String name = type.getTypeClass().getName();
+        final int dot = name.lastIndexOf('.');
+        if (dot != -1) {
+            name = name.substring(dot + 1);
+        }
+        return Character.toUpperCase(name.charAt(0)) + name.substring(1);
+    }
+
+    /**
+     * Handles for undefined getters of the different types
+     */
+    private static final MethodHandle[] GET_UNDEFINED = new MethodHandle[ObjectClassGenerator.getNumberOfAccessorTypes()];
+
+    /**
+     * Used to wrap getters for undefined values, where this matters. Currently only in dual fields.
+     * If an object starts out as undefined it needs special getters until it has been assigned
+     * something the first time
+     *
+     * @param returnType type to cast the undefined to
+     *
+     * @return undefined as returnType
+     */
+    public static MethodHandle getUndefined(final Class<?> returnType) {
+        return GET_UNDEFINED[ObjectClassGenerator.getAccessorTypeIndex(returnType)];
+    }
+
+    static {
+        int pos = 0;
+        for (final Type type : ACCESSOR_TYPES) {
+            GET_UNDEFINED[pos++] = findOwnMH("getUndefined" + typeName(type), type.getTypeClass(), Object.class);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static int getUndefinedInt(final Object obj) {
+        return UNDEFINED_INT;
+    }
+
+    @SuppressWarnings("unused")
+    private static long getUndefinedLong(final Object obj) {
+        return UNDEFINED_LONG;
+    }
+
+    @SuppressWarnings("unused")
+    private static double getUndefinedDouble(final Object obj) {
+        return UNDEFINED_DOUBLE;
+    }
+
+    @SuppressWarnings("unused")
+    private static Object getUndefinedObject(final Object obj) {
+        return ScriptRuntime.UNDEFINED;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), ObjectClassGenerator.class, name, MH.type(rtype, types));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java
new file mode 100644
index 0000000..e4e7b7d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java
@@ -0,0 +1,172 @@
+/*
+ * 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.codegen;
+
+import java.util.List;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.PropertyMap;
+
+/**
+ * Base class for object creation code generation.
+ */
+public abstract class ObjectCreator {
+
+    /** Compile unit for this ObjectCreator, see CompileUnit */
+    protected final CompileUnit   compileUnit;
+
+    /** List of keys to initiate in this ObjectCreator */
+    protected final List<String>  keys;
+
+    /** List of symbols to initiate in this ObjectCreator */
+    protected final List<Symbol>  symbols;
+
+    /** Code generator */
+    protected final CodeGenerator codegen;
+
+    private   final boolean       isScope;
+    private   final boolean       hasArguments;
+    private         int           fieldCount;
+    private         int           paramCount;
+    private         String        fieldObjectClassName;
+    private         Class<?>      fieldObjectClass;
+    private         PropertyMap   propertyMap;
+
+    /**
+     * Constructor
+     *
+     * @param codegen      the code generator
+     * @param keys         the keys
+     * @param symbols      the symbols corresponding to keys, same index
+     * @param isScope      is this object scope
+     * @param hasArguments does the created object have an "arguments" property
+     */
+    protected ObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final boolean isScope, final boolean hasArguments) {
+        this.codegen       = codegen;
+        this.compileUnit   = codegen.getCurrentCompileUnit();
+        this.keys          = keys;
+        this.symbols       = symbols;
+        this.isScope       = isScope;
+        this.hasArguments  = hasArguments;
+
+        countFields();
+        findClass();
+    }
+
+    /**
+     * Tally the number of fields and parameters.
+     */
+    private void countFields() {
+        for (final Symbol symbol : this.symbols) {
+            if (symbol != null) {
+                if (hasArguments() && symbol.isParam()) {
+                    symbol.setFieldIndex(paramCount++);
+                } else {
+                    symbol.setFieldIndex(fieldCount++);
+                }
+            }
+        }
+    }
+
+    /**
+     * Locate (or indirectly create) the object container class.
+     */
+    private void findClass() {
+        fieldObjectClassName = isScope() ?
+            ObjectClassGenerator.getClassName(fieldCount, paramCount) :
+            ObjectClassGenerator.getClassName(fieldCount);
+
+        try {
+            this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName));
+        } catch (final ClassNotFoundException e) {
+            throw new AssertionError("Nashorn has encountered an internal error.  Structure can not be created.");
+        }
+    }
+
+    /**
+     * Generate code for making the object.
+     * @param method Script method.
+     */
+    protected abstract void makeObject(final MethodEmitter method);
+
+    /**
+     * Create a new MapCreator
+     * @param clazz type of MapCreator
+     * @return map creator instantiated by type
+     */
+    protected MapCreator newMapCreator(final Class<?> clazz) {
+        return new MapCreator(clazz, keys, symbols);
+    }
+
+    /**
+     * Construct the property map appropriate for the object.
+     * @return the newly created property map
+     */
+    protected PropertyMap makeMap() {
+        if (keys.isEmpty()) { //empty map
+            propertyMap = PropertyMap.newMap(fieldObjectClass);
+        } else {
+            propertyMap = newMapCreator(fieldObjectClass).makeMap(hasArguments());
+        }
+        return propertyMap;
+    }
+
+    /**
+     * Emit the correct map for the object.
+     * @param method method emitter
+     * @return the method emitter
+     */
+    protected MethodEmitter loadMap(final MethodEmitter method) {
+        codegen.loadConstant(propertyMap);
+        return method;
+    }
+
+    /**
+     * Get the class name for the object class,
+     * e.g. {@code com.nashorn.oracle.scripts.JO2P0}
+     *
+     * @return script class name
+     */
+    String getClassName() {
+        return fieldObjectClassName;
+    }
+
+    /**
+     * Is this a scope object
+     * @return true if scope
+     */
+    protected boolean isScope() {
+        return isScope;
+    }
+
+    /**
+     * Does the created object have an "arguments" property
+     * @return true if has an "arguments" property
+     */
+    protected boolean hasArguments() {
+        return hasArguments;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java b/nashorn/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java
new file mode 100644
index 0000000..1731da8
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java
@@ -0,0 +1,693 @@
+/*
+ * 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.codegen;
+
+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.lookup.Lookup.MH;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.RuntimeNode.Request;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+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.
+ * Gradually reverts to wider boxed types if the assumption for the RuntimeNode
+ * is proven wrong. Finally reverts to the generic ScriptRuntime method.
+ *
+ * This is used from the CodeGenerator when we have a runtime node, but 1 or more
+ * primitive arguments. This class generated appropriate specializations, for example
+ * {@code Object a === int b} is a good idea to specialize to {@code ((Integer)a).intValue() == b}
+ * surrounded by catch blocks that will try less narrow specializations
+ */
+public final class RuntimeCallSite extends MutableCallSite {
+    static final Call BOOTSTRAP = staticCallNoLookup(Bootstrap.class, "runtimeBootstrap", CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
+
+    private static final MethodHandle NEXT = findOwnMH("next",  MethodHandle.class);
+
+    private final RuntimeNode.Request request;
+
+    private String name;
+
+    /**
+     * A specialized runtime node, i.e. on where we know at least one more specific type than object
+     */
+    static final class SpecializedRuntimeNode {
+        private static final char REQUEST_SEPARATOR = ':';
+
+        private final RuntimeNode.Request request;
+
+        private final Type[] parameterTypes;
+
+        private final Type   returnType;
+
+        /**
+         * Constructor.
+         *
+         * @param request        runtime node request to specialize
+         * @param parameterTypes parameter types of the call site
+         * @param returnType     return type of the call site
+         */
+        SpecializedRuntimeNode(final RuntimeNode.Request request, final Type[] parameterTypes, final Type returnType) {
+            this.request        = request;
+            this.parameterTypes = parameterTypes;
+            this.returnType     = returnType;
+        }
+
+        /**
+         * The first type to try to use for this genrated runtime node
+         *
+         * @return a type
+         */
+        public Type firstTypeGuess() {
+            Type widest = Type.UNKNOWN;
+            for (final Type type : parameterTypes) {
+                if (type.isObject()) {
+                    continue;
+                }
+                widest = Type.widest(type, widest);
+            }
+            widest = Type.widest(widest, firstTypeGuessForObject(request));
+
+            return widest;
+        }
+
+        private static Type firstTypeGuessForObject(final Request request) {
+            switch (request) {
+            case ADD:
+                return INT;
+            default:
+                return BOOLEAN;
+            }
+        }
+
+        Request getRequest() {
+            return request;
+        }
+
+        Type[] getParameterTypes() {
+            return parameterTypes;
+        }
+
+        Type getReturnType() {
+            return returnType;
+        }
+
+        private static char descFor(final Type type) {
+            if (type.isObject()) {
+                return 'O';
+            }
+            return type.getDescriptor().charAt(0);
+        }
+
+        @Override
+        public boolean equals(final Object other) {
+            if (other instanceof SpecializedRuntimeNode) {
+                final SpecializedRuntimeNode otherNode = (SpecializedRuntimeNode)other;
+
+                if (!otherNode.getReturnType().equals(getReturnType())) {
+                    return false;
+                }
+
+                if (getParameterTypes().length != otherNode.getParameterTypes().length) {
+                    return false;
+                }
+
+                for (int i = 0; i < getParameterTypes().length; i++) {
+                    if (!Type.areEquivalent(getParameterTypes()[i], otherNode.getParameterTypes()[i])) {
+                        return false;
+                    }
+                }
+
+                return otherNode.getRequest().equals(getRequest());
+            }
+
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            int hashCode = getRequest().toString().hashCode();
+            hashCode ^= getReturnType().hashCode();
+            for (final Type type : getParameterTypes()) {
+                hashCode ^= type.hashCode();
+            }
+            return hashCode;
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder sb = new StringBuilder();
+            sb.append(getRequest().toString());
+            sb.append(REQUEST_SEPARATOR);
+            sb.append(descFor(getReturnType()));
+
+            for (final Type type : getParameterTypes()) {
+                sb.append(descFor(type));
+            }
+
+            return sb.toString();
+        }
+
+        String getName(final Type extraType) {
+            return toString() + "_" + descFor(extraType);
+        }
+
+        String getInitialName() {
+            return getName(firstTypeGuess());
+        }
+    }
+
+
+    /**
+     * Constructor
+     *
+     * @param type method type for call site
+     * @param name name of runtime call
+     */
+    public RuntimeCallSite(final MethodType type, final String name) {
+        super(type);
+        this.name    = name;
+        this.request = Request.valueOf(name.substring(0, name.indexOf(SpecializedRuntimeNode.REQUEST_SEPARATOR)));
+        setTarget(makeMethod(name));
+    }
+
+    private String nextName(final String requestName) {
+        if (requestName.equals(request.toString())) {
+            return null;
+        }
+
+        final char[] c = requestName.toCharArray();
+        final int last = c.length - 1;
+
+        if (c[last - 1] != '_') {
+            return null;
+        }
+
+        switch (c[last]) {
+        case 'Z':
+            c[last] = 'I';
+            break;
+        case 'I':
+            c[last] = 'J';
+            break;
+        case 'J':
+            c[last] = 'D';
+            break;
+        case 'D':
+        default:
+            return request.toString();
+        }
+
+        return new String(c);
+    }
+
+    private boolean isSpecialized(final String requestName) {
+        return nextName(requestName) != null;
+    }
+
+    private MethodHandle makeMethod(final String requestName) {
+        MethodHandle mh;
+
+        if (isSpecialized(requestName)) {
+            final Class<?> boxedType;
+            final Class<?> primitiveType;
+
+            switch (requestName.charAt(requestName.length() - 1)) {
+            case 'Z':
+                boxedType = Boolean.class;
+                primitiveType = int.class;
+                break;
+            case 'I':
+                boxedType = Integer.class;
+                primitiveType = int.class;
+                break;
+            case 'J':
+                boxedType = Long.class;
+                primitiveType = long.class;
+                break;
+            case 'D':
+                boxedType = Number.class;
+                primitiveType = double.class;
+                break;
+            default:
+                throw new RuntimeException("should not reach here");
+            }
+
+            final boolean isStrictCmp = (request == Request.EQ_STRICT || request == Request.NE_STRICT);
+
+            if (isStrictCmp &&
+                    (boxedType != Boolean.class &&
+                        (type().parameterType(0) == boolean.class ||
+                         type().parameterType(1) == boolean.class))) {
+                // number and boolean are never strictly equal, e.g. 0 !== false
+                mh = MH.dropArguments(MH.constant(boolean.class, request == Request.NE_STRICT), 0, type().parameterArray());
+            } else {
+                mh = METHODS.get(request.nonStrictName() + primitiveType.getSimpleName());
+                // unbox objects
+
+                for (int i = 0; i < type().parameterCount(); i++) {
+                    if (!type().parameterType(i).isPrimitive()) {
+                        mh = MH.filterArguments(mh, i, UNBOX.get(boxedType));
+                    }
+                }
+
+                mh = Lookup.filterReturnType(mh, type().returnType());
+                mh = MH.explicitCastArguments(mh, type());
+            }
+
+            final MethodHandle fallback = MH.foldArguments(MethodHandles.exactInvoker(type()), MH.bindTo(NEXT, this));
+
+            MethodHandle guard;
+            if (type().parameterType(0).isPrimitive()) {
+                guard = MH.insertArguments(
+                            MH.dropArguments(CHECKCAST, 1, type().parameterType(0)), 0, boxedType);
+            } else if (type().parameterType(1).isPrimitive()) {
+                guard = MH.insertArguments(
+                            MH.dropArguments(CHECKCAST, 2, type().parameterType(1)), 0, boxedType);
+            } else {
+                assert !type().parameterType(0).isPrimitive() && !type().parameterType(1).isPrimitive();
+                guard = MH.insertArguments(CHECKCAST2, 0, boxedType);
+            }
+
+            if (request == Request.ADD && boxedType == Integer.class) {
+                // int add needs additional overflow check
+                MethodHandle addcheck = ADDCHECK;
+                for (int i = 0; i < type().parameterCount(); i++) {
+                    if (!type().parameterType(i).isPrimitive()) {
+                        addcheck = MH.filterArguments(addcheck, i, UNBOX.get(boxedType));
+                    }
+                }
+                addcheck = MH.explicitCastArguments(addcheck, type().changeReturnType(boolean.class));
+                guard    = MH.guardWithTest(upcastGuard(guard), addcheck,
+                                MH.dropArguments(MH.constant(boolean.class, false), 0, type().parameterArray()));
+            }
+
+            return MH.guardWithTest(upcastGuard(guard), mh, fallback);
+        }
+
+        // generic fallback
+        return MH.explicitCastArguments(Lookup.filterReturnType(GENERIC_METHODS.get(request.name()), type().returnType()), type());
+    }
+
+    private MethodHandle upcastGuard(final MethodHandle guard) {
+        return MH.asType(guard, type().changeReturnType(boolean.class));
+    }
+
+    /**
+     * This is public just so that the generated specialization code can
+     * use it to get the next wider typed method
+     *
+     * Do not call directly
+     *
+     * @return next wider specialization method for this RuntimeCallSite
+     */
+    public MethodHandle next() {
+        this.name = nextName(name);
+        final MethodHandle next = makeMethod(name);
+        setTarget(next);
+        return next;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " " + name;
+    }
+
+    /** Method cache */
+    private static final Map<String, MethodHandle> METHODS;
+
+    /** Generic method cache */
+    private static final Map<String, MethodHandle> GENERIC_METHODS;
+
+    /** Unbox cache */
+    private static final Map<Class<?>, MethodHandle> UNBOX;
+
+    private static final MethodHandle CHECKCAST  = findOwnMH("checkcast", boolean.class, Class.class, Object.class);
+    private static final MethodHandle CHECKCAST2 = findOwnMH("checkcast", boolean.class, Class.class, Object.class, Object.class);
+    private static final MethodHandle ADDCHECK   = findOwnMH("ADDcheck",  boolean.class, int.class, int.class);
+
+    /**
+     * Build maps of correct boxing operations
+     */
+    static {
+        UNBOX = new HashMap<>();
+        UNBOX.put(Boolean.class, findOwnMH("unboxZ", int.class, Object.class));
+        UNBOX.put(Integer.class, findOwnMH("unboxI", int.class, Object.class));
+        UNBOX.put(Long.class,    findOwnMH("unboxJ", long.class, Object.class));
+        UNBOX.put(Number.class,  findOwnMH("unboxD", double.class, Object.class));
+
+        METHODS = new HashMap<>();
+
+        for (final Request req : Request.values()) {
+            if (req.canSpecialize()) {
+                if (req.name().endsWith("_STRICT")) {
+                    continue;
+                }
+
+                final boolean isCmp = Request.isComparison(req);
+
+                METHODS.put(req.name() + "int",    findOwnMH(req.name(), (isCmp ? boolean.class : int.class),  int.class, int.class));
+                METHODS.put(req.name() + "long",   findOwnMH(req.name(), (isCmp ? boolean.class : long.class), long.class, long.class));
+                METHODS.put(req.name() + "double", findOwnMH(req.name(), (isCmp ? boolean.class : double.class), double.class, double.class));
+            }
+        }
+
+        GENERIC_METHODS = new HashMap<>();
+        for (final Request req : Request.values()) {
+            if (req.canSpecialize()) {
+                GENERIC_METHODS.put(req.name(), MH.findStatic(MethodHandles.lookup(), ScriptRuntime.class, req.name(),
+                        MH.type(req.getReturnType().getTypeClass(), Object.class, Object.class)));
+            }
+        }
+    }
+
+    /**
+     * Specialized version of != operator for two int arguments. Do not call directly.
+     * @param a int
+     * @param b int
+     * @return a != b
+     */
+    public static boolean NE(final int a, final int b) {
+        return a != b;
+    }
+
+    /**
+     * Specialized version of != operator for two double arguments. Do not call directly.
+     * @param a double
+     * @param b double
+     * @return a != b
+     */
+    public static boolean NE(final double a, final double b) {
+        return a != b;
+    }
+
+    /**
+     * Specialized version of != operator for two long arguments. Do not call directly.
+     * @param a long
+     * @param b long
+     * @return a != b
+     */
+    public static boolean NE(final long a, final long b) {
+        return a != b;
+    }
+
+    /**
+     * Specialized version of == operator for two int arguments. Do not call directly.
+     * @param a int
+     * @param b int
+     * @return a == b
+     */
+    public static boolean EQ(final int a, final int b) {
+        return a == b;
+    }
+
+    /**
+     * Specialized version of == operator for two double arguments. Do not call directly.
+     * @param a double
+     * @param b double
+     * @return a == b
+     */
+    public static boolean EQ(final double a, final double b) {
+        return a == b;
+    }
+
+    /**
+     * Specialized version of == operator for two long arguments. Do not call directly.
+     * @param a long
+     * @param b long
+     * @return a == b
+     */
+    public static boolean EQ(final long a, final long b) {
+        return a == b;
+    }
+
+    /**
+     * Specialized version of {@literal <} operator for two int arguments. Do not call directly.
+     * @param a int
+     * @param b int
+     * @return a {@code <} b
+     */
+    public static boolean LT(final int a, final int b) {
+        return a < b;
+    }
+
+    /**
+     * Specialized version of {@literal <} operator for two double arguments. Do not call directly.
+     * @param a double
+     * @param b double
+     * @return a {@literal <} b
+     */
+    public static boolean LT(final double a, final double b) {
+        return a < b;
+    }
+
+    /**
+     * Specialized version of {@literal <} operator for two long arguments. Do not call directly.
+     * @param a long
+     * @param b long
+     * @return a {@literal <} b
+     */
+    public static boolean LT(final long a, final long b) {
+        return a < b;
+    }
+
+    /**
+     * Specialized version of {@literal <=} operator for two int arguments. Do not call directly.
+     * @param a int
+     * @param b int
+     * @return a {@literal <=} b
+     */
+    public static boolean LE(final int a, final int b) {
+        return a <= b;
+    }
+
+    /**
+     * Specialized version of {@literal <=} operator for two double arguments. Do not call directly.
+     * @param a double
+     * @param b double
+     * @return a {@literal <=} b
+     */
+    public static boolean LE(final double a, final double b) {
+        return a <= b;
+    }
+
+    /**
+     * Specialized version of {@literal <=} operator for two long arguments. Do not call directly.
+     * @param a long
+     * @param b long
+     * @return a {@literal <=} b
+     */
+    public static boolean LE(final long a, final long b) {
+        return a <= b;
+    }
+
+    /**
+     * Specialized version of {@literal >} operator for two int arguments. Do not call directly.
+     * @param a int
+     * @param b int
+     * @return a {@literal >} b
+     */
+    public static boolean GT(final int a, final int b) {
+        return a > b;
+    }
+
+    /**
+     * Specialized version of {@literal >} operator for two double arguments. Do not call directly.
+     * @param a double
+     * @param b double
+     * @return a {@literal >} b
+     */
+    public static boolean GT(final double a, final double b) {
+        return a > b;
+    }
+
+    /**
+     * Specialized version of {@literal >} operator for two long arguments. Do not call directly.
+     * @param a long
+     * @param b long
+     * @return a {@literal >} b
+     */
+    public static boolean GT(final long a, final long b) {
+        return a > b;
+    }
+
+    /**
+     * Specialized version of {@literal >=} operator for two int arguments. Do not call directly.
+     * @param a int
+     * @param b int
+     * @return a {@literal >=} b
+     */
+    public static boolean GE(final int a, final int b) {
+        return a >= b;
+    }
+
+    /**
+     * Specialized version of {@literal >=} operator for two double arguments. Do not call directly.
+     * @param a double
+     * @param b double
+     * @return a {@literal >=} b
+     */
+    public static boolean GE(final double a, final double b) {
+        return a >= b;
+    }
+
+    /**
+     * Specialized version of {@literal >=} operator for two long arguments. Do not call directly.
+     * @param a long
+     * @param b long
+     * @return a {@code >=} b
+     */
+    public static boolean GE(final long a, final long b) {
+        return a >= b;
+    }
+
+    /**
+     * Specialized version of + operator for two int arguments. Do not call directly.
+     * @param a int
+     * @param b int
+     * @return a + b
+     */
+    public static int ADD(final int a, final int b) {
+        return a + b;
+    }
+
+    /**
+     * Specialized version of + operator for two long arguments. Do not call directly.
+     * @param a long
+     * @param b long
+     * @return a + b
+     */
+    public static long ADD(final long a, final long b) {
+        return a + b;
+    }
+
+    /**
+     * Specialized version of + operator for two double arguments. Do not call directly.
+     * @param a double
+     * @param b double
+     * @return a + b
+     */
+    public static double ADD(final double a, final double b) {
+        return a + b;
+    }
+
+    /**
+     * Check that ints are addition compatible, i.e. their sum is equal to the sum
+     * of them cast to long. Otherwise the addition will overflow. Do not call directly.
+     *
+     * @param a int
+     * @param b int
+     *
+     * @return true if addition does not overflow
+     */
+    public static boolean ADDcheck(final int a, final int b) {
+        return (a + b == (long)a + (long)b);
+    }
+
+    /**
+     * Checkcast used for specialized ops. Do not call directly
+     *
+     * @param type to to check against
+     * @param obj  object to check for type
+     *
+     * @return true if type check holds
+     */
+    public static boolean checkcast(final Class<?> type, final Object obj) {
+        return type.isInstance(obj);
+    }
+
+    /**
+     * Checkcast used for specialized ops. Do not call directly
+     *
+     * @param type type to check against
+     * @param objA first object to check against type
+     * @param objB second object to check against type
+     *
+     * @return true if type check holds for both objects
+     */
+    public static boolean checkcast(final Class<?> type, final Object objA, final Object objB) {
+        return type.isInstance(objA) && type.isInstance(objB);
+    }
+
+    /**
+     * Unbox a java.lang.Boolean. Do not call directly
+     * @param obj object to cast to int and unbox
+     * @return an int value for the boolean, 1 is true, 0 is false
+     */
+    public static int unboxZ(final Object obj) {
+        return (boolean)obj ? 1 : 0;
+    }
+
+    /**
+     * Unbox a java.lang.Integer. Do not call directly
+     * @param obj object to cast to int and unbox
+     * @return an int
+     */
+    public static int unboxI(final Object obj) {
+        return (int)obj;
+    }
+
+    /**
+     * Unbox a java.lang.Long. Do not call directly
+     * @param obj object to cast to long and unbox
+     * @return a long
+     */
+    public static long unboxJ(final Object obj) {
+        return (long)obj;
+    }
+
+    /**
+     * Unbox a java.lang.Number. Do not call directly
+     * @param obj object to cast to Number and unbox
+     * @return a double
+     */
+    public static double unboxD(final Object obj) {
+        return ((Number)obj).doubleValue();
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        try {
+            return MH.findStatic(MethodHandles.lookup(), RuntimeCallSite.class, name, MH.type(rtype, types));
+        } catch (final MethodHandleFactory.LookupException e) {
+            return MH.findVirtual(MethodHandles.lookup(), RuntimeCallSite.class, name, MH.type(rtype, types));
+        }
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java b/nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java
new file mode 100644
index 0000000..588e2f4
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java
@@ -0,0 +1,194 @@
+/*
+ * 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.codegen;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * A scope call or get operation that can be shared by several callsites. This generates a static
+ * method that wraps the invokedynamic instructions to get or call scope variables.
+ * The rationale for this is that initial linking of invokedynamic callsites is expensive,
+ * so by sharing them we can reduce startup overhead and allow very large scripts to run that otherwise wouldn't.
+ *
+ * <p>Static methods generated by this class expect two parameters in addition to the parameters of the
+ * function call: The current scope object and the depth of the target scope relative to the scope argument
+ * for when this is known at compile-time (fast-scope access).</p>
+ *
+ * <p>The second argument may be -1 for non-fast-scope symbols, in which case the scope chain is checked
+ * for each call. This may cause callsite invalidation when the shared method is used from different
+ * scopes, but such sharing of non-fast scope calls may still be necessary for very large scripts.</p>
+ *
+ * <p>Scope calls must not be shared between normal callsites and callsites contained in a <tt>with</tt>
+ * statement as this condition is not handled by current guards and will cause a runtime error.</p>
+ */
+class SharedScopeCall {
+
+    /** Threshold for using shared scope calls with fast scope access. */
+    public static final int FAST_SCOPE_CALL_THRESHOLD = 4;
+    /** Threshold for using shared scope calls with slow scope access. */
+    public static final int SLOW_SCOPE_CALL_THRESHOLD = 500;
+    /** Threshold for using shared scope gets with fast scope access. */
+    public static final int FAST_SCOPE_GET_THRESHOLD  = 200;
+
+    final Type valueType;
+    final Symbol symbol;
+    final Type returnType;
+    final Type[] paramTypes;
+    final int flags;
+    final boolean isCall;
+    private CompileUnit compileUnit;
+    private String methodName;
+    private String staticSignature;
+
+    /**
+     * Constructor.
+     *
+     * @param symbol the symbol
+     * @param valueType the type of the value
+     * @param returnType the return type
+     * @param paramTypes the function parameter types
+     * @param flags the callsite flags
+     */
+    SharedScopeCall(final Symbol symbol, final Type valueType, final Type returnType, final Type[] paramTypes, final int flags) {
+        this.symbol = symbol;
+        this.valueType = valueType;
+        this.returnType = returnType;
+        this.paramTypes = paramTypes;
+        this.flags = flags;
+        // If paramTypes is not null this is a call, otherwise it's just a get.
+        this.isCall = paramTypes != null;
+    }
+
+    @Override
+    public int hashCode() {
+        return symbol.hashCode() ^ returnType.hashCode() ^ Arrays.hashCode(paramTypes) ^ flags;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj instanceof SharedScopeCall) {
+            final SharedScopeCall c = (SharedScopeCall) obj;
+            return symbol.equals(c.symbol)
+                    && flags == c.flags
+                    && returnType.equals(c.returnType)
+                    && Arrays.equals(paramTypes, c.paramTypes);
+        }
+        return false;
+    }
+
+    /**
+     * Set the compile unit and method name.
+     * @param compileUnit the compile unit
+     * @param methodName the method name
+     */
+    protected void setClassAndName(final CompileUnit compileUnit, final String methodName) {
+        this.compileUnit = compileUnit;
+        this.methodName  = methodName;
+    }
+
+    /**
+     * Generate the invoke instruction for this shared scope call.
+     * @param method the method emitter
+     */
+    public void generateInvoke(final MethodEmitter method) {
+        method.invokestatic(compileUnit.getUnitClassName(), methodName, getStaticSignature());
+    }
+
+    /**
+     * Generate the method that implements the scope get or call.
+     */
+    protected void generateScopeCall() {
+        final ClassEmitter classEmitter = compileUnit.getClassEmitter();
+        final EnumSet<ClassEmitter.Flag> methodFlags = EnumSet.of(ClassEmitter.Flag.STATIC);
+
+        // This method expects two fixed parameters in addition to any parameters that may be
+        // passed on to the function: A ScriptObject representing the caller's current scope object,
+        // and an int specifying the distance to the target scope containing the symbol we want to
+        // access, or -1 if this is not known at compile time (e.g. because of a "with" or "eval").
+
+        final MethodEmitter method = classEmitter.method(methodFlags, methodName, getStaticSignature());
+        method.begin();
+
+        // Load correct scope by calling getProto() on the scope argument as often as specified
+        // by the second argument.
+        final Label parentLoopStart = new Label("parent_loop_start");
+        final Label parentLoopDone  = new Label("parent_loop_done");
+        method.load(Type.OBJECT, 0);
+        method.label(parentLoopStart);
+        method.load(Type.INT, 1);
+        method.iinc(1, -1);
+        method.ifle(parentLoopDone);
+        method.invoke(ScriptObject.GET_PROTO);
+        method._goto(parentLoopStart);
+        method.label(parentLoopDone);
+
+        method.dynamicGet(valueType, symbol.getName(), flags, isCall);
+
+        // If this is a get we're done, otherwise call the value as function.
+        if (isCall) {
+            method.convert(Type.OBJECT);
+            // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
+            method.loadNull();
+            int slot = 2;
+            for (final Type type : paramTypes) {
+                method.load(type, slot++);
+                if (type == Type.NUMBER || type == Type.LONG) {
+                    slot++;
+                }
+            }
+            method.dynamicCall(returnType, 2 + paramTypes.length, flags);
+        }
+
+        method._return(returnType);
+        method.end();
+    }
+
+    private String getStaticSignature() {
+        if (staticSignature == null) {
+            if (paramTypes == null) {
+                staticSignature = Type.getMethodDescriptor(returnType, Type.typeFor(ScriptObject.class), Type.INT);
+            } else {
+                final Type[] params = new Type[paramTypes.length + 2];
+                params[0] = Type.typeFor(ScriptObject.class);
+                params[1] = Type.INT;
+                int i = 2;
+                for (Type type : paramTypes)  {
+                    if (type.isObject()) {
+                        type = Type.OBJECT;
+                    }
+                    params[i++] = type;
+                }
+                staticSignature = Type.getMethodDescriptor(returnType, params);
+            }
+        }
+        return staticSignature;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java
new file mode 100644
index 0000000..b92f238
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java
@@ -0,0 +1,417 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
+
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BreakNode;
+import jdk.nashorn.internal.ir.ContinueNode;
+import jdk.nashorn.internal.ir.DoWhileNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.LabelNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.WhileNode;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Split the IR into smaller compile units.
+ */
+final class Splitter extends NodeVisitor {
+    /** Current compiler. */
+    private final Compiler compiler;
+
+    /** IR to be broken down. */
+    private final FunctionNode functionNode;
+
+    /** Compile unit for the main script. */
+    private final CompileUnit outermostCompileUnit;
+
+    /** Cache for calculated block weights. */
+    private final Map<Node, Long> weightCache = new HashMap<>();
+
+    /** Weight threshold for when to start a split. */
+    public static final long SPLIT_THRESHOLD = Options.getIntProperty("nashorn.compiler.splitter.threshold", 32 * 1024);
+
+    private static final DebugLogger LOG = Compiler.LOG;
+
+    /**
+     * Constructor.
+     *
+     * @param compiler              the compiler
+     * @param functionNode          function node to split
+     * @param outermostCompileUnit  compile unit for outermost function, if non-lazy this is the script's compile unit
+     */
+    public Splitter(final Compiler compiler, final FunctionNode functionNode, final CompileUnit outermostCompileUnit) {
+        this.compiler             = compiler;
+        this.functionNode         = functionNode;
+        this.outermostCompileUnit = outermostCompileUnit;
+    }
+
+    /**
+     * Execute the split
+     */
+    void split() {
+        if (functionNode.isLazy()) {
+            LOG.fine("Postponing split of '" + functionNode.getName() + "' as it's lazy");
+            return;
+        }
+        LOG.fine("Initiating split of '" + functionNode.getName() + "'");
+
+        long weight = WeighNodes.weigh(functionNode);
+
+        if (weight >= SPLIT_THRESHOLD) {
+            LOG.fine("Splitting '" + functionNode.getName() + "' as its weight " + weight + " exceeds split threshold " + SPLIT_THRESHOLD);
+
+            functionNode.accept(this);
+
+            if (functionNode.isSplit()) {
+                // Weight has changed so weigh again, this time using block weight cache
+                weight = WeighNodes.weigh(functionNode, weightCache);
+            }
+
+            if (weight >= SPLIT_THRESHOLD) {
+                weight = splitBlock(functionNode);
+            }
+
+            if (functionNode.isSplit()) {
+                functionNode.accept(new SplitFlowAnalyzer());
+            }
+        }
+
+        assert functionNode.getCompileUnit() == null : "compile unit already set";
+
+        if (compiler.getFunctionNode() == functionNode) { //functionNode.isScript()) {
+            assert outermostCompileUnit != null : "outermost compile unit is null";
+
+            functionNode.setCompileUnit(outermostCompileUnit);
+            outermostCompileUnit.addWeight(weight + WeighNodes.FUNCTION_WEIGHT);
+        } else {
+            functionNode.setCompileUnit(findUnit(weight));
+        }
+
+        // Recursively split nested functions
+        for (final FunctionNode function : functionNode.getFunctions()) {
+            new Splitter(compiler, function, outermostCompileUnit).split();
+        }
+    }
+
+    /**
+     * Override this logic to look up compile units in a different way
+     * @param weight weight needed
+     * @return compile unit
+     */
+    protected CompileUnit findUnit(final long weight) {
+        return compiler.findUnit(weight);
+    }
+
+    /**
+     * Split a block into sub methods.
+     *
+     * @param block Block or function to split.
+     *
+     * @return new weight for the resulting block.
+     */
+    private long splitBlock(final Block block) {
+        functionNode.setIsSplit();
+
+        final List<Node> splits = new ArrayList<>();
+        List<Node> statements = new ArrayList<>();
+        long statementsWeight = 0;
+
+        for (final Node statement : block.getStatements()) {
+            final long weight = WeighNodes.weigh(statement, weightCache);
+
+            if (statementsWeight + weight >= SPLIT_THRESHOLD || statement.isTerminal()) {
+                if (!statements.isEmpty()) {
+                    splits.add(createBlockSplitNode(block, statements, statementsWeight));
+                    statements = new ArrayList<>();
+                    statementsWeight = 0;
+                }
+
+            }
+
+            if (statement.isTerminal()) {
+                splits.add(statement);
+            } else {
+                statements.add(statement);
+                statementsWeight += weight;
+            }
+        }
+
+        if (!statements.isEmpty()) {
+            splits.add(createBlockSplitNode(block, statements, statementsWeight));
+        }
+
+        block.setStatements(splits);
+
+        return WeighNodes.weigh(block, weightCache);
+    }
+
+    /**
+     * Create a new split node from statements contained in a parent block.
+     *
+     * @param parent     Parent block.
+     * @param statements Statements to include.
+     *
+     * @return New split node.
+     */
+    private SplitNode createBlockSplitNode(final Block parent, final List<Node> statements, final long weight) {
+        final Source source = parent.getSource();
+        final long   token  = parent.getToken();
+        final int    finish = parent.getFinish();
+        final String name   = parent.getFunction().uniqueName(SPLIT_PREFIX.tag());
+
+        final Block newBlock = new Block(source, token, finish, parent, functionNode);
+        newBlock.setFrame(new Frame(parent.getFrame()));
+        newBlock.setStatements(statements);
+
+        final SplitNode splitNode = new SplitNode(name, functionNode, newBlock);
+
+        splitNode.setCompileUnit(compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT));
+
+        return splitNode;
+    }
+
+    @Override
+    public Node enter(final Block block) {
+        if (block.isCatchBlock()) {
+            return null;
+        }
+
+        final long weight = WeighNodes.weigh(block, weightCache);
+
+        if (weight < SPLIT_THRESHOLD) {
+            weightCache.put(block, weight);
+            return null;
+        }
+
+        return block;
+    }
+
+    @Override
+    public Node leave(final Block block) {
+        assert !block.isCatchBlock();
+
+        // Block was heavier than SLIT_THRESHOLD in enter, but a sub-block may have
+        // been split already, so weigh again before splitting.
+        long weight = WeighNodes.weigh(block, weightCache);
+        if (weight >= SPLIT_THRESHOLD) {
+            weight = splitBlock(block);
+        }
+        weightCache.put(block, weight);
+
+        return block;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Node leave(final LiteralNode literal) {
+        long weight = WeighNodes.weigh(literal);
+
+        if (weight < SPLIT_THRESHOLD) {
+            return literal;
+        }
+
+        functionNode.setIsSplit();
+
+        if (literal instanceof ArrayLiteralNode) {
+            final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode) literal;
+            final Node[]           value            = arrayLiteralNode.getValue();
+            final int[]            postsets         = arrayLiteralNode.getPostsets();
+            final List<ArrayUnit>  units            = new ArrayList<>();
+
+            long totalWeight = 0;
+            int  lo          = 0;
+
+            for (int i = 0; i < postsets.length; i++) {
+                final int  postset = postsets[i];
+                final Node element = value[postset];
+
+                weight = WeighNodes.weigh(element);
+                totalWeight += weight;
+
+                if (totalWeight >= SPLIT_THRESHOLD) {
+                    final CompileUnit unit = compiler.findUnit(totalWeight - weight);
+                    units.add(new ArrayUnit(unit, lo, i));
+                    lo = i;
+                    totalWeight = weight;
+                }
+            }
+
+            if (lo != postsets.length) {
+                final CompileUnit unit = compiler.findUnit(totalWeight);
+                units.add(new ArrayUnit(unit, lo, postsets.length));
+            }
+
+            arrayLiteralNode.setUnits(units);
+        }
+
+        return literal;
+    }
+
+    @Override
+    public Node enter(final FunctionNode node) {
+        if (node.isLazy()) {
+            return null;
+        }
+
+        final List<Node> statements = node.getStatements();
+
+        for (final Node statement : statements) {
+            statement.accept(this);
+        }
+
+        return null;
+    }
+
+    static class SplitFlowAnalyzer extends NodeVisitor {
+
+        /** Stack of visited Split nodes, deepest node first. */
+        private final Deque<SplitNode> splitStack;
+
+        /** Map of possible jump targets to containing split node */
+        private final Map<Node,SplitNode> targetNodes = new HashMap<>();
+
+        SplitFlowAnalyzer() {
+            this.splitStack = new LinkedList<>();
+        }
+
+        @Override
+        public Node enter(final LabelNode labelNode) {
+            registerJumpTarget(labelNode.getBreakNode());
+            registerJumpTarget(labelNode.getContinueNode());
+            return labelNode;
+        }
+
+        @Override
+        public Node enter(final WhileNode whileNode) {
+            registerJumpTarget(whileNode);
+            return whileNode;
+        }
+
+        @Override
+        public Node enter(final DoWhileNode doWhileNode) {
+            registerJumpTarget(doWhileNode);
+            return doWhileNode;
+        }
+
+        @Override
+        public Node enter(final ForNode forNode) {
+            registerJumpTarget(forNode);
+            return forNode;
+        }
+
+        @Override
+        public Node enter(final SwitchNode switchNode) {
+            registerJumpTarget(switchNode);
+            return switchNode;
+        }
+
+        @Override
+        public Node enter(final ReturnNode returnNode) {
+            for (final SplitNode split : splitStack) {
+                split.setHasReturn(true);
+            }
+            return returnNode;
+        }
+
+        @Override
+        public Node enter(final ContinueNode continueNode) {
+            searchJumpTarget(continueNode.getTargetNode(), continueNode.getTargetLabel());
+            return continueNode;
+        }
+
+        @Override
+        public Node enter(final BreakNode breakNode) {
+            searchJumpTarget(breakNode.getTargetNode(), breakNode.getTargetLabel());
+            return breakNode;
+        }
+
+        @Override
+        public Node enter(final SplitNode splitNode) {
+            splitStack.addFirst(splitNode);
+            return splitNode;
+        }
+
+        @Override
+        public Node leave(final SplitNode splitNode) {
+            assert splitNode == splitStack.peekFirst();
+            splitStack.removeFirst();
+            return splitNode;
+        }
+
+        /**
+         * Register the split node containing a potential jump target.
+         * @param targetNode a potential target node.
+         */
+        private void registerJumpTarget(final Node targetNode) {
+            final SplitNode splitNode = splitStack.peekFirst();
+            if (splitNode != null) {
+                targetNodes.put(targetNode, splitNode);
+            }
+        }
+
+        /**
+         * Check if a jump target is outside the current split node and its parent split nodes.
+         * @param targetNode the jump target node.
+         * @param targetLabel the jump target label.
+         */
+        private void searchJumpTarget(final Node targetNode, final Label targetLabel) {
+
+            final SplitNode targetSplit = targetNodes.get(targetNode);
+            // Note that targetSplit may be null, indicating that targetNode is in top level method.
+            // In this case we have to add the external jump target to all split nodes.
+
+            for (final SplitNode split : splitStack) {
+                if (split == targetSplit) {
+                    break;
+                }
+                final List<Label> externalTargets = split.getExternalTargets();
+                if (!externalTargets.contains(targetLabel)) {
+                    split.addExternalTarget(targetLabel);
+                }
+            }
+        }
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java b/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java
new file mode 100644
index 0000000..9f2e8be
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java
@@ -0,0 +1,567 @@
+/*
+ * 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.codegen;
+
+import java.util.List;
+import java.util.Map;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BreakNode;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ContinueNode;
+import jdk.nashorn.internal.ir.DoWhileNode;
+import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.IndexNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.PropertyNode;
+import jdk.nashorn.internal.ir.ReferenceNode;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.ThrowNode;
+import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.WhileNode;
+import jdk.nashorn.internal.ir.WithNode;
+import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
+
+
+/**
+ * Computes the "byte code" weight of an AST segment. This is used
+ * for Splitting too large class files
+ */
+final class WeighNodes extends NodeOperatorVisitor {
+    /*
+     * Weight constants.
+     */
+            static final long FUNCTION_WEIGHT  = 40;
+    private static final long ACCESS_WEIGHT    = 4;
+    private static final long ADD_WEIGHT       = 10;
+    private static final long BREAK_WEIGHT     = 1;
+    private static final long CALL_WEIGHT      = 10;
+    private static final long CATCH_WEIGHT     = 10;
+    private static final long CONTINUE_WEIGHT  = 1;
+    private static final long IF_WEIGHT        = 2;
+    private static final long LITERAL_WEIGHT   = 10;
+    private static final long LOOP_WEIGHT      = 4;
+    private static final long NEW_WEIGHT       = 6;
+    private static final long REFERENCE_WEIGHT = 20;
+    private static final long RETURN_WEIGHT    = 2;
+    private static final long SPLIT_WEIGHT     = 40;
+    private static final long SWITCH_WEIGHT    = 8;
+    private static final long THROW_WEIGHT     = 2;
+    private static final long VAR_WEIGHT       = 40;
+    private static final long WITH_WEIGHT      = 8;
+
+    /** Accumulated weight. */
+    private long weight;
+
+    /** Optional cache for weight of block nodes. */
+    private final Map<Node, Long> weightCache;
+
+    /*
+     * Constructor
+     *
+     * @param weightCache cache of already calculated block weights
+     */
+    private WeighNodes(final Map<Node, Long> weightCache) {
+        super(null, null);
+        this.weightCache = weightCache;
+    }
+
+    static long weigh(final Node node) {
+        final WeighNodes weighNodes = new WeighNodes(null);
+        node.accept(weighNodes);
+        return weighNodes.weight;
+    }
+
+    static long weigh(final Node node, final Map<Node, Long> weightCache) {
+        final WeighNodes weighNodes = new WeighNodes(weightCache);
+        node.accept(weighNodes);
+        return weighNodes.weight;
+    }
+
+    @Override
+    public Node leave(final AccessNode accessNode) {
+        weight += ACCESS_WEIGHT;
+        return accessNode;
+    }
+
+    @Override
+    public Node enter(final Block block) {
+        if (weightCache != null && weightCache.containsKey(block)) {
+            weight += weightCache.get(block);
+            return null;
+        }
+
+        return block;
+    }
+
+    @Override
+    public Node leave(final BreakNode breakNode) {
+        weight += BREAK_WEIGHT;
+        return breakNode;
+    }
+
+    @Override
+    public Node leave(final CallNode callNode) {
+        weight += CALL_WEIGHT;
+        return callNode;
+    }
+
+    @Override
+    public Node leave(final CatchNode catchNode) {
+        weight += CATCH_WEIGHT;
+        return catchNode;
+    }
+
+    @Override
+    public Node leave(final ContinueNode continueNode) {
+        weight += CONTINUE_WEIGHT;
+        return continueNode;
+    }
+
+    @Override
+    public Node leave(final DoWhileNode doWhileNode) {
+        weight += LOOP_WEIGHT;
+        return doWhileNode;
+    }
+
+    @Override
+    public Node leave(final ExecuteNode executeNode) {
+        return executeNode;
+    }
+
+    @Override
+    public Node leave(final ForNode forNode) {
+        weight += LOOP_WEIGHT;
+        return forNode;
+    }
+
+    @Override
+    public Node enter(final FunctionNode functionNode) {
+        final List<Node> statements = functionNode.getStatements();
+
+        for (final Node statement : statements) {
+            statement.accept(this);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node leave(final IdentNode identNode) {
+        weight += ACCESS_WEIGHT + identNode.getName().length() * 2;
+        return identNode;
+    }
+
+    @Override
+    public Node leave(final IfNode ifNode) {
+        weight += IF_WEIGHT;
+        return ifNode;
+    }
+
+    @Override
+    public Node leave(final IndexNode indexNode) {
+        weight += ACCESS_WEIGHT;
+        return indexNode;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Node enter(final LiteralNode literalNode) {
+        weight += LITERAL_WEIGHT;
+
+        if (literalNode instanceof ArrayLiteralNode) {
+            final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode;
+            final Node[]           value            = arrayLiteralNode.getValue();
+            final int[]            postsets         = arrayLiteralNode.getPostsets();
+            final List<ArrayUnit>  units            = arrayLiteralNode.getUnits();
+
+            if (units == null) {
+                for (final int postset : postsets) {
+                    final Node element = value[postset];
+
+                    if (element != null) {
+                        element.accept(this);
+                    }
+                }
+            }
+
+            return null;
+        }
+
+        return literalNode;
+    }
+
+    @Override
+    public Node leave(final PropertyNode propertyNode) {
+        weight += LITERAL_WEIGHT;
+        return propertyNode;
+    }
+
+    @Override
+    public Node leave(final ReferenceNode referenceNode) {
+        weight += REFERENCE_WEIGHT;
+        return referenceNode;
+    }
+
+    @Override
+    public Node leave(final ReturnNode returnNode) {
+        weight += RETURN_WEIGHT;
+        return returnNode;
+    }
+
+    @Override
+    public Node leave(final RuntimeNode runtimeNode) {
+        weight += CALL_WEIGHT;
+        return runtimeNode;
+    }
+
+    @Override
+    public Node enter(final SplitNode splitNode) {
+        weight += SPLIT_WEIGHT;
+        return null;
+    }
+
+    @Override
+    public Node leave(final SwitchNode switchNode) {
+        weight += SWITCH_WEIGHT;
+        return switchNode;
+    }
+
+    @Override
+    public Node leave(final ThrowNode throwNode) {
+        weight += THROW_WEIGHT;
+        return throwNode;
+    }
+
+    @Override
+    public Node leave(final TryNode tryNode) {
+        weight += THROW_WEIGHT;
+        return tryNode;
+    }
+
+    @Override
+    public Node leave(final VarNode varNode) {
+        weight += VAR_WEIGHT;
+        return varNode;
+    }
+
+    @Override
+    public Node leave(final WhileNode whileNode) {
+        weight += LOOP_WEIGHT;
+        return whileNode;
+    }
+
+    @Override
+    public Node leave(final WithNode withNode) {
+        weight += WITH_WEIGHT;
+        return withNode;
+    }
+
+    @Override
+    public Node leaveADD(final UnaryNode unaryNode) {
+        return unaryNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveBIT_NOT(final UnaryNode unaryNode) {
+        return unaryNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveCONVERT(final UnaryNode unaryNode) {
+        return unaryNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveDECINC(final UnaryNode unaryNode) {
+         return unaryNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveDELETE(final UnaryNode unaryNode) {
+        return runtimeNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveDISCARD(final UnaryNode unaryNode) {
+        return unaryNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveNEW(final UnaryNode unaryNode) {
+        weight += NEW_WEIGHT;
+        return unaryNode;
+    }
+
+    @Override
+    public Node leaveNOT(final UnaryNode unaryNode) {
+        return unaryNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveSUB(final UnaryNode unaryNode) {
+        return unaryNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveTYPEOF(final UnaryNode unaryNode) {
+        return runtimeNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveVOID(final UnaryNode unaryNode) {
+        return unaryNodeWeight(unaryNode);
+    }
+
+    @Override
+    public Node leaveADD(final BinaryNode binaryNode) {
+        weight += ADD_WEIGHT;
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveAND(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_ADD(final BinaryNode binaryNode) {
+        weight += ADD_WEIGHT;
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveASSIGN_BIT_AND(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_BIT_OR(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_DIV(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_MOD(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_MUL(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SAR(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SHL(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SHR(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveASSIGN_SUB(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveBIND(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveBIT_AND(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveBIT_OR(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveBIT_XOR(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveCOMMARIGHT(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveDIV(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveEQ(final BinaryNode binaryNode) {
+        return runtimeNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveEQ_STRICT(final BinaryNode binaryNode) {
+        return runtimeNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveGE(final BinaryNode binaryNode) {
+        return runtimeNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveGT(final BinaryNode binaryNode) {
+        return runtimeNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveIN(final BinaryNode binaryNode) {
+        weight += CALL_WEIGHT;
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveINSTANCEOF(final BinaryNode binaryNode) {
+        weight += CALL_WEIGHT;
+        return binaryNode;
+    }
+
+    @Override
+    public Node leaveLE(final BinaryNode binaryNode) {
+        return runtimeNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveLT(final BinaryNode binaryNode) {
+        return runtimeNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveMOD(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveMUL(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveNE(final BinaryNode binaryNode) {
+        return runtimeNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveNE_STRICT(final BinaryNode binaryNode) {
+        return runtimeNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveOR(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveSAR(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveSHL(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveSHR(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    @Override
+    public Node leaveSUB(final BinaryNode binaryNode) {
+        return binaryNodeWeight(binaryNode);
+    }
+
+    private Node unaryNodeWeight(final UnaryNode unaryNode) {
+        weight += 1;
+        return unaryNode;
+    }
+
+    private Node binaryNodeWeight(final BinaryNode binaryNode) {
+        weight += 1;
+        return binaryNode;
+    }
+
+    private Node runtimeNodeWeight(final UnaryNode unaryNode) {
+        weight += CALL_WEIGHT;
+        return unaryNode;
+    }
+
+    private Node runtimeNodeWeight(final BinaryNode binaryNode) {
+        weight += Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType()).isObject() ? CALL_WEIGHT : 1;
+        return binaryNode;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/ArrayType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/ArrayType.java
new file mode 100644
index 0000000..b6701df
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/ArrayType.java
@@ -0,0 +1,107 @@
+/*
+ * 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.codegen.types;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.AALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.AASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.ANEWARRAY;
+import static jdk.internal.org.objectweb.asm.Opcodes.ARRAYLENGTH;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+
+/**
+ * This is an array type, i.e. OBJECT_ARRAY, NUMBER_ARRAY.
+ */
+public class ArrayType extends ObjectType implements BytecodeArrayOps {
+
+    /**
+     * Constructor
+     *
+     * @param clazz the Java class representation of the array
+     */
+    protected ArrayType(final Class<?> clazz) {
+        super(clazz);
+    }
+
+    /**
+     * Get the element type of the array elements e.g. for OBJECT_ARRAY, this is OBJECT
+     *
+     * @return the element type
+     */
+    public Type getElementType() {
+        return Type.typeFor(getTypeClass().getComponentType());
+    }
+
+    @Override
+    public void astore(final MethodVisitor method) {
+        method.visitInsn(AASTORE);
+    }
+
+    @Override
+    public Type aload(final MethodVisitor method) {
+        method.visitInsn(AALOAD);
+        return getElementType();
+    }
+
+    @Override
+    public Type arraylength(final MethodVisitor method) {
+        method.visitInsn(ARRAYLENGTH);
+        return INT;
+    }
+
+    @Override
+    public Type newarray(final MethodVisitor method) {
+        method.visitTypeInsn(ANEWARRAY, getElementType().getInternalName());
+        return this;
+    }
+
+    @Override
+    public Type newarray(final MethodVisitor method, final int dims) {
+        method.visitMultiANewArrayInsn(getInternalName(), dims);
+        return this;
+    }
+
+    @Override
+    public Type load(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(ALOAD, slot);
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "array<elementType=" + getElementType().getTypeClass().getSimpleName() + '>';
+    }
+
+    @Override
+    public Type convert(final MethodVisitor method, final Type to) {
+        assert to.isObject();
+        assert !to.isArray() || ((ArrayType)to).getElementType() == getElementType();
+        return to;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/BitwiseType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/BitwiseType.java
new file mode 100644
index 0000000..dbd0aa1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/BitwiseType.java
@@ -0,0 +1,44 @@
+/*
+ * 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.codegen.types;
+
+/**
+ * This class represents a numeric type that can be used for bit operations.
+ */
+public abstract class BitwiseType extends NumericType implements BytecodeBitwiseOps {
+
+    /**
+     * Constructor
+     *
+     * @param name   name of type
+     * @param clazz  Java class used to represent type
+     * @param weight weight of type
+     * @param slots  number of bytecode slots this type takes up
+     */
+    protected BitwiseType(final String name, final Class<?> clazz, final int weight, final int slots) {
+        super(name, clazz, weight, slots);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java
new file mode 100644
index 0000000..c27c058
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.codegen.types;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1;
+import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.ISTORE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.nashorn.internal.codegen.CompilerConstants;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.runtime.JSType;
+
+/**
+ * The boolean type class
+ */
+public final class BooleanType extends Type {
+
+    private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Boolean.class, "valueOf", Boolean.class, boolean.class);
+
+    /**
+     * Constructor
+     */
+    protected BooleanType() {
+        super("boolean", boolean.class, 1, 1);
+    }
+
+    @Override
+    public Type nextWider() {
+        return INT;
+    }
+
+    @Override
+    public Class<?> getBoxedType() {
+        return Boolean.class;
+    }
+
+    @Override
+    public Type loadUndefined(final MethodVisitor method) {
+        method.visitLdcInsn(ObjectClassGenerator.UNDEFINED_INT);
+        return BOOLEAN;
+    }
+
+    @Override
+    public Type loadEmpty(final MethodVisitor method) {
+        assert false : "unsupported operation";
+        return null;
+    }
+
+    @Override
+    public void _return(final MethodVisitor method) {
+        method.visitInsn(IRETURN);
+    }
+
+    @Override
+    public Type load(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(ILOAD, slot);
+        return BOOLEAN;
+    }
+
+    @Override
+    public void store(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(ISTORE, slot);
+    }
+
+    @Override
+    public Type ldc(final MethodVisitor method, final Object c) {
+        assert c instanceof Boolean;
+        method.visitInsn((Boolean) c ? ICONST_1 : ICONST_0);
+        return BOOLEAN;
+    }
+
+    @Override
+    public Type convert(final MethodVisitor method, final Type to) {
+        if (isEquivalentTo(to)) {
+            return to;
+        }
+
+        if (to.isNumber()) {
+            convert(method, OBJECT);
+            invokeStatic(method, JSType.TO_NUMBER);
+        } else if (to.isInteger()) {
+            return to; // do nothing.
+        } else if (to.isLong()) {
+            convert(method, OBJECT);
+            invokeStatic(method, JSType.TO_UINT32);
+        } else if (to.isLong()) {
+            convert(method, OBJECT);
+            invokeStatic(method, JSType.TO_LONG);
+        } else if (to.isString()) {
+            invokeStatic(method, VALUE_OF);
+            invokeStatic(method, JSType.TO_PRIMITIVE);
+            invokeStatic(method, JSType.TO_STRING);
+        } else if (to.isObject()) {
+            invokeStatic(method, VALUE_OF);
+        } else {
+            assert false : "Illegal conversion " + this + " -> " + to;
+        }
+
+        return to;
+    }
+
+    @Override
+    public Type add(final MethodVisitor method) {
+        assert false : "unsupported operation";
+        return null;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeArrayOps.java b/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeArrayOps.java
new file mode 100644
index 0000000..d38cec3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeArrayOps.java
@@ -0,0 +1,78 @@
+/*
+ * 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.codegen.types;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+
+/**
+ * Array operations, not supported by all ops
+ */
+interface BytecodeArrayOps {
+
+    /**
+     * Load an array element given that the array and its index are already on
+     * the stack
+     *
+     * @param method method visitor
+     * @return the array element type
+     *
+     */
+    Type aload(MethodVisitor method);
+
+    /**
+     * Store an array element given that the array and its index and the element
+     * are on the stack
+     *
+     * @param method method visitor
+     */
+    void astore(MethodVisitor method);
+
+    /**
+     * Generate an array length operation
+     *
+     * @param method method method visitor
+     * @return length of the array
+     */
+    Type arraylength(MethodVisitor method);
+
+    /**
+     * Create a new array of this array type and length on stack
+     *
+     * @param method method visitor
+     * @return the type of the array
+     */
+    Type newarray(MethodVisitor method);
+
+    /**
+     * Create a new multi array of this array type and allocate the number of
+     * dimensions given
+     *
+     * @param method method visitor
+     * @param dims   number of dimensions
+     * @return the type of the new array
+     */
+    Type newarray(MethodVisitor method, int dims);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeBitwiseOps.java b/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeBitwiseOps.java
new file mode 100644
index 0000000..ca3e1d3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeBitwiseOps.java
@@ -0,0 +1,96 @@
+/*
+ * 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.codegen.types;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+
+/**
+ * Bitwise operations not supported by all types
+ */
+interface BytecodeBitwiseOps {
+
+    /**
+     * Pop and logically shift the two values on top of the stack (steps, value)
+     * right and push the result on the stack
+     *
+     * @param method method visitor
+     * @return result type
+     */
+    Type shr(MethodVisitor method);
+
+    /**
+     * Pop and arithmetically shift of the two values on top of the stack
+     * (steps, value) right and push the result on the stack
+     *
+     * @param method method visitor
+     * @return result type
+     */
+    Type sar(MethodVisitor method);
+
+    /**
+     * Pop and logically shift of the two values on top of the stack (steps,
+     * value) left and push the result on the stack
+     *
+     * @param method method visitor
+     * @return result type
+     */
+    Type shl(MethodVisitor method);
+
+    /**
+     * Pop and AND the two values on top of the stack and push the result on the
+     * stack
+     *
+     * @param method method visitor
+     * @return result type
+     */
+    Type and(MethodVisitor method);
+
+    /**
+     * Pop and OR the two values on top of the stack and push the result on the
+     * stack
+     *
+     * @param method method visitor
+     * @return result type
+     */
+    Type or(MethodVisitor method);
+
+    /**
+     * Pop and XOR the two values on top of the stack and push the result on the
+     * stack
+     *
+     * @param method method visitor
+     * @return result type
+     */
+    Type xor(MethodVisitor method);
+
+    /**
+     * Comparison with int return value, e.g. LCMP.
+     *
+     * @param method the method visitor
+     * @return int return value
+     */
+    Type cmp(MethodVisitor method);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeNumericOps.java b/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeNumericOps.java
new file mode 100644
index 0000000..ae53028
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeNumericOps.java
@@ -0,0 +1,93 @@
+/*
+ * 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.codegen.types;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+
+/**
+ * Numeric operations, not supported by all types
+ */
+interface BytecodeNumericOps {
+
+    /**
+     * Pop and negate the value on top of the stack and push the result
+     *
+     * @param method method visitor
+     *
+     * @return result type
+     */
+    Type neg(MethodVisitor method);
+
+    /**
+     * Pop two values on top of the stack and subtract the first from the
+     * second, pushing the result on the stack
+     *
+     * @param method method visitor
+     *
+     * @return result type
+     */
+    Type sub(MethodVisitor method);
+
+    /**
+     * Pop and multiply the two values on top of the stack and push the result
+     * on the stack
+     *
+     * @param method method visitor
+     *
+     * @return result type
+     */
+    Type mul(MethodVisitor method);
+
+    /**
+     * Pop two values on top of the stack and divide the first with the second,
+     * pushing the result on the stack
+     *
+     * @param method method visitor
+     *
+     * @return result type
+     */
+    Type div(MethodVisitor method);
+
+    /**
+     * Pop two values on top of the stack and compute the modulo of the first
+     * with the second, pushing the result on the stack
+     *
+     * @param method method visitor
+     *
+     * @return result type
+     */
+    Type rem(MethodVisitor method);
+
+    /**
+     * Comparison with int return value, e.g. LCMP, DCMP.
+     *
+     * @param method the method visitor
+     * @param isCmpG is this a double style cmpg
+     *
+     * @return int return value
+     */
+    Type cmp(MethodVisitor method, boolean isCmpG);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeOps.java b/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeOps.java
new file mode 100644
index 0000000..bbbddf9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeOps.java
@@ -0,0 +1,158 @@
+/*
+ * 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.codegen.types;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+
+
+/**
+ * Interface for byte code generation for all runtime types. Each
+ * type implements this interface and provides the type specific
+ * operations to do the generic things described herein.
+ *
+ * The bytecode ops are coupled to a MethodVisitor from ASM for
+ * byte code generation. They know nothing about our MethodGenerator,
+ * which is the abstraction for working with Nashorn JS types
+ * For exmaple, anything like "two or one slots" for a type, which
+ * is represented in bytecode and ASM, is abstracted away in the
+ * MethodGenerator. There you just say "dup" or "store".
+ *
+ * @see Type
+ * @see MethodVisitor
+ */
+interface BytecodeOps {
+
+    /**
+     * Duplicate top entry of stack. If a too large depth is
+     * given, so that there are no possible bytecode instructions
+     * available to generate the dup sequence, null is returned.
+     *
+     * @param method  method visitor
+     * @param depth   how far should the copy be pushed down
+     *
+     * @return        the type at the top of the stack or null
+     */
+    Type dup(MethodVisitor method, int depth);
+
+    /**
+     * Pop an entry of this type from the top of the bytecode
+     * stack. This works regardless of what category this type
+     * is
+     *
+     * @param method  method visitor
+     *
+     * @return the popped type
+     */
+    Type pop(MethodVisitor method);
+
+    /**
+     * Swap this type with the bytecode stack with the one below
+     * Generate appropriate code no matter the categories of the
+     * two types
+     *
+     * @param method  method visitor
+     * @param other   the type below this one on the stack
+     *
+     * @return        the other type
+     */
+    Type swap(MethodVisitor method, Type other);
+
+    /**
+     * Pop two values on top of the stack and add the
+     * first to the second, pushing the result on the stack
+     *
+     * @param method  method visitor
+     * @return result type
+     */
+    Type add(MethodVisitor method);
+
+    /**
+     * Load a variable from a local slot to the stack
+     *
+     * @param method method visitor
+     * @param slot   the slot to load
+     *
+     * @return       the type that was loaded
+     */
+    Type load(MethodVisitor method, int slot);
+
+    /**
+     * Store a variable from the stack to a local slot
+     *
+     * @param method  method visitor
+     * @param slot    the slot to store to
+     */
+    void store(MethodVisitor method, int slot);
+
+    /**
+     * Load a constant to the stack.
+     *
+     * @param method  method visitor
+     * @param c       the value of the constant
+     *
+     * @return        the type at the top of the stack after load
+     */
+    Type ldc(MethodVisitor method, Object c);
+
+    /**
+     * Load the "undefined" value to the stack. Note that
+     * there may be different representations of this for
+     * e.g. doubles and objects. Abstraction removes this
+     *
+     * @param  method  method visitor.
+     *
+     * @return the undefined type at the top of the stack
+     */
+    Type loadUndefined(MethodVisitor method);
+
+    /**
+     * Load the "empty" value to the stack.
+     *
+     * @param  method  method visitor.
+     * @return the undefined type at the top of the stack
+     */
+    Type loadEmpty(MethodVisitor method);
+
+    /**
+     * Generate code that pops and casts the element on top of the
+     * stack to another type, given as parameter
+     *
+     * @param method  method visitor
+     * @param to      the type to cast to
+     *
+     * @return the to type
+     */
+    Type convert(MethodVisitor method, Type to);
+
+    /**
+     * Return the parameter on top of the stack
+     * from a method
+     *
+     * @param method the method visitor
+     */
+    void _return(MethodVisitor method);
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/IntType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/IntType.java
new file mode 100644
index 0000000..9b859dd
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/IntType.java
@@ -0,0 +1,260 @@
+/*
+ * 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.codegen.types;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.BIPUSH;
+import static jdk.internal.org.objectweb.asm.Opcodes.I2D;
+import static jdk.internal.org.objectweb.asm.Opcodes.I2L;
+import static jdk.internal.org.objectweb.asm.Opcodes.IADD;
+import static jdk.internal.org.objectweb.asm.Opcodes.IAND;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_2;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_3;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_4;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_5;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_M1;
+import static jdk.internal.org.objectweb.asm.Opcodes.IDIV;
+import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.IMUL;
+import static jdk.internal.org.objectweb.asm.Opcodes.INEG;
+import static jdk.internal.org.objectweb.asm.Opcodes.IOR;
+import static jdk.internal.org.objectweb.asm.Opcodes.IREM;
+import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.ISHL;
+import static jdk.internal.org.objectweb.asm.Opcodes.ISHR;
+import static jdk.internal.org.objectweb.asm.Opcodes.ISTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ISUB;
+import static jdk.internal.org.objectweb.asm.Opcodes.IUSHR;
+import static jdk.internal.org.objectweb.asm.Opcodes.IXOR;
+import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.nashorn.internal.codegen.CompilerConstants;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+
+/**
+ * Type class: INT
+ */
+class IntType extends BitwiseType {
+
+    private static final CompilerConstants.Call TO_STRING = staticCallNoLookup(Integer.class, "toString", String.class, int.class);
+    private static final CompilerConstants.Call VALUE_OF  = staticCallNoLookup(Integer.class, "valueOf", Integer.class, int.class);
+
+    protected IntType() {
+        super("int", int.class, 2, 1);
+    }
+
+    @Override
+    public Type nextWider() {
+        return LONG;
+    }
+
+    @Override
+    public Class<?> getBoxedType() {
+        return Integer.class;
+    }
+
+    @Override
+    public Type ldc(final MethodVisitor method, final Object c) {
+        assert c instanceof Integer;
+
+        final int value = ((Integer) c).intValue();
+
+        switch (value) {
+            case -1:
+                method.visitInsn(ICONST_M1);
+                break;
+            case 0:
+                method.visitInsn(ICONST_0);
+                break;
+            case 1:
+                method.visitInsn(ICONST_1);
+                break;
+            case 2:
+                method.visitInsn(ICONST_2);
+                break;
+            case 3:
+                method.visitInsn(ICONST_3);
+                break;
+            case 4:
+                method.visitInsn(ICONST_4);
+                break;
+            case 5:
+                method.visitInsn(ICONST_5);
+                break;
+            default:
+                if (value == (byte) value) {
+                    method.visitIntInsn(BIPUSH, value);
+                } else if (value == (short) value) {
+                    method.visitIntInsn(SIPUSH, value);
+                } else {
+                    method.visitLdcInsn(c);
+                }
+                break;
+        }
+
+        return Type.INT;
+    }
+
+    @Override
+    public Type convert(final MethodVisitor method, final Type to) {
+        if (to.isEquivalentTo(this)) {
+            return to;
+        }
+
+        if (to.isNumber()) {
+            method.visitInsn(I2D);
+        } else if (to.isLong()) {
+            method.visitInsn(I2L);
+        } else if (to.isBoolean()) {
+            //nop
+        } else if (to.isString()) {
+            invokeStatic(method, TO_STRING);
+        } else if (to.isObject()) {
+            invokeStatic(method, VALUE_OF);
+        } else {
+            assert false : "Illegal conversion " + this + " -> " + to;
+        }
+
+        return to;
+    }
+
+    @Override
+    public Type add(final MethodVisitor method) {
+        method.visitInsn(IADD);
+        return INT;
+    }
+
+    @Override
+    public Type shr(final MethodVisitor method) {
+        method.visitInsn(IUSHR);
+        return INT;
+    }
+
+    @Override
+    public Type sar(final MethodVisitor method) {
+        method.visitInsn(ISHR);
+        return INT;
+    }
+
+    @Override
+    public Type shl(final MethodVisitor method) {
+        method.visitInsn(ISHL);
+        return INT;
+    }
+
+    @Override
+    public Type and(final MethodVisitor method) {
+        method.visitInsn(IAND);
+        return INT;
+    }
+
+    @Override
+    public Type or(final MethodVisitor method) {
+        method.visitInsn(IOR);
+        return INT;
+    }
+
+    @Override
+    public Type xor(final MethodVisitor method) {
+        method.visitInsn(IXOR);
+        return INT;
+    }
+
+    @Override
+    public Type load(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(ILOAD, slot);
+        return INT;
+    }
+
+    @Override
+    public void store(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(ISTORE, slot);
+    }
+
+    @Override
+    public Type sub(final MethodVisitor method) {
+        method.visitInsn(ISUB);
+        return INT;
+    }
+
+    @Override
+    public Type mul(final MethodVisitor method) {
+        method.visitInsn(IMUL);
+        return INT;
+    }
+
+    @Override
+    public Type div(final MethodVisitor method) {
+        method.visitInsn(IDIV);
+        return INT;
+    }
+
+    @Override
+    public Type rem(final MethodVisitor method) {
+        method.visitInsn(IREM);
+        return INT;
+    }
+
+    @Override
+    public Type neg(final MethodVisitor method) {
+        method.visitInsn(INEG);
+        return INT;
+    }
+
+    @Override
+    public void _return(final MethodVisitor method) {
+        method.visitInsn(IRETURN);
+    }
+
+    @Override
+    public Type loadUndefined(final MethodVisitor method) {
+        method.visitLdcInsn(ObjectClassGenerator.UNDEFINED_INT);
+        return INT;
+    }
+
+    @Override
+    public Type loadEmpty(final MethodVisitor method) {
+        assert false : "unsupported operation";
+        return null;
+    }
+
+    @Override
+    public Type cmp(final MethodVisitor method, final boolean isCmpG) {
+        assert false : "unsupported operation";
+        return null;
+    }
+
+    @Override
+    public Type cmp(final MethodVisitor method) {
+        assert false : "unsupported operation";
+        return null;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/LongType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/LongType.java
new file mode 100644
index 0000000..d3e00b6
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/LongType.java
@@ -0,0 +1,229 @@
+/*
+ * 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.codegen.types;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.L2D;
+import static jdk.internal.org.objectweb.asm.Opcodes.L2I;
+import static jdk.internal.org.objectweb.asm.Opcodes.LADD;
+import static jdk.internal.org.objectweb.asm.Opcodes.LAND;
+import static jdk.internal.org.objectweb.asm.Opcodes.LCMP;
+import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_1;
+import static jdk.internal.org.objectweb.asm.Opcodes.LDIV;
+import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.LMUL;
+import static jdk.internal.org.objectweb.asm.Opcodes.LNEG;
+import static jdk.internal.org.objectweb.asm.Opcodes.LOR;
+import static jdk.internal.org.objectweb.asm.Opcodes.LREM;
+import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.LSHL;
+import static jdk.internal.org.objectweb.asm.Opcodes.LSHR;
+import static jdk.internal.org.objectweb.asm.Opcodes.LSTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.LSUB;
+import static jdk.internal.org.objectweb.asm.Opcodes.LUSHR;
+import static jdk.internal.org.objectweb.asm.Opcodes.LXOR;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.nashorn.internal.codegen.CompilerConstants;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+
+/**
+ * Type class: LONG
+ */
+class LongType extends BitwiseType {
+
+    private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Long.class, "valueOf", Long.class, long.class);
+
+    protected LongType(final String name) {
+        super(name, long.class, 3, 2);
+    }
+
+    protected LongType() {
+        this("long");
+    }
+
+    @Override
+    public Type nextWider() {
+        return NUMBER;
+    }
+
+    @Override
+    public Class<?> getBoxedType() {
+        return Long.class;
+    }
+
+    @Override
+    public Type cmp(final MethodVisitor method) {
+        method.visitInsn(LCMP);
+        return INT;
+    }
+
+    @Override
+    public Type load(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(LLOAD, slot);
+        return LONG;
+    }
+
+    @Override
+    public void store(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(LSTORE, slot);
+    }
+
+    @Override
+    public Type ldc(final MethodVisitor method, final Object c) {
+        assert c instanceof Long;
+
+        final long value = (Long) c;
+
+        if (value == 0L) {
+            method.visitInsn(LCONST_0);
+        } else if (value == 1L) {
+            method.visitInsn(LCONST_1);
+        } else {
+            method.visitLdcInsn(c);
+        }
+
+        return Type.LONG;
+    }
+
+    @Override
+    public Type convert(final MethodVisitor method, final Type to) {
+        if (isEquivalentTo(to)) {
+            return to;
+        }
+
+        if (to.isNumber()) {
+            method.visitInsn(L2D);
+        } else if (to.isInteger()) {
+            method.visitInsn(L2I);
+        } else if (to.isBoolean()) {
+            method.visitInsn(L2I);
+        } else if (to.isObject()) {
+            invokeStatic(method, VALUE_OF);
+        } else {
+            assert false : "Illegal conversion " + this + " -> " + to;
+        }
+
+        return to;
+    }
+
+    @Override
+    public Type add(final MethodVisitor method) {
+        method.visitInsn(LADD);
+        return LONG;
+    }
+
+    @Override
+    public Type sub(final MethodVisitor method) {
+        method.visitInsn(LSUB);
+        return LONG;
+    }
+
+    @Override
+    public Type mul(final MethodVisitor method) {
+        method.visitInsn(LMUL);
+        return LONG;
+    }
+
+    @Override
+    public Type div(final MethodVisitor method) {
+        method.visitInsn(LDIV);
+        return LONG;
+    }
+
+    @Override
+    public Type rem(final MethodVisitor method) {
+        method.visitInsn(LREM);
+        return LONG;
+    }
+
+    @Override
+    public Type shr(final MethodVisitor method) {
+        method.visitInsn(LUSHR);
+        return LONG;
+    }
+
+    @Override
+    public Type sar(final MethodVisitor method) {
+        method.visitInsn(LSHR);
+        return LONG;
+    }
+
+    @Override
+    public Type shl(final MethodVisitor method) {
+        method.visitInsn(LSHL);
+        return LONG;
+    }
+
+    @Override
+    public Type and(final MethodVisitor method) {
+        method.visitInsn(LAND);
+        return LONG;
+    }
+
+    @Override
+    public Type or(final MethodVisitor method) {
+        method.visitInsn(LOR);
+        return LONG;
+    }
+
+    @Override
+    public Type xor(final MethodVisitor method) {
+        method.visitInsn(LXOR);
+        return LONG;
+    }
+
+    @Override
+    public Type neg(final MethodVisitor method) {
+        method.visitInsn(LNEG);
+        return LONG;
+    }
+
+    @Override
+    public void _return(final MethodVisitor method) {
+        method.visitInsn(LRETURN);
+    }
+
+    @Override
+    public Type loadUndefined(final MethodVisitor method) {
+        method.visitLdcInsn(ObjectClassGenerator.UNDEFINED_LONG);
+        return LONG;
+    }
+
+    @Override
+    public Type loadEmpty(final MethodVisitor method) {
+        assert false : "unsupported operation";
+        return null;
+    }
+
+    @Override
+    public Type cmp(final MethodVisitor method, final boolean isCmpG) {
+        return cmp(method);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/NumberType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/NumberType.java
new file mode 100644
index 0000000..4dc62c5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/NumberType.java
@@ -0,0 +1,177 @@
+/*
+ * 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.codegen.types;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.DADD;
+import static jdk.internal.org.objectweb.asm.Opcodes.DCMPG;
+import static jdk.internal.org.objectweb.asm.Opcodes.DCMPL;
+import static jdk.internal.org.objectweb.asm.Opcodes.DCONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.DCONST_1;
+import static jdk.internal.org.objectweb.asm.Opcodes.DDIV;
+import static jdk.internal.org.objectweb.asm.Opcodes.DLOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.DMUL;
+import static jdk.internal.org.objectweb.asm.Opcodes.DNEG;
+import static jdk.internal.org.objectweb.asm.Opcodes.DREM;
+import static jdk.internal.org.objectweb.asm.Opcodes.DRETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.DSTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.DSUB;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.nashorn.internal.codegen.CompilerConstants;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.runtime.JSType;
+
+class NumberType extends NumericType {
+
+    private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Double.class, "valueOf", Double.class, double.class);
+
+    protected NumberType() {
+        super("double", double.class, 4, 2);
+    }
+
+    @Override
+    public Type nextWider() {
+        return OBJECT;
+    }
+
+    @Override
+    public Class<?> getBoxedType() {
+        return Double.class;
+    }
+
+    @Override
+    public Type cmp(final MethodVisitor method, final boolean isCmpG) {
+        method.visitInsn(isCmpG ? DCMPG : DCMPL);
+        return INT;
+    }
+
+    @Override
+    public Type load(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(DLOAD, slot);
+        return NUMBER;
+    }
+
+    @Override
+    public void store(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(DSTORE, slot);
+    }
+
+    @Override
+    public Type loadUndefined(final MethodVisitor method) {
+        method.visitLdcInsn(ObjectClassGenerator.UNDEFINED_DOUBLE);
+        return NUMBER;
+    }
+
+    @Override
+    public Type loadEmpty(final MethodVisitor method) {
+        assert false : "unsupported operation";
+        return null;
+    }
+
+    @Override
+    public Type ldc(final MethodVisitor method, final Object c) {
+        assert c instanceof Double;
+
+        final double value = (Double) c;
+
+        if (Double.doubleToLongBits(value) == 0L) { // guard against -0.0
+            method.visitInsn(DCONST_0);
+        } else if (value == 1.0) {
+            method.visitInsn(DCONST_1);
+        } else {
+            method.visitLdcInsn(value);
+        }
+
+        return NUMBER;
+    }
+
+    @Override
+    public Type convert(final MethodVisitor method, final Type to) {
+        if (isEquivalentTo(to)) {
+            return null;
+        }
+
+        if (to.isInteger()) {
+            invokeStatic(method, JSType.TO_INT32_D);
+        } else if (to.isLong()) {
+            invokeStatic(method, JSType.TO_INT64_D);
+        } else if (to.isBoolean()) {
+            invokeStatic(method, JSType.TO_BOOLEAN_D);
+        } else if (to.isString()) {
+            invokeStatic(method, JSType.TO_STRING_D);
+        } else if (to.isObject()) {
+            invokeStatic(method, VALUE_OF);
+        } else {
+            assert false : "Illegal conversion " + this + " -> " + to;
+        }
+
+        return to;
+    }
+
+    @Override
+    public Type add(final MethodVisitor method) {
+        method.visitInsn(DADD);
+        return NUMBER;
+    }
+
+    @Override
+    public Type sub(final MethodVisitor method) {
+        method.visitInsn(DSUB);
+        return NUMBER;
+    }
+
+    @Override
+    public Type mul(final MethodVisitor method) {
+        method.visitInsn(DMUL);
+        return NUMBER;
+    }
+
+    @Override
+    public Type div(final MethodVisitor method) {
+        method.visitInsn(DDIV);
+        return NUMBER;
+    }
+
+    @Override
+    public Type rem(final MethodVisitor method) {
+        method.visitInsn(DREM);
+        return NUMBER;
+    }
+
+    @Override
+    public Type neg(final MethodVisitor method) {
+        method.visitInsn(DNEG);
+        return NUMBER;
+    }
+
+    @Override
+    public void _return(final MethodVisitor method) {
+        method.visitInsn(DRETURN);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/NumericType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/NumericType.java
new file mode 100644
index 0000000..597ff57
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/NumericType.java
@@ -0,0 +1,43 @@
+/*
+ * 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.codegen.types;
+
+/**
+ * This is a numeric type, i.e. NUMBER, LONG, INT, INT32.
+ */
+public abstract class NumericType extends Type implements BytecodeNumericOps {
+    /**
+     * Constructor
+     *
+     * @param name   name of type
+     * @param clazz  Java class used to represent type
+     * @param weight weight of type
+     * @param slots  number of bytecode slots this type takes up
+     */
+    protected NumericType(final String name, final Class<?> clazz, final int weight, final int slots) {
+        super(name, clazz, weight, slots);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java b/nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java
new file mode 100644
index 0000000..cb2f876
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java
@@ -0,0 +1,169 @@
+/*
+ * 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.codegen.types;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACONST_NULL;
+import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.CHECKCAST;
+import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
+import static jdk.nashorn.internal.codegen.CompilerConstants.className;
+import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
+
+import java.lang.invoke.MethodHandle;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.nashorn.internal.codegen.CompilerConstants;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Undefined;
+
+/**
+ * Type class: OBJECT This is the object type, used for all object types. It can
+ * contain a class that is a more specialized object
+ */
+class ObjectType extends Type {
+
+    protected ObjectType() {
+        this(Object.class);
+    }
+
+    protected ObjectType(final Class<?> clazz) {
+        super("object",
+                clazz,
+                clazz == Object.class ? Type.MAX_WEIGHT : 10,
+                1);
+    }
+
+    @Override
+    public String toString() {
+        return "object" + (getTypeClass() != Object.class ? "<type=" + getTypeClass().getSimpleName() + '>' : "");
+    }
+
+    @Override
+    public Type add(final MethodVisitor method) {
+        invokeStatic(method, ScriptRuntime.ADD);
+        return Type.OBJECT;
+    }
+
+    @Override
+    public Type load(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(ALOAD, slot);
+        return Type.OBJECT;
+    }
+
+    @Override
+    public void store(final MethodVisitor method, final int slot) {
+        assert slot != -1;
+        method.visitVarInsn(ASTORE, slot);
+    }
+
+    @Override
+    public Type loadUndefined(final MethodVisitor method) {
+        method.visitFieldInsn(GETSTATIC, className(ScriptRuntime.class), "UNDEFINED", typeDescriptor(Undefined.class));
+        return OBJECT;
+    }
+
+    @Override
+    public Type loadEmpty(final MethodVisitor method) {
+        method.visitFieldInsn(GETSTATIC, className(ScriptRuntime.class), "EMPTY", typeDescriptor(Undefined.class));
+        return OBJECT;
+    }
+
+    @Override
+    public Type ldc(final MethodVisitor method, final Object c) {
+        if (c == null) {
+            method.visitInsn(ACONST_NULL);
+        } else if (c instanceof Undefined) {
+            return loadUndefined(method);
+        } else if (c instanceof String) {
+            method.visitLdcInsn(c);
+            return STRING;
+        } else if (c instanceof Handle) {
+            method.visitLdcInsn(c);
+            return Type.typeFor(MethodHandle.class);
+        } else {
+            assert false : "implementation missing for class " + c.getClass() + " value=" + c;
+        }
+
+        return OBJECT;
+    }
+
+    @Override
+    public Type convert(final MethodVisitor method, final Type to) {
+        final boolean toString = to.isString();
+        if (!toString) {
+            if (to.isArray()) {
+                final Type elemType = ((ArrayType)to).getElementType();
+
+                //note that if this an array, things won't work. see {link @ArrayType} subclass.
+                //we also have the unpleasant case of NativeArray which looks like an Object, but is
+                //an array to the type system. This is treated specially at the known load points
+
+                if (elemType.isString()) {
+                    method.visitTypeInsn(CHECKCAST, CompilerConstants.className(String[].class));
+                } else if (elemType.isNumber()) {
+                    method.visitTypeInsn(CHECKCAST, CompilerConstants.className(double[].class));
+                } else if (elemType.isLong()) {
+                    method.visitTypeInsn(CHECKCAST, CompilerConstants.className(long[].class));
+                } else if (elemType.isInteger()) {
+                    method.visitTypeInsn(CHECKCAST, CompilerConstants.className(int[].class));
+                } else {
+                    method.visitTypeInsn(CHECKCAST, CompilerConstants.className(Object[].class));
+                }
+                return to;
+            } else if (to.isObject()) {
+                return to;
+            }
+        } else if (isString()) {
+            return to;
+        }
+
+        if (to.isInteger()) {
+            invokeStatic(method, JSType.TO_INT32);
+        } else if (to.isNumber()) {
+            invokeStatic(method, JSType.TO_NUMBER);
+        } else if (to.isLong()) {
+            invokeStatic(method, JSType.TO_INT64);
+        } else if (to.isBoolean()) {
+            invokeStatic(method, JSType.TO_BOOLEAN);
+        } else if (to.isString()) {
+            invokeStatic(method, JSType.TO_PRIMITIVE);
+            invokeStatic(method, JSType.TO_STRING);
+        } else {
+            assert false : "Illegal conversion " + this + " -> " + to + " " + isString() + " " + toString;
+        }
+
+        return to;
+    }
+
+    @Override
+    public void _return(final MethodVisitor method) {
+        method.visitInsn(ARETURN);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java
new file mode 100644
index 0000000..d36dd20
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java
@@ -0,0 +1,882 @@
+/*
+ * 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.codegen.types;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.DALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.DASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP2;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP2_X1;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP2_X2;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP_X1;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP_X2;
+import static jdk.internal.org.objectweb.asm.Opcodes.IALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.LASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.NEWARRAY;
+import static jdk.internal.org.objectweb.asm.Opcodes.POP;
+import static jdk.internal.org.objectweb.asm.Opcodes.POP2;
+import static jdk.internal.org.objectweb.asm.Opcodes.SWAP;
+import static jdk.internal.org.objectweb.asm.Opcodes.T_DOUBLE;
+import static jdk.internal.org.objectweb.asm.Opcodes.T_INT;
+
+import java.lang.invoke.MethodHandle;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+
+
+/**
+ * This is the representation of a JavaScript type, disassociated from java
+ * Classes, with the basis for conversion weight, mapping to ASM types
+ * and implementing the ByteCodeOps interface which tells this type
+ * how to generate code for various operations.
+ *
+ * Except for ClassEmitter, this is the only class that has to know
+ * about the underlying byte code generation system.
+ *
+ * The different types know how to generate bytecode for the different
+ * operations, inherited from BytecodeOps, that they support. This avoids
+ * if/else chains depending on type in several cases and allows for
+ * more readable and shorter code
+ *
+ * The Type class also contains logic used by the type inference and
+ * for comparing types against each other, as well as the concepts
+ * of narrower to wider types. The widest type is an object. Ideally we
+ * would like as narrow types as possible for code to be efficient, e.g
+ * INTs rather than OBJECTs
+ */
+
+public abstract class Type implements Comparable<Type>, BytecodeOps {
+
+    /** Human readable name for type */
+    private final String name;
+
+    /** Descriptor for type */
+    private final String descriptor;
+
+    /** The "weight" of the type. Used for picking widest/least specific common type */
+    private final int weight;
+
+    /** How many bytecode slots does this type occupy */
+    private final int slots;
+
+    /** The class for this type */
+    private final Class<?> clazz;
+
+    /** Weights are used to decide which types are "wider" than other types */
+    protected static final int MIN_WEIGHT = -1;
+
+    /** Set way below Integer.MAX_VALUE to prevent overflow when adding weights. Objects are still heaviest. */
+    protected static final int MAX_WEIGHT = 20;
+
+    /**
+     * Constructor
+     *
+     * @param clazz       class for type
+     * @param weight      weight - higher is more generic
+     * @param slots       how many bytecode slots the type takes up
+     */
+    Type(final String name, final Class<?> clazz, final int weight, final int slots) {
+        this.name       = name;
+        this.clazz      = clazz;
+        this.descriptor = Type.getDescriptor(clazz);
+        this.weight     = weight;
+        assert weight >= MIN_WEIGHT && weight <= MAX_WEIGHT : "illegal type weight: " + weight;
+        this.slots      = slots;
+    }
+
+    /**
+     * Return an internal descriptor for a type
+     *
+     * @param type the type
+     * @return descriptor string
+     */
+    public static String getDescriptor(final Class<?> type) {
+        return jdk.internal.org.objectweb.asm.Type.getDescriptor(type);
+    }
+
+    /**
+     * Get the weight of this type - use this e.g. for sorting method descriptors
+     * @return the weight
+     */
+    public int getWeight() {
+        return weight;
+    }
+
+    /**
+     * Get the Class representing this type
+     * @return the class for this type
+     */
+    public Class<?> getTypeClass() {
+        return clazz;
+    }
+
+    /**
+     * For specialization, return the next, slightly more difficulty, type
+     * to test.
+     *
+     * @return the next Type
+     */
+    public Type nextWider() {
+        return null;
+    }
+
+    /**
+     * Get the boxed type for this class
+     * @return the boxed version of this type or null if N/A
+     */
+    public Class<?> getBoxedType() {
+        assert !getTypeClass().isPrimitive();
+        return null;
+    }
+
+    /**
+     * Generate a method descriptor given a return type and a param array
+     *
+     * @param returnType return type
+     * @param types      parameters
+     *
+     * @return a descriptor string
+     */
+    public static String getMethodDescriptor(final Type returnType, final Type... types) {
+        final jdk.internal.org.objectweb.asm.Type[] itypes = new jdk.internal.org.objectweb.asm.Type[types.length];
+        for (int i = 0; i < types.length; i++) {
+            itypes[i] = types[i].getInternalType();
+        }
+        return jdk.internal.org.objectweb.asm.Type.getMethodDescriptor(returnType.getInternalType(), itypes);
+    }
+
+    /**
+     * Generate a method descriptor given a return type and a param array
+     *
+     * @param returnType return type
+     * @param types      parameters
+     *
+     * @return a descriptor string
+     */
+    public static String getMethodDescriptor(final Class<?> returnType, final Class<?>... types) {
+        final jdk.internal.org.objectweb.asm.Type[] itypes = new jdk.internal.org.objectweb.asm.Type[types.length];
+        for (int i = 0; i < types.length; i++) {
+            itypes[i] = getInternalType(types[i]);
+        }
+        return jdk.internal.org.objectweb.asm.Type.getMethodDescriptor(getInternalType(returnType), itypes);
+    }
+
+    /**
+     * Return the type for an internal type, package private - do not use
+     * outside code gen
+     *
+     * @param itype internal type
+     * @return Nashorn type
+     */
+    @SuppressWarnings("fallthrough")
+    static Type typeFor(final jdk.internal.org.objectweb.asm.Type itype) {
+        switch (itype.getSort()) {
+        case jdk.internal.org.objectweb.asm.Type.BOOLEAN:
+            return BOOLEAN;
+        case jdk.internal.org.objectweb.asm.Type.INT:
+            return INT;
+        case jdk.internal.org.objectweb.asm.Type.LONG:
+            return LONG;
+        case jdk.internal.org.objectweb.asm.Type.DOUBLE:
+            return NUMBER;
+        case jdk.internal.org.objectweb.asm.Type.OBJECT:
+            return OBJECT;
+        case jdk.internal.org.objectweb.asm.Type.VOID:
+            return null;
+        case jdk.internal.org.objectweb.asm.Type.ARRAY:
+            switch (itype.getElementType().getSort()) {
+            case jdk.internal.org.objectweb.asm.Type.DOUBLE:
+                return NUMBER_ARRAY;
+            case jdk.internal.org.objectweb.asm.Type.INT:
+                return INT_ARRAY;
+            case jdk.internal.org.objectweb.asm.Type.LONG:
+                return LONG_ARRAY;
+            default:
+                assert false;
+            case jdk.internal.org.objectweb.asm.Type.OBJECT:
+                return OBJECT_ARRAY;
+            }
+
+        default:
+            assert false : "Unknown itype : " + itype + " sort " + itype.getSort();
+            break;
+        }
+        return null;
+    }
+
+    /**
+     * Get the return type for a method
+     *
+     * @param methodDescriptor method descriptor
+     * @return return type
+     */
+    public static Type getMethodReturnType(final String methodDescriptor) {
+        return Type.typeFor(jdk.internal.org.objectweb.asm.Type.getReturnType(methodDescriptor));
+    }
+
+    /**
+     * Get type array representing arguments of a method in order
+     *
+     * @param methodDescriptor method descriptor
+     * @return parameter type array
+     */
+    public static Type[] getMethodArguments(final String methodDescriptor) {
+        final jdk.internal.org.objectweb.asm.Type itypes[] = jdk.internal.org.objectweb.asm.Type.getArgumentTypes(methodDescriptor);
+        final Type types[] = new Type[itypes.length];
+        for (int i = 0; i < itypes.length; i++) {
+            types[i] = Type.typeFor(itypes[i]);
+        }
+        return types;
+    }
+
+    static jdk.internal.org.objectweb.asm.Type getInternalType(final String className) {
+        return jdk.internal.org.objectweb.asm.Type.getType(className);
+    }
+
+    private jdk.internal.org.objectweb.asm.Type getInternalType() {
+        return jdk.internal.org.objectweb.asm.Type.getType(getTypeClass());
+    }
+
+    private static jdk.internal.org.objectweb.asm.Type getInternalType(final Class<?> type) {
+        return jdk.internal.org.objectweb.asm.Type.getType(type);
+    }
+
+    static void invokeStatic(final MethodVisitor method, final Call call) {
+        method.visitMethodInsn(INVOKESTATIC, call.className(), call.name(), call.descriptor());
+    }
+
+    /**
+     * Get the internal JVM name of a type
+     * @return the internal name
+     */
+    public String getInternalName() {
+        return jdk.internal.org.objectweb.asm.Type.getInternalName(getTypeClass());
+    }
+
+    /**
+     * Get the internal JVM name of type type represented by a given Java class
+     * @param clazz the class
+     * @return the internal name
+     */
+    public static String getInternalName(final Class<?> clazz) {
+        return jdk.internal.org.objectweb.asm.Type.getInternalName(clazz);
+    }
+
+    /**
+     * Determines whether a type is the UNKNOWN type, i.e. not set yet
+     * Used for type inference.
+     *
+     * @return true if UNKNOWN, false otherwise
+     */
+    public boolean isUnknown() {
+        return this.equals(Type.UNKNOWN);
+    }
+
+    /**
+     * Determines whether a type is the BOOLEAN type
+     * @return true if BOOLEAN, false otherwise
+     */
+    public boolean isBoolean() {
+        return this.equals(Type.BOOLEAN);
+    }
+
+    /**
+     * Determines whether a type is the INT type
+     * @return true if INTEGER, false otherwise
+     */
+    public boolean isInteger() {
+        return this.equals(Type.INT);
+    }
+
+    /**
+     * Determines whether a type is the LONG type
+     * @return true if LONG, false otherwise
+     */
+    public boolean isLong() {
+        return this.equals(Type.LONG);
+    }
+
+    /**
+     * Determines whether a type is the NUMBER type
+     * @return true if NUMBER, false otherwise
+     */
+    public boolean isNumber() {
+        return this.equals(Type.NUMBER);
+    }
+
+    /**
+     * Determines whether a type is numeric, i.e. NUMBER,
+     * INT, LONG.
+     *
+     * @return true if numeric, false otherwise
+     */
+    public boolean isNumeric() {
+        return this instanceof NumericType;
+    }
+
+    /**
+     * Determines whether a type is an array type, i.e.
+     * OBJECT_ARRAY or NUMBER_ARRAY (for now)
+     *
+     * @return true if an array type, false otherwise
+     */
+    public boolean isArray() {
+        return this instanceof ArrayType;
+    }
+
+    /**
+     * Determines if a type takes up two bytecode slots or not
+     *
+     * @return true if type takes up two bytecode slots rather than one
+     */
+    public boolean isCategory2() {
+        return getSlots() == 2;
+    }
+
+    /**
+     * Determines whether a type is an OBJECT type, e.g. OBJECT, STRING,
+     * NUMBER_ARRAY etc.
+     *
+     * @return true if object type, false otherwise
+     */
+    public boolean isObject() {
+        return this instanceof ObjectType;
+    }
+
+    /**
+     * Determines whether a type is a STRING type
+     *
+     * @return true if object type, false otherwise
+     */
+    public boolean isString() {
+        return this.equals(Type.STRING);
+    }
+
+    /**
+     * Determine if two types are equivalent, i.e. need no conversion
+     *
+     * @param type the second type to check
+     *
+     * @return true if types are equivalent, false otherwise
+     */
+    public boolean isEquivalentTo(final Type type) {
+        return this.weight() == type.weight() || (isObject() && type.isObject());
+    }
+
+    /**
+     * Determine if a type can be assigned to from another
+     *
+     * @param type0 the first type to check
+     * @param type1 the second type to check
+     *
+     * @return true if type1 can be written to type2, false otherwise
+     */
+    public static boolean isAssignableFrom(final Type type0, final Type type1) {
+        if (type0.isObject() && type1.isObject()) {
+            return type0.weight() >= type1.weight();
+        }
+
+        return type0.weight() == type1.weight();
+    }
+
+    /**
+     * Determine if this type is assignable from another type
+     * @param type the type to check against
+     *
+     * @return true if "type" can be written to this type, false otherwise
+     */
+    public boolean isAssignableFrom(final Type type) {
+        return Type.isAssignableFrom(this, type);
+    }
+
+    /**
+     * Determines is this type is equivalent to another, i.e. needs no conversion
+     * to be assigned to it.
+     *
+     * @param type0 the first type to check
+     * @param type1 the second type to check
+     *
+     * @return true if this type is equivalent to type, false otherwise
+     */
+    public static boolean areEquivalent(final Type type0, final Type type1) {
+        return type0.isEquivalentTo(type1);
+    }
+
+    /**
+     * Determine the number of bytecode slots a type takes up
+     *
+     * @return the number of slots for this type, 1 or 2.
+     */
+    public int getSlots() {
+        return slots;
+    }
+    /**
+     * Returns the widest or most common of two types
+     *
+     * @param type0 type one
+     * @param type1 type two
+     *
+     * @return the widest type
+     */
+    public static Type widest(final Type type0, final Type type1) {
+        if (type0.isArray() && type1.isArray()) {
+            return ((ArrayType)type0).getElementType() == ((ArrayType)type1).getElementType() ? type0 : Type.OBJECT;
+        } else if (type0.isArray() != type1.isArray()) {
+            return Type.OBJECT; //array and non array is always object, widest(Object[], int) NEVER returns Object[], which has most weight. that does not make sense
+        }
+        return type0.weight() > type1.weight() ? type0 : type1;
+    }
+
+    /**
+     * Returns the narrowest or least common of two types
+     *
+     * @param type0 type one
+     * @param type1 type two
+     *
+     * @return the widest type
+     */
+    public static Type narrowest(final Type type0, final Type type1) {
+        return type0.weight() < type1.weight() ? type0 : type1;
+    }
+
+    /**
+     * Returns the widest or most common of two types, but no wider than "limit"
+     *
+     * @param type0 type one
+     * @param type1 type two
+     * @param limit limiting type
+     *
+     * @return the widest type, but no wider than limit
+     */
+    public static Type widest(final Type type0, final Type type1, final Type limit) {
+        final Type type = Type.widest(type0,  type1);
+        if (type.weight() > limit.weight()) {
+            return limit;
+        }
+        return type;
+    }
+
+    /**
+     * Returns the widest or most common of two types, but no narrower than "limit"
+     *
+     * @param type0 type one
+     * @param type1 type two
+     * @param limit limiting type
+     *
+     * @return the widest type, but no wider than limit
+     */
+    public static Type narrowest(final Type type0, final Type type1, final Type limit) {
+        final Type type = type0.weight() < type1.weight() ? type0 : type1;
+        if (type.weight() < limit.weight()) {
+            return limit;
+        }
+        return type;
+    }
+
+    /**
+     * Returns the narrowest of this type and another
+     *
+     * @param  other type to compare against
+     *
+     * @return the widest type
+     */
+    public Type narrowest(final Type other) {
+        return Type.narrowest(this, other);
+    }
+
+    /**
+     * Returns the widest of this type and another
+     *
+     * @param  other type to compare against
+     *
+     * @return the widest type
+     */
+    public Type widest(final Type other) {
+        return Type.widest(this, other);
+    }
+
+    /**
+     * Returns the weight of a type, used for type comparison
+     * between wider and narrower types
+     *
+     * @return the weight
+     */
+    int weight() {
+        return weight;
+    }
+
+    /**
+     * Return the descriptor of a type, used for e.g. signature
+     * generation
+     *
+     * @return the descriptor
+     */
+    public String getDescriptor() {
+        return descriptor;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    /**
+     * Return the (possibly cached) Type object for this class
+     *
+     * @param clazz the class to check
+     *
+     * @return the Type representing this class
+     */
+    public static Type typeFor(final Class<?> clazz) {
+        Type type = cache.get(clazz);
+
+        if (type == null) {
+            assert !clazz.isPrimitive() || clazz == void.class;
+            if (clazz.isArray()) {
+                type = new ArrayType(clazz);
+            } else {
+                type = new ObjectType(clazz);
+            }
+            cache.put(clazz, type);
+        }
+
+        return type;
+    }
+
+    @Override
+    public int compareTo(final Type o) {
+        return o.weight() - weight();
+    }
+
+    /**
+     * Common logic for implementing dup for all types
+     *
+     * @param method method visitor
+     * @param depth dup depth
+     *
+     * @return the type at the top of the stack afterwards
+     */
+    @Override
+    public Type dup(final MethodVisitor method, final int depth) {
+        return Type.dup(method, this, depth);
+    }
+
+    /**
+     * Common logic for implementing swap for all types
+     *
+     * @param method method visitor
+     * @param other  the type to swap with
+     *
+     * @return the type at the top of the stack afterwards, i.e. other
+     */
+    @Override
+    public Type swap(final MethodVisitor method, final Type other) {
+        Type.swap(method, this, other);
+        return other;
+    }
+
+    /**
+     * Common logic for implementing pop for all types
+     *
+     * @param method method visitor
+     *
+     * @return the type that was popped
+     */
+    @Override
+    public Type pop(final MethodVisitor method) {
+        Type.pop(method, this);
+        return this;
+    }
+
+    /**
+     * Superclass logic for pop for all types
+     *
+     * @param method method emitter
+     * @param type   type to pop
+     */
+    protected static void pop(final MethodVisitor method, final Type type) {
+        method.visitInsn(type.isCategory2() ? POP2 : POP);
+    }
+
+    private static Type dup(final MethodVisitor method, final Type type, final int depth) {
+        final boolean       cat2 = type.isCategory2();
+
+        switch (depth) {
+        case 0:
+            method.visitInsn(cat2 ? DUP2 : DUP);
+            break;
+        case 1:
+            method.visitInsn(cat2 ? DUP2_X1 : DUP_X1);
+            break;
+        case 2:
+            method.visitInsn(cat2 ? DUP2_X2 : DUP_X2);
+            break;
+        default:
+            return null; //invalid depth
+        }
+
+        return type;
+    }
+
+    private static void swap(final MethodVisitor method, final Type above, final Type below) {
+        final MethodVisitor mv = method;
+        if (below.isCategory2()) {
+            if (above.isCategory2()) {
+                mv.visitInsn(DUP2_X2);
+                mv.visitInsn(POP2);
+            } else {
+                mv.visitInsn(DUP_X2);
+                mv.visitInsn(POP);
+            }
+        } else {
+            if (above.isCategory2()) {
+                mv.visitInsn(DUP2_X1);
+                mv.visitInsn(POP2);
+            } else {
+                mv.visitInsn(SWAP);
+            }
+        }
+
+    }
+
+    /**
+     * This is the boolean singleton, used for all boolean types
+     */
+    public static final Type BOOLEAN = new BooleanType();
+
+    /**
+     * This is an integer type, i.e INT, INT32.
+     */
+    public static final Type INT = new IntType();
+
+    /**
+     * This is the number singleton, used for all number types
+     */
+    public static final Type NUMBER = new NumberType();
+
+    /**
+     * This is the long singleton, used for all long types
+     */
+    public static final Type LONG = new LongType();
+
+    /**
+     * A string singleton
+     */
+    public static final Type STRING = new ObjectType(String.class);
+
+    /**
+     * This is the object singleton, used for all object types
+     */
+    public static final Type OBJECT = new ObjectType();
+
+    /**
+     * This is the singleton for integer arrays
+     */
+    public static final ArrayType INT_ARRAY = new ArrayType(int[].class) {
+        @Override
+        public void astore(final MethodVisitor method) {
+            method.visitInsn(IASTORE);
+        }
+
+        @Override
+        public Type aload(final MethodVisitor method) {
+            method.visitInsn(IALOAD);
+            return INT;
+        }
+
+        @Override
+        public Type newarray(final MethodVisitor method) {
+            method.visitIntInsn(NEWARRAY, T_INT);
+            return this;
+        }
+
+        @Override
+        public Type getElementType() {
+            return INT;
+        }
+    };
+
+    /**
+     * This is the singleton for long arrays
+     */
+    public static final ArrayType LONG_ARRAY = new ArrayType(long[].class) {
+        @Override
+        public void astore(final MethodVisitor method) {
+            method.visitInsn(LASTORE);
+        }
+
+        @Override
+        public Type aload(final MethodVisitor method) {
+            method.visitInsn(IALOAD);
+            return INT;
+        }
+
+        @Override
+        public Type newarray(final MethodVisitor method) {
+            method.visitIntInsn(NEWARRAY, T_INT);
+            return this;
+        }
+
+        @Override
+        public Type getElementType() {
+            return INT;
+        }
+    };
+
+    /**
+     * This is the singleton for numeric arrays
+     */
+    public static final ArrayType NUMBER_ARRAY = new ArrayType(double[].class) {
+        @Override
+        public void astore(final MethodVisitor method) {
+            method.visitInsn(DASTORE);
+        }
+
+        @Override
+        public Type aload(final MethodVisitor method) {
+            method.visitInsn(DALOAD);
+            return NUMBER;
+        }
+
+        @Override
+        public Type newarray(final MethodVisitor method) {
+            method.visitIntInsn(NEWARRAY, T_DOUBLE);
+            return this;
+        }
+
+        @Override
+        public Type getElementType() {
+            return NUMBER;
+        }
+    };
+
+    /** Singleton for method handle arrays used for properties etc. */
+    public static final ArrayType METHODHANDLE_ARRAY = new ArrayType(MethodHandle[].class);
+
+    /** This is the singleton for string arrays */
+    public static final ArrayType STRING_ARRAY = new ArrayType(String[].class);
+
+    /** This is the singleton for object arrays */
+    public static final ArrayType OBJECT_ARRAY = new ArrayType(Object[].class);
+
+    /** This type, always an object type, just a toString override */
+    public static final Type THIS = new ObjectType() {
+        @Override
+        public String toString() {
+            return "this";
+        }
+    };
+
+    /** Scope type, always an object type, just a toString override */
+    public static final Type SCOPE = new ObjectType() {
+        @Override
+        public String toString() {
+            return "scope";
+        }
+    };
+
+    private static interface Unknown {
+        // EMPTY - used as a class that is absolutely not compatible with a type to represent "unknown"
+    }
+
+    /**
+     * This is the unknown type which is used as initial type for type
+     * inference. It has the minimum type width
+     */
+    public static final Type UNKNOWN = new Type("<unknown>", Unknown.class, MIN_WEIGHT, 1) {
+
+        @Override
+        public String getDescriptor() {
+            return "<unknown>";
+        }
+
+        @Override
+        public Type load(final MethodVisitor method, final int slot) {
+            assert false : "unsupported operation";
+            return null;
+        }
+
+        @Override
+        public void store(final MethodVisitor method, final int slot) {
+            assert false : "unsupported operation";
+        }
+
+        @Override
+        public Type ldc(final MethodVisitor method, final Object c) {
+            assert false : "unsupported operation";
+            return null;
+        }
+
+        @Override
+        public Type loadUndefined(final MethodVisitor method) {
+            assert false : "unsupported operation";
+            return null;
+        }
+
+        @Override
+        public Type loadEmpty(final MethodVisitor method) {
+            assert false : "unsupported operation";
+            return null;
+        }
+
+        @Override
+        public Type convert(final MethodVisitor method, final Type to) {
+            assert false : "unsupported operation";
+            return null;
+        }
+
+        @Override
+        public void _return(final MethodVisitor method) {
+            assert false : "unsupported operation";
+        }
+
+        @Override
+        public Type add(final MethodVisitor method) {
+            assert false : "unsupported operation";
+            return null;
+        }
+    };
+
+    /** Mappings between java classes and their Type singletons */
+    private static final Map<Class<?>, Type> cache = Collections.synchronizedMap(new HashMap<Class<?>, Type>());
+
+    //TODO may need to be cleared, as all types are retained throughout code generation
+    static {
+        cache.put(BOOLEAN.getTypeClass(), BOOLEAN);
+        cache.put(INT.getTypeClass(),     INT);
+        cache.put(LONG.getTypeClass(),    LONG);
+        cache.put(NUMBER.getTypeClass(),  NUMBER);
+        cache.put(STRING.getTypeClass(),  STRING);
+        cache.put(OBJECT.getTypeClass(),  OBJECT);
+        cache.put(OBJECT_ARRAY.getTypeClass(), OBJECT_ARRAY);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java
new file mode 100644
index 0000000..481e385
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java
@@ -0,0 +1,166 @@
+/*
+ * 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.ir;
+
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
+
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation of a property access (period operator.)
+ *
+ */
+public class AccessNode extends BaseNode implements TypeOverride {
+    /** Property ident. */
+    private IdentNode property;
+
+    /** Does this node have a type override */
+    private boolean hasCallSiteType;
+
+    /**
+     * Constructor
+     *
+     * @param source    source code
+     * @param token     token
+     * @param finish    finish
+     * @param base      base node
+     * @param property  property
+     */
+    public AccessNode(final Source source, final long token, final int finish, final Node base, final IdentNode property) {
+        super(source, token, finish, base);
+
+        this.start    = base.getStart();
+        this.property = property;
+
+        this.property.setIsPropertyName();
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param accessNode  source node
+     */
+    public AccessNode(final AccessNode accessNode) {
+        this(accessNode, new CopyState());
+    }
+
+    /**
+     * Internal copy constructor
+     *
+     * @param accessNode  source node
+     * @param cs          copy state
+     */
+    protected AccessNode(final AccessNode accessNode, final CopyState cs) {
+        super(accessNode, cs);
+        this.property = (IdentNode)cs.existingOrCopy(accessNode.getProperty());
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new AccessNode(this, cs);
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!super.equals(other)) {
+            return false;
+        }
+        final AccessNode accessNode = (AccessNode)other;
+        return property.equals(accessNode.getProperty());
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ property.hashCode();
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            base = base.accept(visitor);
+            property = (IdentNode)property.accept(visitor);
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        final boolean needsParen = tokenType().needsParens(getBase().tokenType(), true);
+
+        if (hasCallSiteType) {
+            sb.append('{');
+            final String desc = getType().getDescriptor();
+            sb.append(desc.charAt(desc.length() - 1) == ';' ? "O" : getType().getDescriptor());
+            sb.append('}');
+        }
+
+        if (needsParen) {
+            sb.append('(');
+        }
+
+        base.toString(sb);
+
+        if (needsParen) {
+            sb.append(')');
+        }
+        sb.append('.');
+
+        sb.append(property.getName());
+    }
+
+    /**
+     * Get the property
+     *
+     * @return the property IdentNode
+     */
+    public IdentNode getProperty() {
+        return property;
+    }
+
+    @Override
+    public void setType(final Type type) {
+        if (DEBUG_FIELDS && !Type.areEquivalent(getSymbol().getSymbolType(), type)) {
+            ObjectClassGenerator.LOG.info(getClass().getName() + " " + this + " => " + type + " instead of " + getType());
+        }
+        property.setType(type);
+        getSymbol().setTypeOverride(type); //always a temp so this is fine.
+        hasCallSiteType = true;
+    }
+
+    @Override
+    public boolean canHaveCallSiteType() {
+        return true; //carried by the symbol and always the same nodetype==symboltype
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Assignment.java b/nashorn/src/jdk/nashorn/internal/ir/Assignment.java
new file mode 100644
index 0000000..8107a87
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/Assignment.java
@@ -0,0 +1,49 @@
+/*
+ * 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.ir;
+
+/**
+ * Can a node be an assignment under certain circumstances?
+ * Then it should implement this interface
+ *
+ * @param <D> the destination type
+ */
+public interface Assignment<D extends Node> {
+
+    /**
+     * Get assignment destination
+     *
+     * @return get the assignment destination node
+     */
+    public D getAssignmentDest();
+
+    /**
+     * Get the assignment source
+     *
+     * @return get the assignment source node
+     */
+    public Node getAssignmentSource();
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java
new file mode 100644
index 0000000..ea632d1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java
@@ -0,0 +1,101 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR base for accessing/indexing nodes.
+ *
+ * @see AccessNode
+ * @see IndexNode
+ */
+public abstract class BaseNode extends Node implements FunctionCall {
+
+    /** Base Node. */
+    protected Node base;
+
+    /**
+     * Constructor
+     *
+     * @param source source code
+     * @param token  token
+     * @param finish finish
+     * @param base   base node
+     */
+    public BaseNode(final Source source, final long token, final int finish, final Node base) {
+        super(source, token, finish);
+        this.base = base;
+        setStart(base.getStart());
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param baseNode the base node
+     * @param cs       a copy state
+     */
+    protected BaseNode(final BaseNode baseNode, final CopyState cs) {
+        super(baseNode);
+        this.base = cs.existingOrCopy(baseNode.getBase());
+        setStart(base.getStart());
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!super.equals(other)) {
+            return false;
+        }
+        final BaseNode baseNode = (BaseNode)other;
+        return base.equals(baseNode.getBase());
+    }
+
+    @Override
+    public int hashCode() {
+        return base.hashCode();
+    }
+
+    /**
+     * Get the base node for this access
+     * @return the base node
+     */
+    public Node getBase() {
+        return base;
+    }
+
+    /**
+     * Reset the base node for this access
+     * @param base new base node
+     */
+    public void setBase(final Node base) {
+        this.base = base;
+    }
+
+    @Override
+    public boolean isFunction() {
+        return false;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java
new file mode 100644
index 0000000..26964ba
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java
@@ -0,0 +1,236 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * BinaryNode nodes represent two operand operations.
+ */
+public class BinaryNode extends UnaryNode {
+    /** Left hand side argument. */
+    protected Node lhs;
+
+    /**
+     * Constructor
+     *
+     * @param source source code
+     * @param token  token
+     * @param lhs    left hand side
+     * @param rhs    right hand side
+     */
+    public BinaryNode(final Source source, final long token, final Node lhs, final Node rhs) {
+        super(source, token, rhs);
+
+        start  = lhs.getStart();
+        finish = rhs.getFinish();
+
+        this.lhs = lhs;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param binaryNode the binary node
+     * @param cs         copy state
+     */
+    protected BinaryNode(final BinaryNode binaryNode, final CopyState cs) {
+        super(binaryNode, cs);
+        lhs = cs.existingOrCopy(binaryNode.lhs);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new BinaryNode(this, cs);
+    }
+
+    /**
+     * Return the widest possible type for this operation. This is used for compile time
+     * static type inference
+     *
+     * @return Type
+     */
+    @Override
+    public Type getWidestOperationType() {
+        switch (tokenType()) {
+        case SHR:
+        case ASSIGN_SHR:
+            return Type.LONG;
+        case ASSIGN_SAR:
+        case ASSIGN_SHL:
+        case ASSIGN_BIT_AND:
+        case ASSIGN_BIT_OR:
+        case ASSIGN_BIT_XOR:
+        case SAR:
+        case SHL:
+            return Type.INT;
+        case DIV:
+        case MOD:
+        case MUL:
+        case ASSIGN_DIV:
+        case ASSIGN_MOD:
+        case ASSIGN_MUL:
+        case ASSIGN_SUB:
+            return Type.NUMBER;
+        default:
+            return Type.OBJECT;
+        }
+    }
+
+    /**
+     * Check if this node is an assigment
+     *
+     * @return true if this node assigns a value
+     */
+    @Override
+    public boolean isAssignment() {
+        switch (tokenType()) {
+        case ASSIGN:
+        case ASSIGN_ADD:
+        case ASSIGN_BIT_AND:
+        case ASSIGN_BIT_OR:
+        case ASSIGN_BIT_XOR:
+        case ASSIGN_DIV:
+        case ASSIGN_MOD:
+        case ASSIGN_MUL:
+        case ASSIGN_SAR:
+        case ASSIGN_SHL:
+        case ASSIGN_SHR:
+        case ASSIGN_SUB:
+           return true;
+        default:
+           return false;
+        }
+    }
+
+    @Override
+    public boolean isSelfModifying() {
+        return isAssignment() && tokenType() != TokenType.ASSIGN;
+    }
+
+    @Override
+    public Node getAssignmentDest() {
+        return isAssignment() ? lhs() : null;
+    }
+
+    @Override
+    public Node getAssignmentSource() {
+        return rhs();
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!super.equals(other)) {
+            return false;
+        }
+        return lhs.equals(((BinaryNode)other).lhs());
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ lhs().hashCode();
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            lhs = lhs.accept(visitor);
+            rhs = rhs.accept(visitor);
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        final TokenType type = tokenType();
+
+        final boolean lhsParen = type.needsParens(lhs().tokenType(), true);
+        final boolean rhsParen = type.needsParens(rhs().tokenType(), false);
+
+        if (lhsParen) {
+            sb.append('(');
+        }
+
+        lhs().toString(sb);
+
+        if (lhsParen) {
+            sb.append(')');
+        }
+
+        sb.append(' ');
+
+        switch (type) {
+        case COMMALEFT:
+            sb.append(",<");
+            break;
+        case COMMARIGHT:
+            sb.append(",>");
+            break;
+        case INCPREFIX:
+        case DECPREFIX:
+            sb.append("++");
+            break;
+        default:
+            sb.append(type.getName());
+            break;
+        }
+
+        sb.append(' ');
+
+        if (rhsParen) {
+            sb.append('(');
+        }
+        rhs().toString(sb);
+        if (rhsParen) {
+            sb.append(')');
+        }
+    }
+
+    /**
+     * Get the left hand side expression for this node
+     * @return the left hand side expression
+     */
+    public Node lhs() {
+        return lhs;
+    }
+
+    /**
+     * Set the left hand side expression for this node
+     * @param lhs new left hand side expression
+     */
+    public void setLHS(final Node lhs) {
+        this.lhs = lhs;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Block.java b/nashorn/src/jdk/nashorn/internal/ir/Block.java
new file mode 100644
index 0000000..9449be5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/Block.java
@@ -0,0 +1,588 @@
+/*
+ * 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.ir;
+
+import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL;
+import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
+import static jdk.nashorn.internal.ir.Symbol.IS_LET;
+import static jdk.nashorn.internal.ir.Symbol.IS_PARAM;
+import static jdk.nashorn.internal.ir.Symbol.IS_SCOPE;
+import static jdk.nashorn.internal.ir.Symbol.IS_VAR;
+import static jdk.nashorn.internal.ir.Symbol.KINDMASK;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import jdk.nashorn.internal.codegen.Frame;
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.annotations.ParentNode;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for a list of statements and functions. All provides the
+ * basis for script body.
+ *
+ */
+public class Block extends Node {
+    /** Parent context */
+    @ParentNode @Ignore
+    private Block parent;
+
+    /** Owning function. */
+    @Ignore //don't print it, it is apparent in the tree
+    protected FunctionNode function;
+
+    /** List of statements */
+    protected List<Node> statements;
+
+    /** Symbol table. */
+    protected final HashMap<String, Symbol> symbols;
+
+    /** Variable frame. */
+    protected Frame frame;
+
+    /** Entry label. */
+    protected final Label entryLabel;
+
+    /** Break label. */
+    protected final Label breakLabel;
+
+    /** Does the block/function need a new scope? */
+    protected boolean needsScope;
+
+    /**
+     * Constructor
+     *
+     * @param source   source code
+     * @param token    token
+     * @param finish   finish
+     * @param parent   reference to parent block
+     * @param function function node this block is in
+     */
+    public Block(final Source source, final long token, final int finish, final Block parent, final FunctionNode function) {
+        super(source, token, finish);
+
+        this.parent     = parent;
+        this.function   = function;
+        this.statements = new ArrayList<>();
+        this.symbols    = new HashMap<>();
+        this.entryLabel = new Label("block_entry");
+        this.breakLabel = new Label("block_break");
+    }
+
+    /**
+     * Internal copy constructor
+     *
+     * @param block the source block
+     * @param cs    the copy state
+     */
+    protected Block(final Block block, final CopyState cs) {
+        super(block);
+
+        this.parent     = block.parent;
+        this.function   = block.function;
+        this.statements = new ArrayList<>();
+        for (final Node statement : block.getStatements()) {
+            statements.add(cs.existingOrCopy(statement));
+        }
+        this.symbols    = new HashMap<>();
+        this.frame      = block.frame == null ? null : block.frame.copy();
+        this.entryLabel = new Label(block.entryLabel);
+        this.breakLabel = new Label(block.breakLabel);
+
+        assert block.symbols.isEmpty() : "must not clone with symbols";
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return fixBlockChain(new Block(this, cs));
+    }
+
+    /**
+     * Whenever a clone that contains a hierarchy of blocks is created,
+     * this function has to be called to ensure that the parents point
+     * to the correct parent blocks or two different ASTs would not
+     * be completely separated.
+     *
+     * @return the argument
+     */
+    static Block fixBlockChain(final Block root) {
+        root.accept(new NodeVisitor() {
+            private Block        parent   = root.getParent();
+            private final FunctionNode function = root.getFunction();
+
+            @Override
+            public Node enter(final Block block) {
+                assert block.getFunction() == function;
+                block.setParent(parent);
+                parent = block;
+
+                return block;
+            }
+
+            @Override
+            public Node leave(final Block block) {
+                parent = block.getParent();
+
+                return block;
+            }
+
+            @Override
+            public Node enter(final FunctionNode functionNode) {
+                assert functionNode.getFunction() == function;
+
+                return enter((Block)functionNode);
+            }
+
+            @Override
+            public Node leave(final FunctionNode functionNode) {
+                assert functionNode.getFunction() == function;
+
+                return leave((Block)functionNode);
+            }
+
+        });
+
+        return root;
+    }
+
+    /**
+     * Add a new statement to the statement list.
+     *
+     * @param statement Statement node to add.
+     */
+    public void addStatement(final Node statement) {
+        if (statement != null) {
+            statements.add(statement);
+            if (getFinish() < statement.getFinish()) {
+                setFinish(statement.getFinish());
+            }
+        }
+    }
+
+    /**
+     * Prepend a statement to the statement list
+     *
+     * @param statement Statement node to add
+     */
+    public void prependStatement(final Node statement) {
+        if (statement != null) {
+            final List<Node> newStatements = new ArrayList<>();
+            newStatements.add(statement);
+            newStatements.addAll(statements);
+            setStatements(newStatements);
+        }
+    }
+
+    /**
+     * Add a list of statements to the statement list.
+     *
+     * @param statementList Statement nodes to add.
+     */
+    public void addStatements(final List<Node> statementList) {
+        statements.addAll(statementList);
+    }
+
+    /**
+     * Add a new function to the function list.
+     *
+     * @param functionNode Function node to add.
+     */
+    public void addFunction(final FunctionNode functionNode) {
+        assert parent != null : "Parent context missing.";
+
+        parent.addFunction(functionNode);
+    }
+
+    /**
+     * Add a list of functions to the function list.
+     *
+     * @param functionNodes Function nodes to add.
+     */
+    public void addFunctions(final List<FunctionNode> functionNodes) {
+        assert parent != null : "Parent context missing.";
+
+        parent.addFunctions(functionNodes);
+    }
+
+    /**
+     * Set the function list to a new one
+     *
+     * @param functionNodes the nodes to set
+     */
+    public void setFunctions(final List<FunctionNode> functionNodes) {
+        assert parent != null : "Parent context missing.";
+
+        parent.setFunctions(functionNodes);
+    }
+
+    /**
+     * Assist in IR navigation.
+     *
+     * @param visitor IR navigating visitor.
+     * @return new or same node
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        final Block saveBlock = visitor.getCurrentBlock();
+        visitor.setCurrentBlock(this);
+
+        try {
+            // Ignore parent to avoid recursion.
+
+            if (visitor.enter(this) != null) {
+                for (int i = 0, count = statements.size(); i < count; i++) {
+                    final Node statement = statements.get(i);
+                    statements.set(i, statement.accept(visitor));
+                }
+
+                return visitor.leave(this);
+            }
+        } finally {
+            visitor.setCurrentBlock(saveBlock);
+        }
+
+        return this;
+    }
+
+    /**
+     * Search for symbol.
+     *
+     * @param name Symbol name.
+     *
+     * @return Found symbol or null if not found.
+     */
+    public Symbol findSymbol(final String name) {
+        // Search up block chain to locate symbol.
+
+        for (Block block = this; block != null; block = block.getParent()) {
+            // Find name.
+            final Symbol symbol = block.symbols.get(name);
+            // If found then we are good.
+            if (symbol != null) {
+                return symbol;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Search for symbol in current function.
+     *
+     * @param name Symbol name.
+     *
+     * @return Found symbol or null if not found.
+     */
+    public Symbol findLocalSymbol(final String name) {
+        // Search up block chain to locate symbol.
+        for (Block block = this; block != null; block = block.getParent()) {
+            // Find name.
+            final Symbol symbol = block.symbols.get(name);
+            // If found then we are good.
+            if (symbol != null) {
+                return symbol;
+            }
+
+            // If searched function then we are done.
+            if (block == block.function) {
+                break;
+            }
+        }
+
+        // Not found.
+        return null;
+    }
+
+    /**
+     * Test if this block represents a <tt>catch</tt> block in a <tt>try</tt> statement.
+     * This is used by the Splitter as catch blocks are not be subject to splitting.
+     *
+     * @return true if this block represents a catch block in a try statement.
+     */
+    public boolean isCatchBlock() {
+        return statements.size() == 1 && statements.get(0) instanceof CatchNode;
+    }
+
+    /**
+     * Test to see if a symbol is local to the function.
+     *
+     * @param symbol Symbol to test.
+     * @return True if a local symbol.
+     */
+    public boolean isLocal(final Symbol symbol) {
+        // some temp symbols have no block, so can be assumed local
+        final Block block = symbol.getBlock();
+        return block == null || block.getFunction() == function;
+    }
+
+    /**
+     * Declare the definition of a new symbol.
+     *
+     * @param name         Name of symbol.
+     * @param symbolFlags  Symbol flags.
+     * @param node         Defining Node.
+     *
+     * @return Symbol for given name or null for redefinition.
+     */
+    public Symbol defineSymbol(final String name, final int symbolFlags, final Node node) {
+        int    flags  = symbolFlags;
+        Symbol symbol = findSymbol(name); // Locate symbol.
+
+        if ((flags & KINDMASK) == IS_GLOBAL) {
+            flags |= IS_SCOPE;
+        }
+
+        if (symbol != null) {
+            // Symbol was already defined. Check if it needs to be redefined.
+            if ((flags & KINDMASK) == IS_PARAM) {
+                if (!function.isLocal(symbol)) {
+                    // Not defined in this function. Create a new definition.
+                    symbol = null;
+                } else if (symbol.isParam()) {
+                    // Duplicate parameter. Null return will force an error.
+                    assert false : "duplicate parameter";
+                    return null;
+                }
+            } else if ((flags & KINDMASK) == IS_VAR) {
+                if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & Symbol.IS_LET) == Symbol.IS_LET) {
+                    assert !((flags & IS_LET) == IS_LET && symbol.getBlock() == this) : "duplicate let variable in block";
+                    // Always create a new definition.
+                    symbol = null;
+                } else {
+                    // Not defined in this function. Create a new definition.
+                    if (!function.isLocal(symbol) || symbol.less(IS_VAR)) {
+                        symbol = null;
+                    }
+                }
+            }
+        }
+
+        if (symbol == null) {
+            // If not found, then create a new one.
+            Block symbolBlock;
+
+            // Determine where to create it.
+            if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
+                symbolBlock = this;
+            } else {
+                symbolBlock = getFunction();
+            }
+
+            // Create and add to appropriate block.
+            symbol = new Symbol(name, flags, node, symbolBlock);
+            symbolBlock.putSymbol(name, symbol);
+
+            if ((flags & Symbol.KINDMASK) != IS_GLOBAL) {
+                symbolBlock.getFrame().addSymbol(symbol);
+                symbol.setNeedsSlot(true);
+            }
+        } else if (symbol.less(flags)) {
+            symbol.setFlags(flags);
+        }
+
+        if (node != null) {
+            node.setSymbol(symbol);
+        }
+
+        return symbol;
+    }
+
+    /**
+     * Declare the use of a symbol.
+     *
+     * @param name Name of symbol.
+     * @param node Using node
+     *
+     * @return Symbol for given name.
+     */
+    public Symbol useSymbol(final String name, final Node node) {
+        Symbol symbol = findSymbol(name);
+
+        if (symbol == null) {
+            // If not found, declare as a free var.
+            symbol = defineSymbol(name, IS_GLOBAL, node);
+        } else {
+            node.setSymbol(symbol);
+        }
+
+        return symbol;
+    }
+
+    /**
+     * Add parent name to the builder.
+     *
+     * @param sb String bulder.
+     */
+    public void addParentName(final StringBuilder sb) {
+        if (parent != null) {
+            parent.addParentName(sb);
+        }
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        for (final Node statement : statements) {
+            statement.toString(sb);
+            sb.append(';');
+        }
+    }
+
+    /**
+     * Print symbols in block in alphabetical order, sorted on name
+     * Used for debugging, see the --print-symbols flag
+     *
+     * @param stream print writer to output symbols to
+     *
+     * @return true if symbols were found
+     */
+    public boolean printSymbols(final PrintWriter stream) {
+        final List<Symbol> values = new ArrayList<>(symbols.values());
+
+        Collections.sort(values, new Comparator<Symbol>() {
+            @Override
+            public int compare(final Symbol s0, final Symbol s1) {
+                return s0.getName().compareTo(s1.getName());
+            }
+        });
+
+        for (final Symbol symbol : values) {
+            symbol.print(stream);
+        }
+
+        return !values.isEmpty();
+    }
+
+    /**
+     * Get the break label for this block
+     * @return the break label
+     */
+    public Label getBreakLabel() {
+        return breakLabel;
+    }
+
+    /**
+     * Get the entry label for this block
+     * @return the entry label
+     */
+    public Label getEntryLabel() {
+        return entryLabel;
+    }
+
+    /**
+     * Get the frame for this block
+     * @return the frame
+     */
+    public Frame getFrame() {
+        return frame;
+    }
+
+    /**
+     * Get the FunctionNode for this block, i.e. the function it
+     * belongs to
+     *
+     * @return the function node
+     */
+    public FunctionNode getFunction() {
+        return function;
+    }
+
+    /**
+     * Reset the frame for this block
+     *
+     * @param frame  the new frame
+     */
+    public void setFrame(final Frame frame) {
+        this.frame = frame;
+    }
+
+    /**
+     * Get the parent block
+     *
+     * @return parent block, or null if none exists
+     */
+    public Block getParent() {
+        return parent;
+    }
+
+    /**
+     * Set the parent block
+     *
+     * @param parent the new parent block
+     */
+    public void setParent(final Block parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Get the list of statements in this block
+     *
+     * @return a list of statements
+     */
+    public List<Node> getStatements() {
+        return Collections.unmodifiableList(statements);
+    }
+
+    /**
+     * Reset the statement list for this block
+     *
+     * @param statements  new statement list
+     */
+    public void setStatements(final List<Node> statements) {
+        this.statements = statements;
+    }
+
+    /**
+     * Add or overwrite an existing symbol in the block
+     *
+     * @param name   name of symbol
+     * @param symbol symbol
+     */
+    public void putSymbol(final String name, final Symbol symbol) {
+        symbols.put(name, symbol);
+    }
+
+    /**
+     * Check whether scope is necessary for this Block
+     *
+     * @return true if this function needs a scope
+     */
+    public boolean needsScope() {
+        return needsScope;
+    }
+
+    /**
+     * Set the needs scope flag.
+     */
+    public void setNeedsScope() {
+        needsScope = true;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java b/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java
new file mode 100644
index 0000000..81c572d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java
@@ -0,0 +1,97 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for {@code break} statements.
+ */
+public class BreakNode extends LabeledNode {
+
+     /**
+     * Constructor
+     *
+     * @param source     source code
+     * @param token      token
+     * @param finish     finish
+     * @param labelNode  break label
+     * @param targetNode node to break to
+     * @param tryChain   surrounding try chain
+     */
+    public BreakNode(final Source source, final long token, final int finish, final LabelNode labelNode, final Node targetNode, final TryNode tryChain) {
+        super(source, token, finish, labelNode, targetNode, tryChain);
+        setHasGoto();
+    }
+
+    private BreakNode(final BreakNode breakNode, final CopyState cs) {
+        super(breakNode, cs);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new BreakNode(this, cs);
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    /**
+     * Return the target label of this break node.
+     * @return the target label.
+     */
+    public Label getTargetLabel() {
+        if (targetNode instanceof BreakableNode) {
+            return ((BreakableNode)targetNode).getBreakLabel();
+        } else if (targetNode instanceof Block) {
+            return ((Block)targetNode).getBreakLabel();
+        }
+
+        throw new AssertionError("Invalid break target " + targetNode.getClass());
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("break");
+
+        if (labelNode != null) {
+            sb.append(' ');
+            labelNode.getLabel().toString(sb);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java b/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java
new file mode 100644
index 0000000..d15b756
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java
@@ -0,0 +1,68 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * This class represents a node from which control flow can execute
+ * a {@code break} statement
+ */
+public abstract class BreakableNode extends Node {
+
+    /** break label. */
+    protected Label breakLabel;
+
+    /**
+     * Constructor
+     *
+     * @param source   source code
+     * @param token    token
+     * @param finish   finish
+     */
+    public BreakableNode(final Source source, final long token, final int finish) {
+        super(source, token, finish);
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param breakableNode source node
+     */
+    protected BreakableNode(final BreakableNode breakableNode) {
+        super(breakableNode);
+    }
+
+    /**
+     * Return the break label, i.e. the location to go to on break.
+     * @return the break label
+     */
+    public Label getBreakLabel() {
+        return breakLabel;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/CallNode.java b/nashorn/src/jdk/nashorn/internal/ir/CallNode.java
new file mode 100644
index 0000000..387369e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/CallNode.java
@@ -0,0 +1,339 @@
+/*
+ * 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.ir;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for a function call.
+ *
+ */
+public class CallNode extends Node implements TypeOverride {
+
+    private Type type;
+
+    /** Function identifier or function body. */
+    private Node function;
+
+    /** Call arguments. */
+    private List<Node> args;
+
+    /** flag - is new expression */
+    private boolean isNew;
+
+    /** flag - is in with block */
+    private boolean inWithBlock;
+
+    /**
+     * Arguments to be passed to builtin {@code eval} function
+     */
+    public static class EvalArgs {
+        /** evaluated code */
+        private Node code;
+
+        /** 'this' passed to evaluated code */
+        private IdentNode evalThis;
+
+        /** location string for the eval call */
+        final private String location;
+
+        /** is this call from a strict context? */
+        final private boolean strictMode;
+
+        /**
+         * Constructor
+         *
+         * @param code       code to evaluate
+         * @param evalThis   this node
+         * @param location   location for the eval call
+         * @param strictMode is this a call from a strict context?
+         */
+        public EvalArgs(final Node code, final IdentNode evalThis, final String location, final boolean strictMode) {
+            this.code = code;
+            this.evalThis = evalThis;
+            this.location = location;
+            this.strictMode = strictMode;
+        }
+
+        /**
+         * Return the code that is to be eval:ed by this eval function
+         * @return code as an AST node
+         */
+        public Node getCode() {
+            return code;
+        }
+
+        /**
+         * Set the code that is to be eval.ed by this eval function
+         * @param code the code as an AST node
+         */
+        public void setCode(final Node code) {
+            this.code = code;
+        }
+
+        /**
+         * Get the {@code this} symbol used to invoke this eval call
+         * @return the {@code this} symbol
+         */
+        public IdentNode getThis() {
+            return this.evalThis;
+        }
+
+        /**
+         * Set the {@code this} symbol used to invoke this eval call
+         * @param evalThis the {@code this} symbol
+         */
+        public void setThis(final IdentNode evalThis) {
+            this.evalThis = evalThis;
+        }
+
+        /**
+         * Get the human readable location for this eval call
+         * @return the location
+         */
+        public String getLocation() {
+            return this.location;
+        }
+
+        /**
+         * Check whether this eval call is executed in strict mode
+         * @return true if executed in strict mode, false otherwise
+         */
+        public boolean getStrictMode() {
+            return this.strictMode;
+        }
+    }
+
+    /** arguments for 'eval' call. Non-null only if this call node is 'eval' */
+    @Ignore
+    private EvalArgs evalArgs;
+
+    /**
+     * Constructors
+     *
+     * @param source   the source
+     * @param token    token
+     * @param finish   finish
+     * @param function the function to call
+     * @param args     args to the call
+     */
+    public CallNode(final Source source, final long token, final int finish, final Node function, final List<Node> args) {
+        super(source, token, finish);
+
+        setStart(function.getStart());
+
+        this.function     = function;
+        this.args         = args;
+    }
+
+    private CallNode(final CallNode callNode, final CopyState cs) {
+        super(callNode);
+
+        final List<Node> newArgs = new ArrayList<>();
+
+        for (final Node arg : callNode.args) {
+            newArgs.add(cs.existingOrCopy(arg));
+        }
+
+        this.function     = cs.existingOrCopy(callNode.function);     //TODO existing or same?
+        this.args         = newArgs;
+        this.isNew        = callNode.isNew;
+        this.inWithBlock  = callNode.inWithBlock;
+    }
+
+
+    @Override
+    public Type getType() {
+        if (hasCallSiteType()) {
+            return type;
+        }
+        assert !function.getType().isUnknown();
+        return function.getType();
+    }
+
+    @Override
+    public void setType(final Type type) {
+        this.type = type;
+    }
+
+    private boolean hasCallSiteType() {
+        return this.type != null;
+    }
+
+    @Override
+    public boolean canHaveCallSiteType() {
+        return true;
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new CallNode(this, cs);
+    }
+
+    /**
+     * Assist in IR navigation.
+     *
+     * @param visitor IR navigating visitor.
+     *
+     * @return node or replacement
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            function = function.accept(visitor);
+
+            for (int i = 0, count = args.size(); i < count; i++) {
+                args.set(i, args.get(i).accept(visitor));
+            }
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        if (hasCallSiteType()) {
+            sb.append('{');
+            final String desc = getType().getDescriptor();
+            sb.append(desc.charAt(desc.length() - 1) == ';' ? "O" : getType().getDescriptor());
+            sb.append('}');
+        }
+
+        function.toString(sb);
+
+        sb.append('(');
+
+        boolean first = true;
+
+        for (final Node arg : args) {
+            if (!first) {
+                sb.append(", ");
+            } else {
+                first = false;
+            }
+
+            arg.toString(sb);
+        }
+
+        sb.append(')');
+    }
+
+    /**
+     * Get the arguments for the call
+     * @return a list of arguments
+     */
+    public List<Node> getArgs() {
+        return Collections.unmodifiableList(args);
+    }
+
+    /**
+     * Reset the arguments for the call
+     * @param args new arguments list
+     */
+    public void setArgs(final List<Node> args) {
+        this.args = args;
+    }
+
+    /**
+     * If this call is an {@code eval} call, get its EvalArgs structure
+     * @return EvalArgs for call
+     */
+    public EvalArgs getEvalArgs() {
+        return evalArgs;
+    }
+
+    /**
+     * Set the EvalArgs structure for this call, if it has been determined it is an
+     * {@code eval}
+     *
+     * @param evalArgs eval args
+     */
+    public void setEvalArgs(final EvalArgs evalArgs) {
+        this.evalArgs = evalArgs;
+    }
+
+    /**
+     * Check if this call is a call to {@code eval}
+     * @return true if this is a call to {@code eval}
+     */
+    public boolean isEval() {
+        return evalArgs != null;
+    }
+
+    /**
+     * Return the function expression that this call invokes
+     * @return the function
+     */
+    public Node getFunction() {
+        return function;
+    }
+
+    /**
+     * Reset the function expression that this call invokes
+     * @param node the function
+     */
+    public void setFunction(final Node node) {
+        function = node;
+    }
+
+    /**
+     * Check if this call is a new operation
+     * @return true if this a new operation
+     */
+    public boolean isNew() {
+        return isNew;
+    }
+
+    /**
+     * Flag this call as a new operation
+     */
+    public void setIsNew() {
+        this.isNew = true;
+    }
+
+    /**
+     * Check if this call is inside a {@code with} block
+     * @return true if the call is inside a {@code with} block
+     */
+    public boolean inWithBlock() {
+        return inWithBlock;
+    }
+
+    /**
+     * Flag this call to be inside a {@code with} block
+     */
+    public void setInWithBlock() {
+        this.inWithBlock = true;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java b/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java
new file mode 100644
index 0000000..928ba5b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java
@@ -0,0 +1,138 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation of CASE clause.
+ *
+ */
+public class CaseNode extends BreakableNode {
+    /** Test expression. */
+    private Node test;
+
+    /** Statements. */
+    private Block body;
+
+    /** Case entry label. */
+    private final Label entry;
+
+    /**
+     * Constructors
+     *
+     * @param source   the source
+     * @param token    token
+     * @param finish   finish
+     * @param test     case test node, can be any node in JavaScript
+     * @param body     case body
+     */
+    public CaseNode(final Source source, final long token, final int finish, final Node test, final Block body) {
+        super(source, token, finish);
+
+        this.test  = test;
+        this.body  = body;
+        this.entry = new Label("entry");
+    }
+
+    private CaseNode(final CaseNode caseNode, final CopyState cs) {
+        super(caseNode);
+
+        this.test  = cs.existingOrCopy(caseNode.test);
+        this.body  = (Block)cs.existingOrCopy(caseNode.body);
+        this.entry = new Label(caseNode.entry);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new CaseNode(this, cs);
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            if (test != null) {
+                test = test.accept(visitor);
+            }
+            if (body != null) {
+                body = (Block)body.accept(visitor);
+            }
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        if (test != null) {
+            sb.append("case ");
+            test.toString(sb);
+            sb.append(':');
+        } else {
+            sb.append("default:");
+        }
+    }
+
+    /**
+     * Get the body for this case node
+     * @return the body
+     */
+    public Block getBody() {
+        return body;
+    }
+
+    /**
+     * Get the entry label for this case node
+     * @return the entry label
+     */
+    public Label getEntry() {
+        return entry;
+    }
+
+    /**
+     * Get the test expression for this case node
+     * @return the test
+     */
+    public Node getTest() {
+        return test;
+    }
+
+    /**
+     * Reset the test expression for this case node
+     * @param test new test expression
+     */
+    public void setTest(final Node test) {
+        this.test = test;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java b/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java
new file mode 100644
index 0000000..187c394
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java
@@ -0,0 +1,161 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation of a catch clause.
+ *
+ */
+public class CatchNode extends Node {
+    /** Exception identifier. */
+    private IdentNode exception;
+
+    /** Exception condition. */
+    private Node exceptionCondition;
+
+    /** Catch body. */
+    private Block body;
+
+    /** Is rethrow - e.g. synthetic catch block for e.g. finallies, the parser case where
+     * there has to be at least on catch for syntactic validity */
+    private boolean isSyntheticRethrow;
+
+    /**
+     * Constructors
+     *
+     * @param source             the source
+     * @param token              token
+     * @param finish             finish
+     * @param exception          variable name of exception
+     * @param exceptionCondition exception condition
+     * @param body               catch body
+     */
+    public CatchNode(final Source source, final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body) {
+        super(source, token, finish);
+
+        this.exception          = exception;
+        this.exceptionCondition = exceptionCondition;
+        this.body               = body;
+    }
+
+    private CatchNode(final CatchNode catchNode, final CopyState cs) {
+        super(catchNode);
+
+        this.exception          = (IdentNode)cs.existingOrCopy(catchNode.exception);
+        this.exceptionCondition = cs.existingOrCopy(catchNode.exceptionCondition);
+        this.body               = (Block)cs.existingOrCopy(catchNode.body);
+        this.isSyntheticRethrow = catchNode.isSyntheticRethrow;
+     }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new CatchNode(this, cs);
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            exception = (IdentNode)exception.accept(visitor);
+
+            if (exceptionCondition != null) {
+                exceptionCondition = exceptionCondition.accept(visitor);
+            }
+
+            body = (Block)body.accept(visitor);
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append(" catch (");
+        exception.toString(sb);
+
+        if (exceptionCondition != null) {
+            sb.append(" if ");
+            exceptionCondition.toString(sb);
+        }
+        sb.append(')');
+    }
+
+    /**
+     * Check if this catch is a synthetic rethrow
+     * @return true if this is a synthetic rethrow
+     */
+    public boolean isSyntheticRethrow() {
+        return isSyntheticRethrow;
+    }
+
+    /**
+     * Flag this as deliberatly generated catch all that rethrows the
+     * caught exception. This is used for example for generating finally
+     * expressions
+     */
+    public void setIsSyntheticRethrow() {
+        this.isSyntheticRethrow = true;
+    }
+
+    /**
+     * Get the identifier representing the exception thrown
+     * @return the exception identifier
+     */
+    public IdentNode getException() {
+        return exception;
+    }
+
+    /**
+     * Get the exception condition for this catch block
+     * @return the exception condition
+     */
+    public Node getExceptionCondition() {
+        return exceptionCondition;
+    }
+
+    /**
+     * Reset the exception condition for this catch block
+     * @param exceptionCondition the new exception condition
+     */
+    public void setExceptionCondition(final Node exceptionCondition) {
+        this.exceptionCondition = exceptionCondition;
+    }
+
+    /**
+     * Get the body for this catch block
+     * @return the catch block body
+     */
+    public Block getBody() {
+        return body;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java b/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java
new file mode 100644
index 0000000..2063d6b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java
@@ -0,0 +1,90 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for CONTINUE statements.
+ *
+ */
+public class ContinueNode extends LabeledNode {
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param finish     finish
+     * @param labelNode  the continue label
+     * @param targetNode node to continue to
+     * @param tryChain   surrounding try chain
+     */
+    public ContinueNode(final Source source, final long token, final int finish, final LabelNode labelNode, final Node targetNode, final TryNode tryChain) {
+        super(source, token, finish, labelNode, targetNode, tryChain);
+        setHasGoto();
+    }
+
+    private ContinueNode(final ContinueNode continueNode, final CopyState cs) {
+        super(continueNode, cs);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new ContinueNode(this, cs);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    /**
+     * Return the target label of this continue node.
+     * @return the target label.
+     */
+    public Label getTargetLabel() {
+        assert targetNode instanceof WhileNode : "continue target must be a while node";
+        return ((WhileNode)targetNode).getContinueLabel();
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("continue");
+
+        if (labelNode != null) {
+            sb.append(' ');
+            labelNode.getLabel().toString(sb);
+        }
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/ir/DoWhileNode.java b/nashorn/src/jdk/nashorn/internal/ir/DoWhileNode.java
new file mode 100644
index 0000000..476643a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/DoWhileNode.java
@@ -0,0 +1,82 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * Loop representing do while loops. This is mostly split from WhileNode
+ * because of the different order of the Phi Traversals
+ *
+ */
+public class DoWhileNode extends WhileNode {
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param finish     finish
+     */
+    public DoWhileNode(final Source source, final long token, final int finish) {
+        super(source, token, finish);
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param doWhileNode source node
+     * @param cs          copy state
+     */
+    protected DoWhileNode(final DoWhileNode doWhileNode, final CopyState cs) {
+        super(doWhileNode, cs);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new DoWhileNode(this, cs);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            body = (Block)body.accept(visitor);
+            test = test.accept(visitor);
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("while (");
+        test.toString(sb);
+        sb.append(')');
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java b/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java
new file mode 100644
index 0000000..0bfacd5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java
@@ -0,0 +1,71 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for an empty statement.
+ *
+ */
+public class EmptyNode extends Node {
+
+    /**
+     * Constructor
+     *
+     * @param node node to wrap
+     */
+    public EmptyNode(final Node node) {
+        super(node);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param finish     finish
+     */
+    public EmptyNode(final Source source, final long token, final int finish) {
+        super(source, token, finish);
+    }
+
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            return visitor.leave(this);
+        }
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append(';');
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java b/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java
new file mode 100644
index 0000000..501468b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java
@@ -0,0 +1,116 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for executing bare expressions. Basically, an expression
+ * node means "this code will be executed" and evaluating it results in
+ * statements being added to the IR
+ */
+public class ExecuteNode extends Node {
+    /** Expression to execute. */
+    private Node expression;
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param finish     finish
+     * @param expression the expression to execute
+     */
+    public ExecuteNode(final Source source, final long token, final int finish, final Node expression) {
+        super(source, token, finish);
+        this.expression = expression;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param expression an expression to wrap, from which source, tokens and finish are also inherited
+     */
+    public ExecuteNode(final Node expression) {
+        super(expression.getSource(), expression.getToken(), expression.getFinish());
+        this.expression = expression;
+    }
+
+    private ExecuteNode(final ExecuteNode executeNode, final CopyState cs) {
+        super(executeNode);
+        this.expression = cs.existingOrCopy(executeNode.expression);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new ExecuteNode(this, cs);
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!super.equals(other)) {
+            return false;
+        }
+        return expression.equals(((ExecuteNode)other).getExpression());
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ expression.hashCode();
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            setExpression(expression.accept(visitor));
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        expression.toString(sb);
+    }
+
+    /**
+     * Return the expression to be executed
+     * @return the expression
+     */
+    public Node getExpression() {
+        return expression;
+    }
+
+    /**
+     * Reset the expression to be executed
+     * @param expression the expression
+     */
+    public void setExpression(final Node expression) {
+        this.expression = expression;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ForNode.java b/nashorn/src/jdk/nashorn/internal/ir/ForNode.java
new file mode 100644
index 0000000..53b5675
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/ForNode.java
@@ -0,0 +1,213 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representing a FOR statement.
+ *
+ */
+public class ForNode extends WhileNode {
+    /** Initialize expression. */
+    private Node init;
+
+    /** Test expression. */
+    private Node modify;
+
+    /** Iterator symbol. */
+    private Symbol iterator;
+
+    /** is for in */
+    private boolean isForIn;
+
+    /** is for each */
+    private boolean isForEach;
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param finish     finish
+     */
+    public ForNode(final Source source, final long token, final int finish) {
+        super(source, token, finish);
+    }
+
+    private ForNode(final ForNode forNode, final CopyState cs) {
+        super(forNode, cs);
+
+        this.init      = cs.existingOrCopy(forNode.init);
+        this.modify    = cs.existingOrCopy(forNode.modify);
+        this.iterator  = forNode.iterator;
+        this.isForIn   = forNode.isForIn;
+        this.isForEach = forNode.isForEach;
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new ForNode(this, cs);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            if (init != null) {
+                init = init.accept(visitor);
+            }
+
+            if (test != null) {
+                test = test.accept(visitor);
+            }
+
+            if (modify != null) {
+                modify = modify.accept(visitor);
+            }
+
+            body = (Block)body.accept(visitor);
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("for (");
+
+        if (isForIn()) {
+            init.toString(sb);
+            sb.append(" in ");
+            modify.toString(sb);
+        } else {
+            if (init != null) {
+                init.toString(sb);
+            }
+            sb.append("; ");
+            if (test != null) {
+                test.toString(sb);
+            }
+            sb.append("; ");
+            if (modify != null) {
+                modify.toString(sb);
+            }
+        }
+
+        sb.append(')');
+    }
+
+    /**
+     * Get the initialization expression for this for loop
+     * @return the initialization expression
+     */
+    public Node getInit() {
+        return init;
+    }
+
+    /**
+     * Reset the initialization expression for this for loop
+     * @param init new initialization expression
+     */
+    public void setInit(final Node init) {
+        this.init = init;
+    }
+
+    /**
+     * Is this a for in construct rather than a standard init;condition;modification one
+     * @return true if this is a for in constructor
+     */
+    public boolean isForIn() {
+        return isForIn;
+    }
+
+    /**
+     * Flag this to be a for in construct
+     */
+    public void setIsForIn() {
+        this.isForIn = true;
+    }
+
+    /**
+     * Is this a for each construct, known from e.g. Rhino. This will be a for of construct
+     * in ECMAScript 6
+     * @return true if this is a for each construct
+     */
+    public boolean isForEach() {
+        return isForEach;
+    }
+
+    /**
+     * Flag this to be a for each construct
+     */
+    public void setIsForEach() {
+        this.isForEach = true;
+    }
+
+    /**
+     * If this is a for in or for each construct, there is an iterator symbol
+     * @return the symbol for the iterator to be used, or null if none exists
+     */
+    public Symbol getIterator() {
+        return iterator;
+    }
+
+    /**
+     * Assign an iterator symbol to this ForNode. Used for for in and for each constructs
+     * @param iterator the iterator symbol
+     */
+    public void setIterator(final Symbol iterator) {
+        this.iterator = iterator;
+    }
+
+    /**
+     * Get the modification expression for this ForNode
+     * @return the modification expression
+     */
+    public Node getModify() {
+        return modify;
+    }
+
+    /**
+     * Reset the modification expression for this ForNode
+     * @param modify new modification expression
+     */
+    public void setModify(final Node modify) {
+        this.modify = modify;
+    }
+
+    @Override
+    public Node getTest() {
+        return test;
+    }
+
+    @Override
+    public void setTest(final Node test) {
+        this.test = test;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionCall.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionCall.java
new file mode 100644
index 0000000..73a6c62
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionCall.java
@@ -0,0 +1,39 @@
+/*
+ * 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.ir;
+
+/**
+ * Interface used by AccessNodes, IndexNodes and IdentNodes to signal
+ * that they are function calls
+ */
+public interface FunctionCall {
+    /**
+     * Return true if this function call implementor is a function
+     *
+     * @return true if implements a function call
+     */
+    public boolean isFunction();
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
new file mode 100644
index 0000000..d928aa7
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
@@ -0,0 +1,1289 @@
+/*
+ * 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.ir;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.LITERAL_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.TEMP_PREFIX;
+import static jdk.nashorn.internal.ir.Symbol.IS_CONSTANT;
+import static jdk.nashorn.internal.ir.Symbol.IS_TEMP;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+import jdk.nashorn.internal.codegen.CompileUnit;
+import jdk.nashorn.internal.codegen.Compiler;
+import jdk.nashorn.internal.codegen.Frame;
+import jdk.nashorn.internal.codegen.MethodEmitter;
+import jdk.nashorn.internal.codegen.Namespace;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Parser;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.UserAccessorProperty;
+import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
+
+/**
+ * IR representation for function (or script.)
+ *
+ */
+public class FunctionNode extends Block {
+
+    /** Function kinds */
+    public enum Kind {
+        /** a normal function - nothing special */
+        NORMAL,
+        /** a script function */
+        SCRIPT,
+        /** a getter, @see {@link UserAccessorProperty} */
+        GETTER,
+        /** a setter, @see {@link UserAccessorProperty} */
+        SETTER
+    }
+
+    /** Compilation states available */
+    public enum CompilationState {
+        /** compiler is ready */
+        INITIALIZED,
+        /** method has been parsed */
+        PARSED,
+        /** method has been parsed */
+        PARSE_ERROR,
+        /** constant folding pass */
+        CONSTANT_FOLDED,
+        /** method has been lowered */
+        LOWERED,
+        /** method hass been attributed */
+        ATTR,
+        /** method has been split */
+        SPLIT,
+        /** method has had its types finalized */
+        FINALIZED,
+        /** method has been emitted to bytecode */
+        EMITTED
+    }
+
+    /** External function identifier. */
+    @Ignore
+    private IdentNode ident;
+
+    /** Internal function name. */
+    private String name;
+
+    /** Compilation unit. */
+    private CompileUnit compileUnit;
+
+    /** Method emitter for current method. */
+    private MethodEmitter method;
+
+    /** Function kind. */
+    private Kind kind;
+
+    /** List of parameters. */
+    private List<IdentNode> parameters;
+
+    /** List of nested functions. */
+    private List<FunctionNode> functions;
+
+    /** First token of function. **/
+    private long firstToken;
+
+    /** Last token of function. **/
+    private long lastToken;
+
+    /** Variable frames. */
+    private Frame frames;
+
+    /** Method's namespace. */
+    private final Namespace namespace;
+
+    /** Node representing current this. */
+    @Ignore
+    private IdentNode thisNode;
+
+    /** Node representing current scope. */
+    @Ignore
+    private IdentNode scopeNode;
+
+    /** Node representing return value. */
+    @Ignore
+    private IdentNode resultNode;
+
+    /** Node representing current arguments. */
+    @Ignore
+    private IdentNode argumentsNode;
+
+    /** Node representing callee */
+    @Ignore
+    private IdentNode calleeNode;
+
+    /** Node representing varargs */
+    @Ignore
+    private IdentNode varArgsNode;
+
+    /** Pending label list. */
+    private final Stack<LabelNode> labelStack;
+
+    /** Pending control list. */
+    private final Stack<Node> controlStack;
+
+    /** Variable declarations in the function's scope */
+    @Ignore
+    private final List<VarNode> declarations;
+
+    /** VarNode for this function statement */
+    @Ignore //this is explicit code anyway and should not be traversed after lower
+    private VarNode funcVarNode;
+
+    /** Line number for function declaration */
+    @Ignore
+    private LineNumberNode funcVarLineNumberNode;
+
+    /** Initializer var func = __callee__, where applicable */
+    @Ignore
+    private Node selfSymbolInit;
+
+    /** Current compilation state */
+    @Ignore
+    private final EnumSet<CompilationState> compilationState;
+
+    /** Function flags. */
+    private int flags;
+
+    /** Is anonymous function flag. */
+    private static final int IS_ANONYMOUS                = 0b0000_0000_0000_0001;
+    /** Is statement flag */
+    private static final int IS_STATEMENT                = 0b0000_0000_0000_0010;
+    /** is this a strict mode function? */
+    private static final int IS_STRICT_MODE              = 0b0000_0000_0000_0100;
+    /** Does the function use the "arguments" identifier ? */
+    private static final int USES_ARGUMENTS              = 0b0000_0000_0000_1000;
+    /** Are we lowered ? */
+    private static final int IS_LOWERED                  = 0b0000_0000_0001_0000;
+    /** Has this node been split because it was too large? */
+    private static final int IS_SPLIT                    = 0b0000_0000_0010_0000;
+    /** Does the function call eval? */
+    private static final int HAS_EVAL                    = 0b0000_0000_0100_0000;
+    /** Does the function contain a with block ? */
+    private static final int HAS_WITH                    = 0b0000_0000_1000_0000;
+    /** Does a descendant function contain a with or eval? */
+    private static final int HAS_DESCENDANT_WITH_OR_EVAL = 0b0000_0001_0000_0000;
+    /** Does the function define "arguments" identifier as a parameter of nested function name? */
+    private static final int DEFINES_ARGUMENTS           = 0b0000_0010_0000_0000;
+    /** Does the function need a self symbol? */
+    private static final int NEEDS_SELF_SYMBOL           = 0b0000_0100_0000_0000;
+    /** Does this function or any of its descendants use variables from an ancestor function's scope (incl. globals)? */
+    private static final int USES_ANCESTOR_SCOPE         = 0b0000_1000_0000_0000;
+    /** Is this function lazily compiled? */
+    private static final int IS_LAZY                     = 0b0001_0000_0000_0000;
+    /** Does this function have lazy, yet uncompiled children */
+    private static final int HAS_LAZY_CHILDREN           = 0b0010_0000_0000_0000;
+
+    /** Does this function or any nested functions contain a with or an eval? */
+    private static final int HAS_DEEP_WITH_OR_EVAL = HAS_EVAL | HAS_WITH | HAS_DESCENDANT_WITH_OR_EVAL;
+    /** Does this function need to store all its variables in scope? */
+    private static final int HAS_ALL_VARS_IN_SCOPE = HAS_DEEP_WITH_OR_EVAL | IS_SPLIT | HAS_LAZY_CHILDREN;
+    /** Does this function potentially need "arguments"? Note that this is not a full test, as further negative check of REDEFINES_ARGS is needed. */
+    private static final int MAYBE_NEEDS_ARGUMENTS = USES_ARGUMENTS | HAS_EVAL;
+    /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep with or eval. */
+    private static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_WITH_OR_EVAL;
+
+    /** What is the return type of this function? */
+    private Type returnType = Type.UNKNOWN;
+
+    /**
+     * Used to keep track of a function's parent blocks.
+     * This is needed when a (finally body) block is cloned than contains inner functions.
+     * Does not include function.getParent().
+     */
+    @Ignore
+    private List<Block> referencingParentBlocks;
+
+    /**
+     * Constructor
+     *
+     * @param source    the source
+     * @param token     token
+     * @param finish    finish
+     * @param namespace the namespace
+     * @param parent    the parent block
+     * @param ident     the identifier
+     * @param name      the name of the function
+     */
+    @SuppressWarnings("LeakingThisInConstructor")
+    public FunctionNode(final Source source, final long token, final int finish, final Namespace namespace, final Block parent, final IdentNode ident, final String name) {
+        super(source, token, finish, parent, null);
+
+        this.ident             = ident;
+        this.name              = name;
+        this.kind              = Kind.NORMAL;
+        this.parameters        = new ArrayList<>();
+        this.functions         = new ArrayList<>();
+        this.firstToken        = token;
+        this.lastToken         = token;
+        this.namespace         = namespace;
+        this.labelStack        = new Stack<>();
+        this.controlStack      = new Stack<>();
+        this.declarations      = new ArrayList<>();
+        // my block -> function is this. We added @SuppressWarnings("LeakingThisInConstructor") as NetBeans identifies
+        // it as such a leak - this is a false positive as we're setting this into a field of the object being
+        // constructed, so it can't be seen from other threads.
+        this.function          = this;
+        this.compilationState  = EnumSet.of(CompilationState.INITIALIZED);
+    }
+
+    @SuppressWarnings("LeakingThisInConstructor")
+    private FunctionNode(final FunctionNode functionNode, final CopyState cs) {
+        super(functionNode, cs);
+
+        this.ident = (IdentNode)cs.existingOrCopy(functionNode.ident);
+        this.name  = functionNode.name;
+        this.kind  = functionNode.kind;
+
+        this.parameters = new ArrayList<>();
+        for (final IdentNode param : functionNode.getParameters()) {
+            this.parameters.add((IdentNode) cs.existingOrCopy(param));
+        }
+
+        this.functions         = new ArrayList<>();
+        this.firstToken        = functionNode.firstToken;
+        this.lastToken         = functionNode.lastToken;
+        this.namespace         = functionNode.getNamespace();
+        this.thisNode          = (IdentNode)cs.existingOrCopy(functionNode.thisNode);
+        this.scopeNode         = (IdentNode)cs.existingOrCopy(functionNode.scopeNode);
+        this.resultNode        = (IdentNode)cs.existingOrCopy(functionNode.resultNode);
+        this.argumentsNode     = (IdentNode)cs.existingOrCopy(functionNode.argumentsNode);
+        this.varArgsNode       = (IdentNode)cs.existingOrCopy(functionNode.varArgsNode);
+        this.calleeNode        = (IdentNode)cs.existingOrCopy(functionNode.calleeNode);
+        this.labelStack        = new Stack<>();
+        this.controlStack      = new Stack<>();
+        this.declarations      = new ArrayList<>();
+
+        for (final VarNode decl : functionNode.getDeclarations()) {
+            declarations.add((VarNode) cs.existingOrCopy(decl)); //TODO same?
+        }
+
+        this.flags = functionNode.flags;
+
+        this.funcVarNode = (VarNode)cs.existingOrCopy(functionNode.funcVarNode);
+        /** VarNode for this function statement */
+
+        // my block -> function is this. We added @SuppressWarnings("LeakingThisInConstructor") as NetBeans identifies
+        // it as such a leak - this is a false positive as we're setting this into a field of the object being
+        // constructed, so it can't be seen from other threads.
+        this.function = this;
+
+        this.compilationState = EnumSet.copyOf(functionNode.compilationState);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        // deep clone all parent blocks
+        return fixBlockChain(new FunctionNode(this, cs));
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        final FunctionNode saveFunctionNode = visitor.getCurrentFunctionNode();
+        final Block        saveBlock        = visitor.getCurrentBlock();
+
+        visitor.setCurrentFunctionNode(this);
+        visitor.setCurrentCompileUnit(getCompileUnit());
+        visitor.setCurrentMethodEmitter(getMethodEmitter());
+        visitor.setCurrentBlock(this);
+
+        try {
+            if (visitor.enter(this) != null) {
+                if (ident != null) {
+                    ident = (IdentNode)ident.accept(visitor);
+                }
+
+                for (int i = 0, count = parameters.size(); i < count; i++) {
+                    parameters.set(i, (IdentNode)parameters.get(i).accept(visitor));
+                }
+
+                for (int i = 0, count = functions.size(); i < count; i++) {
+                    functions.set(i, (FunctionNode)functions.get(i).accept(visitor));
+                }
+
+                for (int i = 0, count = statements.size(); i < count; i++) {
+                    statements.set(i, statements.get(i).accept(visitor));
+                }
+
+                return visitor.leave(this);
+            }
+        } finally {
+            visitor.setCurrentBlock(saveBlock);
+            visitor.setCurrentFunctionNode(saveFunctionNode);
+            visitor.setCurrentCompileUnit(saveFunctionNode != null ? saveFunctionNode.getCompileUnit() : null);
+            visitor.setCurrentMethodEmitter(saveFunctionNode != null ? saveFunctionNode.getMethodEmitter() : null);
+        }
+
+        return this;
+    }
+
+    /**
+     * Locate the parent function.
+     *
+     * @return Parent function.
+     */
+    public FunctionNode findParentFunction() {
+        return getParent() != null ? getParent().getFunction() : null;
+    }
+
+    /**
+     * Add parent name to the builder.
+     *
+     * @param sb String builder.
+     */
+    @Override
+    public void addParentName(final StringBuilder sb) {
+        if (!isScript()) {
+            sb.append(getName());
+            sb.append("$");
+        }
+    }
+
+    @Override
+    public boolean needsScope() {
+        return super.needsScope() || isScript();
+    }
+
+    /**
+     * Check whether this FunctionNode has reached a give CompilationState.
+     *
+     * @param state the state to check for
+     * @return true of the node is in the given state
+     */
+    public boolean hasState(final EnumSet<CompilationState> state) {
+        return compilationState.equals(state);
+    }
+
+    /**
+     * Check whether the state of this FunctionNode contains a given compilation
+     * state.
+     *
+     * A node can be in many states at once, e.g. both lowered and initialized.
+     * To check for an exact state, use {FunctionNode{@link #hasState(EnumSet)}
+     *
+     * @param state state to check for
+     * @return true if state is present in the total compilation state of this FunctionNode
+     */
+    public boolean hasState(final CompilationState state) {
+        return compilationState.contains(state);
+    }
+
+    /**
+     * Add a state to the total CompilationState of this node, e.g. if
+     * FunctionNode has been lowered, the compiler will add
+     * {@code CompilationState#LOWERED} to the state vector
+     *
+     * @param state {@link CompilationState} to add
+     */
+    public void setState(final CompilationState state) {
+        compilationState.add(state);
+    }
+
+    /*
+     * Frame management.
+     */
+
+    /**
+     * Push a new block frame.
+     *
+     * @return the new frame
+     */
+    public final Frame pushFrame() {
+        frames = new Frame(frames);
+        return frames;
+    }
+
+    /**
+     * Pop a block frame.
+     */
+    public final void popFrame() {
+        frames = frames.getPrevious();
+    }
+
+    /**
+     * Create a temporary variable to the current frame.
+     *
+     * @param currentFrame Frame to add to - defaults to current function frame
+     * @param type  Strong type of symbol.
+     * @param node  Primary node to use symbol.
+     *
+     * @return Symbol used.
+     */
+    public Symbol newTemporary(final Frame currentFrame, final Type type, final Node node) {
+        assert currentFrame != null;
+        Symbol symbol = node.getSymbol();
+
+        // If no symbol already present.
+        if (symbol == null) {
+            final String uname = uniqueName(TEMP_PREFIX.tag());
+            symbol = new Symbol(uname, IS_TEMP, type);
+            symbol.setNode(node);
+        }
+
+        // Assign a slot if it doesn't have one.
+        if (!symbol.hasSlot()) {
+            currentFrame.addSymbol(symbol);
+        }
+
+        // Set symbol to node.
+        node.setSymbol(symbol);
+
+        return symbol;
+    }
+
+    /**
+     * Create a unique name in the namespace of this FunctionNode
+     * @param base prefix for name
+     * @return base if no collision exists, otherwise a name prefix with base
+     */
+    public String uniqueName(final String base) {
+        return namespace.uniqueName(base);
+    }
+
+    /**
+     * Add a new temporary variable to the current frame
+     *
+     * @param type Strong type of symbol
+     * @param node Primary node to use symbol
+     *
+     * @return symbol used
+     */
+    public Symbol newTemporary(final Type type, final Node node) {
+        return newTemporary(frames, type, node);
+    }
+
+    /**
+     * Create a virtual symbol for a literal.
+     *
+     * @param literalNode Primary node to use symbol.
+     *
+     * @return Symbol used.
+     */
+    public Symbol newLiteral(final LiteralNode<?> literalNode) {
+        final String uname = uniqueName(LITERAL_PREFIX.tag());
+        final Symbol symbol = new Symbol(uname, IS_CONSTANT, literalNode.getType());
+        symbol.setNode(literalNode);
+        literalNode.setSymbol(symbol);
+
+        return symbol;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append('[');
+        sb.append(returnType);
+        sb.append(']');
+        sb.append(' ');
+
+        sb.append("function");
+
+        if (ident != null) {
+            sb.append(' ');
+            ident.toString(sb);
+        }
+
+        sb.append('(');
+        boolean first = true;
+
+        for (final IdentNode parameter : parameters) {
+            if (!first) {
+                sb.append(", ");
+            } else {
+                first = false;
+            }
+
+            parameter.toString(sb);
+        }
+
+        sb.append(')');
+    }
+
+    /**
+     * Determine if script function.
+     *
+     * @return True if script function.
+     */
+    public boolean isScript() {
+        return getParent() == null;
+    }
+
+    /**
+     * Get the control stack. Used when parsing to establish nesting depths of
+     * different control structures
+     *
+     * @return the control stack
+     */
+    public Stack<Node> getControlStack() {
+        return controlStack;
+    }
+
+    /**
+     * Should this function node be lazily code generated, i.e. first at link time
+     * @return true if lazy
+     */
+    public boolean isLazy() {
+        return (flags & IS_LAZY) != 0;
+    }
+
+    /**
+     * Set if this function should be lazily generated
+     * @param isLazy is lazy
+     */
+    public void setIsLazy(final boolean isLazy) {
+        this.flags = isLazy ? flags | IS_LAZY : flags & ~IS_LAZY;
+    }
+
+    /**
+     * Check if the {@code with} keyword is used in this function
+     *
+     * @return true if {@code with} is used
+     */
+    public boolean hasWith() {
+        return (flags & HAS_WITH) != 0;
+    }
+
+    /**
+     * Flag this function as using the {@code with} keyword
+     */
+    public void setHasWith() {
+        if(!hasWith()) {
+            this.flags |= HAS_WITH;
+            // with requires scope in parents.
+            // TODO: refine this. with should not force all variables in parents to be in scope, only those that are
+            // actually referenced as identifiers by name
+            markParentForWithOrEval();
+        }
+    }
+
+    private void markParentForWithOrEval() {
+        // If this is invoked, then either us or a descendant uses with or eval, meaning we must have our own scope.
+        setNeedsScope();
+
+        final FunctionNode parentFunction = findParentFunction();
+        if(parentFunction != null) {
+            parentFunction.setDescendantHasWithOrEval();
+        }
+    }
+
+    private void setDescendantHasWithOrEval() {
+        if((flags & HAS_DESCENDANT_WITH_OR_EVAL) == 0) {
+            flags |= HAS_DESCENDANT_WITH_OR_EVAL;
+            markParentForWithOrEval();
+        }
+    }
+
+    /**
+     * Check if the {@code eval} keyword is used in this function
+     *
+     * @return true if {@code eval} is used
+     */
+    public boolean hasEval() {
+        return (flags & HAS_EVAL) != 0;
+    }
+
+    /**
+     * Flag this function as calling the {@code eval} function
+     */
+    public void setHasEval() {
+        if(!hasEval()) {
+            this.flags |= HAS_EVAL;
+            markParentForWithOrEval();
+        }
+    }
+
+    /**
+     * Test whether this function or any of its nested functions contains a <tt>with</tt> statement
+     * or an <tt>eval</tt> call.
+     *
+     * @see #hasWith()
+     * @see #hasEval()
+     * @return true if this or a nested function contains with or eval
+     */
+    public boolean hasDeepWithOrEval() {
+        return (flags & HAS_DEEP_WITH_OR_EVAL) != 0;
+    }
+
+    /**
+     * Get the first token for this function
+     * @return the first token
+     */
+    public long getFirstToken() {
+        return firstToken;
+    }
+
+    /**
+     * Set the first token for this function
+     * @param firstToken the first token
+     */
+    public void setFirstToken(final long firstToken) {
+        this.firstToken = firstToken;
+    }
+
+    /**
+     * Get all nested functions
+     * @return list of nested functions in this function
+     */
+    public List<FunctionNode> getFunctions() {
+        return Collections.unmodifiableList(functions);
+    }
+
+    /**
+     * Get the label stack. This is used by the parser to establish
+     * label nesting depth
+     *
+     * @return the label stack
+     */
+    public Stack<LabelNode> getLabelStack() {
+        return labelStack;
+    }
+
+    /**
+     * If this function needs to use var args, return the identifier to the node used
+     * for the var args structure
+     *
+     * @return IdentNode representing the var args structure
+     */
+    public IdentNode getVarArgsNode() {
+        return varArgsNode;
+    }
+
+    /**
+     * Set the identifier to the node used for the var args structure
+     *
+     * @param varArgsNode IdentNode representing the var args
+     */
+    public void setVarArgsNode(final IdentNode varArgsNode) {
+        this.varArgsNode = varArgsNode;
+    }
+
+    /**
+     * If this function uses the {@code callee} variable, return the node used
+     * as this variable
+     *
+     * @return an IdentNode representing the {@code callee} variable
+     */
+    public IdentNode getCalleeNode() {
+        return calleeNode;
+    }
+
+    /**
+     * If this function uses the {@code callee} variable, set the node representing the
+     * callee
+     * @param calleeNode an IdentNode representing the callee
+     */
+    public void setCalleeNode(final IdentNode calleeNode) {
+        this.calleeNode = calleeNode;
+    }
+
+    /**
+     * Check if this function's generated Java method needs a {@code callee} parameter. Functions that need access to
+     * their parent scope, functions that reference themselves, and non-strict functions that need an Arguments object
+     * (since it exposes {@code arguments.callee} property) will need to have a callee parameter.
+     * @return true if the function's generated Java method needs a {@code callee} parameter.
+     */
+    public boolean needsCallee() {
+        return needsParentScope() || needsSelfSymbol() || (needsArguments() && !isStrictMode());
+    }
+
+    /**
+     * If this is a function where {@code arguments} is used, return the node used as the {@code arguments}
+     * variable
+     * @return an IdentNode representing {@code arguments}
+     */
+    public IdentNode getArgumentsNode() {
+        return argumentsNode;
+    }
+
+    /**
+     * If this is a Function where {@code arguments} is used, an identifier to the node representing
+     * the {@code arguments} value has to be supplied by the compiler
+     *
+     * @param argumentsNode IdentNode that represents {@code arguments}
+     */
+    public void setArgumentsNode(final IdentNode argumentsNode) {
+        this.argumentsNode = argumentsNode;
+    }
+
+    /**
+     * Get the identifier for this function
+     * @return the identifier as an IdentityNode
+     */
+    public IdentNode getIdent() {
+        return ident;
+    }
+
+    /**
+     * Reset the identifier for this function
+     * @param ident IdentNode for new identifier
+     */
+    public void setIdent(final IdentNode ident) {
+        this.ident = ident;
+    }
+
+    /**
+     * Does this function's method needs to be variable arity (gather all script-declared parameters in a final
+     * {@code Object[]} parameter. Functions that need to have the "arguments" object as well as functions that simply
+     * declare too many arguments for JVM to handle with fixed arity will need to be variable arity.
+     * @return true if the Java method in the generated code that implements this function needs to be variable arity.
+     * @see #needsArguments()
+     * @see LinkerCallSite#ARGLIMIT
+     */
+    public boolean isVarArg() {
+        return needsArguments() || parameters.size() > LinkerCallSite.ARGLIMIT;
+    }
+
+    /**
+     * Flag this function as one that defines the identifier "arguments" as a function parameter or nested function
+     * name. This precludes it from needing to have an Arguments object defined as "arguments" local variable. Note that
+     * defining a local variable named "arguments" still requires construction of the Arguments object (see
+     * ECMAScript 5.1 Chapter 10.5).
+     * @see #needsArguments()
+     */
+    public void setDefinesArguments() {
+        this.flags |= DEFINES_ARGUMENTS;
+    }
+
+    /**
+     * Returns true if this function needs to have an Arguments object defined as a local variable named "arguments".
+     * Functions that use "arguments" as identifier and don't define it as a name of a parameter or a nested function
+     * (see ECMAScript 5.1 Chapter 10.5), as well as any function that uses eval or with, or has a nested function that
+     * does the same, will have an "arguments" object. Also, if this function is a script, it will not have an
+     * "arguments" object, because it does not have local variables; rather the Global object will have an explicit
+     * "arguments" property that provides command-line arguments for the script.
+     * @return true if this function needs an arguments object.
+     */
+    public boolean needsArguments() {
+        // uses "arguments" or calls eval, but it does not redefine "arguments", and finally, it's not a script, since
+        // for top-level script, "arguments" is picked up from Context by Global.init() instead.
+        return (flags & MAYBE_NEEDS_ARGUMENTS) != 0 && (flags & DEFINES_ARGUMENTS) == 0 && !isScript();
+    }
+
+    /**
+     * Flags this function as one that uses the "arguments" identifier.
+     * @see #needsArguments()
+     */
+    public void setUsesArguments() {
+        flags |= USES_ARGUMENTS;
+    }
+
+    /**
+     * Returns true if this function needs access to its parent scope. Functions referencing variables outside their
+     * scope (including global variables), as well as functions that call eval or have a with block, or have nested
+     * functions that call eval or have a with block, will need a parent scope. Top-level script functions also need a
+     * parent scope since they might be used from within eval, and eval will need an externally passed scope.
+     * @return true if the function needs parent scope.
+     */
+    public boolean needsParentScope() {
+        return (flags & NEEDS_PARENT_SCOPE) != 0 || isScript();
+    }
+
+    /**
+     * Return the kind of this function
+     * @see FunctionNode.Kind
+     * @return the kind
+     */
+    public Kind getKind() {
+        return kind;
+    }
+
+    /**
+     * Set the kind of this function
+     * @see FunctionNode.Kind
+     * @param kind the kind
+     */
+    public void setKind(final Kind kind) {
+        this.kind = kind;
+    }
+
+    /**
+     * Return the last token for this function's code
+     * @return last token
+     */
+    public long getLastToken() {
+        return lastToken;
+    }
+
+    /**
+     * Set the last token for this function's code
+     * @param lastToken the last token
+     */
+    public void setLastToken(final long lastToken) {
+        this.lastToken = lastToken;
+    }
+
+    /**
+     * Get the name of this function
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set the name of this function
+     * @param name the name
+     */
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    /**
+     * Check if this function should have all its variables in its own scope. Scripts, split sub-functions, and
+     * functions having with and/or eval blocks are such.
+     *
+     * @return true if all variables should be in scope
+     */
+    public boolean allVarsInScope() {
+        return isScript() || (flags & HAS_ALL_VARS_IN_SCOPE) != 0;
+    }
+
+    /**
+     * Checks if this function is a sub-function generated by splitting a larger one
+     *
+     * @return true if this function is split from a larger one
+     */
+    public boolean isSplit() {
+        return (flags & IS_SPLIT) != 0;
+    }
+
+    /**
+     * Flag this function node as being a sub-function generated by the splitter
+     */
+    public void setIsSplit() {
+        this.flags |= IS_SPLIT;
+        setNeedsScope();
+    }
+
+    /**
+     * Checks if this function has yet-to-be-generated child functions
+     *
+     * @return true if there are lazy child functions
+     */
+    public boolean hasLazyChildren() {
+        return (flags & HAS_LAZY_CHILDREN) != 0;
+    }
+
+    /**
+     * Flag this function node as having yet-to-be-generated child functions
+     */
+    public void setHasLazyChildren() {
+        this.flags |= HAS_LAZY_CHILDREN;
+        setNeedsScope();
+    }
+
+    /**
+     * Get the parameters to this function
+     * @return a list of IdentNodes which represent the function parameters, in order
+     */
+    public List<IdentNode> getParameters() {
+        return Collections.unmodifiableList(parameters);
+    }
+
+    /**
+     * Set the paremeters to this function
+     * @param parameters a list of IdentNodes representing parameters in left to right order
+     */
+    public void setParameters(final List<IdentNode> parameters) {
+        this.parameters = parameters;
+    }
+
+    /**
+     * Get the identifier for the variable in which the function return value
+     * should be stored
+     * @return an IdentNode representing the return value
+     */
+    public IdentNode getResultNode() {
+        return resultNode;
+    }
+
+    /**
+     * Set the identifier representing the variable in which the function return
+     * value should be stored
+     * @param resultNode an IdentNode representing the return value
+     */
+    public void setResultNode(final IdentNode resultNode) {
+        this.resultNode = resultNode;
+    }
+
+    /**
+     * Get the identifier representing this function's scope
+     * @return an IdentNode representing this function's scope
+     */
+    public IdentNode getScopeNode() {
+        return scopeNode;
+    }
+
+    /**
+     * Set the identifier representing this function's scope
+     * @param scopeNode an IdentNode representing this function's scope
+     */
+    public void setScopeNode(final IdentNode scopeNode) {
+        this.scopeNode = scopeNode;
+    }
+
+    /**
+     * Check if this function is a statement
+     * @return true if function is a statement
+     */
+    public boolean isStatement() {
+        return (flags & IS_STATEMENT) != 0;
+    }
+
+    /**
+     * Flag this function as a statement
+     * @see Parser
+     */
+    public void setIsStatement() {
+        this.flags |= IS_STATEMENT;
+    }
+
+    /**
+     * Check if this function is anonymous
+     * @return true if function is anonymous
+     */
+    public boolean isAnonymous() {
+        return (flags & IS_ANONYMOUS) != 0;
+    }
+
+    /**
+     * Flag this function as an anonymous function.
+     * @see Parser
+     */
+    public void setIsAnonymous() {
+        this.flags |= IS_ANONYMOUS;
+    }
+
+    /**
+     * Does this function need a self symbol - this is needed only for self
+     * referring functions
+     * @return true if function needs a symbol for self
+     */
+    public boolean needsSelfSymbol() {
+        return (flags & NEEDS_SELF_SYMBOL) != 0;
+    }
+
+    /**
+     * Get the initializer statement for the __callee__ variable, where applicable
+     * for self references
+     * @return initialization
+     */
+    public Node getSelfSymbolInit() {
+        return this.selfSymbolInit;
+    }
+
+    /**
+     * Flag the function as needing a self symbol. This is needed only for
+     * self referring functions
+     * @param selfSymbolInit initialization expression for self symbol
+     */
+    public void setNeedsSelfSymbol(final Node selfSymbolInit) {
+        this.flags |= NEEDS_SELF_SYMBOL;
+        this.selfSymbolInit = selfSymbolInit;
+    }
+
+    /**
+     * Marks this function as one using any global symbol. The function and all its parent functions will all be marked
+     * as needing parent scope.
+     * @see #needsParentScope()
+     */
+    public void setUsesGlobalSymbol() {
+        this.flags |= USES_ANCESTOR_SCOPE;
+        final FunctionNode parentFn = findParentFunction();
+        if(parentFn != null) {
+            parentFn.setUsesGlobalSymbol();
+        }
+    }
+
+    /**
+     * Marks this function as using a specified scoped symbol. The function and its parent functions up to but not
+     * including the function defining the symbol will be marked as needing parent scope. The function defining the
+     * symbol will be marked as one that needs to have its own scope.
+     * @param symbol the symbol being used.
+     * @see #needsParentScope()
+     */
+    public void setUsesScopeSymbol(final Symbol symbol) {
+        if(symbol.getBlock() == this) {
+            setNeedsScope();
+        } else {
+            this.flags |= USES_ANCESTOR_SCOPE;
+            final FunctionNode parentFn = findParentFunction();
+            if(parentFn != null) {
+                parentFn.setUsesScopeSymbol(symbol);
+            }
+        }
+    }
+
+    /**
+     * Return the node representing {@code this} in this function
+     * @return IdentNode representing {@code this}
+     */
+    public IdentNode getThisNode() {
+        return thisNode;
+    }
+
+    /**
+     * Set the node representing {@code this} in this function
+     * @param thisNode identifier representing {@code this}
+     */
+    public void setThisNode(final IdentNode thisNode) {
+        this.thisNode = thisNode;
+    }
+
+    /**
+     * Every function declared as {@code function x()} is internally hoisted
+     * and represented as {@code var x = function()  ... }. This getter returns
+     * the VarNode representing this virtual assignment
+     *
+     * @return the var node emitted for setting this function symbol
+     */
+    public VarNode getFunctionVarNode() {
+        return funcVarNode;
+    }
+
+    /**
+     * Set the virtual VarNode assignment for this function.
+     * @see FunctionNode#getFunctionVarNode()
+     *
+     * @param varNode the virtual var node assignment
+     */
+    public void setFunctionVarNode(final VarNode varNode) {
+        funcVarNode = varNode;
+    }
+
+    /**
+     * The line number information where the function was declared must be propagated
+     * to the virtual {@code var x = function() ... } assignment described in
+     * {@link FunctionNode#getFunctionVarNode()}
+     * This maintains the line number of the declaration
+     *
+     * @return a line number node representing the line this function was declared
+     */
+    public LineNumberNode getFunctionVarLineNumberNode() {
+        return funcVarLineNumberNode;
+    }
+
+    /**
+     * Set the virtual VarNode assignment for this function, along with
+     * a line number node for tracking the original start line of the function
+     * declaration
+     *
+     * @param varNode    the virtual var node assignment
+     * @param lineNumber the line number node for the function declaration
+     */
+    public void setFunctionVarNode(final VarNode varNode, final LineNumberNode lineNumber) {
+        funcVarNode           = varNode;
+        funcVarLineNumberNode = lineNumber;
+    }
+
+    /**
+     * Get the namespace this function uses for its symbols
+     * @return the namespace
+     */
+    public Namespace getNamespace() {
+        return namespace;
+    }
+
+    @Override
+    public Type getType() {
+        return getReturnType();
+    }
+
+    /**
+     * Get the return type for this function. Return types can be specialized
+     * if the compiler knows them, but parameters cannot, as they need to go through
+     * appropriate object conversion
+     *
+     * @return the return type
+     */
+    public Type getReturnType() {
+        return returnType;
+    }
+
+    /**
+     * Set the function return type
+     *
+     * @param returnType new return type
+     */
+    public void setReturnType(final Type returnType) {
+        //we never bother with object types narrower than objects, that will lead to byte code verification errors
+        //as for instance even if we know we are returning a string from a method, the code generator will always
+        //treat it as an object, at least for now
+        this.returnType = Type.widest(this.returnType,  returnType.isObject() ? Type.OBJECT : returnType);
+    }
+
+    /**
+     * Set strict mode on or off for this function
+     *
+     * @param isStrictMode true if strict mode should be enabled
+     */
+    public void setStrictMode(final boolean isStrictMode) {
+        flags = isStrictMode ? flags | IS_STRICT_MODE : flags & ~IS_STRICT_MODE;
+    }
+
+    /**
+     * Check if the function is generated in strict mode
+     * @return true if strict mode enabled for function
+     */
+    public boolean isStrictMode() {
+        return (flags & IS_STRICT_MODE) != 0;
+    }
+
+    /**
+     * Set the lowered state
+     */
+    public void setIsLowered() {
+        flags |= IS_LOWERED;
+    }
+
+    /**
+     * Get the lowered state
+     *
+     * @return true if function is lowered
+     */
+    public boolean isLowered() {
+        return (flags & IS_LOWERED) != 0;
+    }
+
+    /**
+     * Add a new function to the function list.
+     *
+     * @param functionNode Function node to add.
+     */
+    @Override
+    public void addFunction(final FunctionNode functionNode) {
+        assert functionNode != null;
+        functions.add(functionNode);
+    }
+
+    /**
+     * Add a list of functions to the function list.
+     *
+     * @param functionNodes  Function nodes to add.
+     */
+    @Override
+    public void addFunctions(final List<FunctionNode> functionNodes) {
+        functions.addAll(functionNodes);
+    }
+
+    /**
+     * Set a function list
+     *
+     * @param functionNodes to set
+     */
+    @Override
+    public void setFunctions(final List<FunctionNode> functionNodes) {
+        this.functions = functionNodes;
+    }
+
+    /**
+     * Add a variable declaration that should be visible to the entire function
+     * scope. Parser does this.
+     *
+     * @param varNode a var node
+     */
+    public void addDeclaration(final VarNode varNode) {
+        declarations.add(varNode);
+    }
+
+    /**
+     * Return all variable declarations from this function scope
+     *
+     * @return all VarNodes in scope
+     */
+    public List<VarNode> getDeclarations() {
+        return Collections.unmodifiableList(declarations);
+    }
+
+    /**
+     * Get the compile unit used to compile this function
+     * @see Compiler
+     * @return the compile unit
+     */
+    public CompileUnit getCompileUnit() {
+        return compileUnit;
+    }
+
+    /**
+     * Reset the compile unit used to compile this function
+     * @see Compiler
+     * @param compileUnit the compile unit
+     */
+    public void setCompileUnit(final CompileUnit compileUnit) {
+        this.compileUnit = compileUnit;
+    }
+
+    /**
+     * Return the method emitter used to write bytecode for this function
+     * @return the method emitter
+     */
+    public MethodEmitter getMethodEmitter() {
+        return method;
+    }
+
+    /**
+     * Set the method emitter that is to be used to write bytecode for this function
+     * @param method a method emitter
+     */
+    public void setMethodEmitter(final MethodEmitter method) {
+        this.method = method;
+    }
+
+    /**
+     * Each FunctionNode maintains a list of reference to its parent blocks.
+     * Add a parent block to this function.
+     *
+     * @param parentBlock  a block to remember as parent
+     */
+    public void addReferencingParentBlock(final Block parentBlock) {
+        assert parentBlock.getFunction() == function.findParentFunction(); // all parent blocks must be in the same function
+        if (parentBlock != function.getParent()) {
+            if (referencingParentBlocks == null) {
+                referencingParentBlocks = new LinkedList<>();
+            }
+            referencingParentBlocks.add(parentBlock);
+        }
+    }
+
+    /**
+     * Get the known parent blocks to this function
+     *
+     * @return list of parent blocks
+     */
+    public List<Block> getReferencingParentBlocks() {
+        if (referencingParentBlocks == null) {
+            return Collections.emptyList();
+        }
+        return Collections.unmodifiableList(referencingParentBlocks);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java
new file mode 100644
index 0000000..b0570a2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java
@@ -0,0 +1,221 @@
+/*
+ * 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.ir;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.__DIR__;
+import static jdk.nashorn.internal.codegen.CompilerConstants.__FILE__;
+import static jdk.nashorn.internal.codegen.CompilerConstants.__LINE__;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
+
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for an identifier.
+ */
+public class IdentNode extends Node implements PropertyKey, TypeOverride, FunctionCall {
+    /** Identifier. */
+    private final String name;
+
+    /** Type for a callsite, e.g. X in a get()X or a set(X)V */
+    private Type callSiteType;
+
+    /** flag for an ident that is the property name of an AccessNode. */
+    private boolean isPropertyName;
+
+    /** flag for an ident on the left hand side of <code>var lhs = rhs;</code>. */
+    private boolean isInitializedHere;
+
+    /**
+     * Constructor
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish position
+     * @param name    name of identifier
+     */
+    public IdentNode(final Source source, final long token, final int finish, final String name) {
+        super(source, token, finish);
+        this.name = name;
+    }
+
+    /**
+     * Copy constructor - create a new IdentNode for the same location
+     *
+     * @param identNode  identNode
+     */
+    public IdentNode(final IdentNode identNode) {
+        super(identNode);
+        this.name              = identNode.getName();
+        this.isPropertyName    = identNode.isPropertyName;
+        this.isInitializedHere = identNode.isInitializedHere;
+    }
+
+    @Override
+    public Type getType() {
+        return callSiteType == null ? super.getType() : callSiteType;
+    }
+
+    @Override
+    public boolean isAtom() {
+        return true;
+    }
+
+    private boolean hasCallSiteType() {
+        //this is an identity that's part of a getter or setter
+        return callSiteType != null;
+    }
+
+    @Override
+    public void setType(final Type type) {
+        if (DEBUG_FIELDS && getSymbol() != null && !Type.areEquivalent(getSymbol().getSymbolType(), type)) {
+            ObjectClassGenerator.LOG.info(getClass().getName() + " " + this + " => " + type + " instead of " + getType());
+        }
+        this.callSiteType = type;
+        // do NOT, repeat NOT touch the symbol here. it might be a local variable or whatever. This is the override if it isn't
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new IdentNode(this);
+    }
+
+    /**
+     * Test to see if two IdentNode are the same.
+     *
+     * @param other Other ident.
+     * @return true if the idents are the same.
+     */
+    @Override
+    public boolean equals(final Object other) {
+        if (other instanceof IdentNode) {
+            return name.equals(((IdentNode)other).name);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    /**
+     * Assist in IR navigation.
+     *
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        if (hasCallSiteType()) {
+            sb.append('{');
+            final String desc = getType().getDescriptor();
+            sb.append(desc.charAt(desc.length() - 1) == ';' ? "O" : getType().getDescriptor());
+            sb.append('}');
+        }
+
+        sb.append(name);
+    }
+
+    /**
+     * Get the name of the identifier
+     * @return  IdentNode name
+     */
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getPropertyName() {
+        return getName();
+    }
+
+    /**
+     * We can only override type if the symbol lives in the scope, otherwise
+     * it is strongly determined by the local variable already allocated
+     *
+     * @return true if can have callsite type
+     */
+    @Override
+    public boolean canHaveCallSiteType() {
+        return getSymbol() != null && getSymbol().isScope();
+    }
+
+    /**
+     * Check if this IdentNode is a property name
+     * @return true if this is a property name
+     */
+    public boolean isPropertyName() {
+        return isPropertyName;
+    }
+
+    /**
+     * Flag this IdentNode as a property name
+     */
+    public void setIsPropertyName() {
+        isPropertyName = true;
+    }
+
+    /**
+     * Helper function for local def analysis.
+     * @return true if IdentNode is initialized on creation
+     */
+    public boolean isInitializedHere() {
+        return isInitializedHere;
+    }
+
+    /**
+     * Flag IdentNode to be initialized on creation
+     */
+    public void setIsInitializedHere() {
+        isInitializedHere = true;
+    }
+
+    /**
+     * Check if this IdentNode is a special identity, currently __DIR__, __FILE__
+     * or __LINE__
+     *
+     * @return true if this IdentNode is special
+     */
+    public boolean isSpecialIdentity() {
+        return name.equals(__DIR__.tag()) || name.equals(__FILE__.tag()) || name.equals(__LINE__.tag());
+    }
+
+    @Override
+    public boolean isFunction() {
+        return false;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/IfNode.java b/nashorn/src/jdk/nashorn/internal/ir/IfNode.java
new file mode 100644
index 0000000..81148c3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/IfNode.java
@@ -0,0 +1,131 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for an IF statement.
+ *
+ */
+public class IfNode extends Node {
+    /** Test expression. */
+    private Node test;
+
+    /** Pass statements. */
+    private Block pass;
+
+    /** Fail statements. */
+    private Block fail;
+
+    /**
+     * Constructor
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param test    test
+     * @param pass    block to execute when test passes
+     * @param fail    block to execute when test fails or null
+     */
+    public IfNode(final Source source, final long token, final int finish, final Node test, final Block pass, final Block fail) {
+        super(source, token, finish);
+
+        this.test = test;
+        this.pass = pass;
+        this.fail = fail;
+    }
+
+    private IfNode(final IfNode ifNode, final CopyState cs) {
+        super(ifNode);
+
+        this.test = cs.existingOrCopy(ifNode.test);
+        this.pass = (Block)cs.existingOrCopy(ifNode.pass);
+        this.fail = (Block)cs.existingOrCopy(ifNode.fail);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new IfNode(this, cs);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            test = test.accept(visitor);
+
+            pass = (Block)pass.accept(visitor);
+
+            if (fail != null) {
+                fail = (Block)fail.accept(visitor);
+            }
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("if (");
+        test.toString(sb);
+        sb.append(')');
+    }
+
+    /**
+     * Get the else block of this IfNode
+     * @return the else block, or null if none exists
+     */
+    public Block getFail() {
+        return fail;
+    }
+
+    /**
+     * Get the then block for this IfNode
+     * @return the then block
+     */
+    public Block getPass() {
+        return pass;
+    }
+
+    /**
+     * Get the test expression for this IfNode
+     * @return the test expression
+     */
+    public Node getTest() {
+        return test;
+    }
+
+    /**
+     * Reset the test expression for this IfNode
+     * @param test a new test expression
+     */
+    public void setTest(final Node test) {
+        this.test = test;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java b/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java
new file mode 100644
index 0000000..9feb5eb
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java
@@ -0,0 +1,160 @@
+/*
+ * 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.ir;
+
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
+
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation of an indexed access (brackets operator.)
+ *
+ */
+public class IndexNode extends BaseNode implements TypeOverride {
+    /** Property ident. */
+    private Node index;
+
+    private boolean hasCallSiteType;
+
+    /**
+     * Constructors
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param base    base node for access
+     * @param index   index for access
+     */
+    public IndexNode(final Source source, final long token, final int finish, final Node base, final Node index) {
+        super(source, token, finish, base);
+
+        this.index = index;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param indexNode source node
+     */
+    public IndexNode(final IndexNode indexNode) {
+        this(indexNode, new CopyState());
+    }
+
+    private IndexNode(final IndexNode indexNode, final CopyState cs) {
+        super(indexNode, cs);
+
+        index = cs.existingOrCopy(indexNode.index);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new IndexNode(this, cs);
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!super.equals(other)) {
+            return false;
+        }
+        return index.equals(((IndexNode)other).getIndex());
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ getIndex().hashCode();
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            base = base.accept(visitor);
+            index = index.accept(visitor);
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        final boolean needsParen = tokenType().needsParens(base.tokenType(), true);
+
+        if (hasCallSiteType) {
+            sb.append('{');
+            final String desc = getType().getDescriptor();
+            sb.append(desc.charAt(desc.length() - 1) == ';' ? "O" : getType().getDescriptor());
+            sb.append('}');
+        }
+
+        if (needsParen) {
+            sb.append('(');
+        }
+
+        base.toString(sb);
+
+        if (needsParen) {
+            sb.append(')');
+        }
+
+        sb.append('[');
+        index.toString(sb);
+        sb.append(']');
+    }
+
+    /**
+     * Get the index expression for this IndexNode
+     * @return the index
+     */
+    public Node getIndex() {
+        return index;
+    }
+
+    /**
+     * Reset the index expression for this IndexNode
+     * @param index a new index expression
+     */
+    public void setIndex(final Node index) {
+        this.index = index;
+    }
+
+    @Override
+    public void setType(final Type type) {
+        if (DEBUG_FIELDS && !Type.areEquivalent(getSymbol().getSymbolType(), type)) {
+            ObjectClassGenerator.LOG.info(getClass().getName() + " " + this + " => " + type + " instead of " + getType());
+        }
+        hasCallSiteType = true;
+        getSymbol().setTypeOverride(type);
+    }
+
+    @Override
+    public boolean canHaveCallSiteType() {
+        return true; //carried by the symbol and always the same nodetype==symboltype
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java b/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java
new file mode 100644
index 0000000..c61bfcb
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java
@@ -0,0 +1,157 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for a labeled statement.
+ *
+ */
+
+public class LabelNode extends Node {
+    /** Label ident. */
+    private IdentNode label;
+
+    /** Statements. */
+    private Block body;
+
+    /** Node to break from. */
+    @Ignore
+    private Node breakNode;
+
+    /** Node to continue. */
+    @Ignore
+    private Node continueNode;
+
+    /**
+     * Constructor
+     *
+     * @param source the source
+     * @param token  token
+     * @param finish finish
+     * @param label  label identifier
+     * @param body   body of label node
+     */
+    public LabelNode(final Source source, final long token, final int finish, final IdentNode label, final Block body) {
+        super(source, token, finish);
+
+        this.label = label;
+        this.body  = body;
+    }
+
+    private LabelNode(final LabelNode labelNode, final CopyState cs) {
+        super(labelNode);
+
+        this.label        = (IdentNode)cs.existingOrCopy(labelNode.label);
+        this.body         = (Block)cs.existingOrCopy(labelNode.body);
+        this.breakNode    = cs.existingOrSame(labelNode.breakNode);
+        this.continueNode = cs.existingOrSame(labelNode.continueNode);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new LabelNode(this, cs);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            label = (IdentNode)label.accept(visitor);
+            body  = (Block)body.accept(visitor);
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        label.toString(sb);
+        sb.append(':');
+    }
+
+    /**
+     * Get the body of the node
+     * @return the body
+     */
+    public Block getBody() {
+        return body;
+    }
+
+    /**
+     * Reset the body of the node
+     * @param body new body
+     */
+    public void setBody(final Block body) {
+        this.body = body;
+    }
+
+    /**
+     * Get the break node for this node
+     * @return the break node
+     */
+    public Node getBreakNode() {
+        return breakNode;
+    }
+
+    /**
+     * Reset the break node for this node
+     * @param breakNode the break node
+     */
+    public void setBreakNode(final Node breakNode) {
+        assert breakNode instanceof BreakableNode || breakNode instanceof Block : "Invalid break node: " + breakNode;
+        this.breakNode = breakNode;
+    }
+
+    /**
+     * Get the continue node for this node
+     * @return the continue node
+     */
+    public Node getContinueNode() {
+        return continueNode;
+    }
+
+    /**
+     * Reset the continue node for this node
+     * @param continueNode the continue node
+     */
+    public void setContinueNode(final Node continueNode) {
+        assert continueNode instanceof WhileNode : "invalid continue node: " + continueNode;
+        this.continueNode = continueNode;
+    }
+
+    /**
+     * Get the identifier representing the label name
+     * @return the label
+     */
+    public IdentNode getLabel() {
+        return label;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LabeledNode.java b/nashorn/src/jdk/nashorn/internal/ir/LabeledNode.java
new file mode 100644
index 0000000..a3783e9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/LabeledNode.java
@@ -0,0 +1,123 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR base class for break and continue.
+ *
+ */
+public abstract class LabeledNode extends Node {
+    /** Optional label. */
+    @Ignore
+    protected final LabelNode labelNode;
+
+    /** Target control node. */
+    @Ignore
+    protected final Node targetNode;
+
+    /** Try chain. */
+    @Ignore
+    protected final TryNode tryChain;
+
+    /** scope nesting level */
+    protected int scopeNestingLevel;
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param finish     finish
+     * @param labelNode  the label node
+     * @param targetNode the place to break to
+     * @param tryChain   the try chain
+     */
+    public LabeledNode(final Source source, final long token, final int finish, final LabelNode labelNode, final Node targetNode, final TryNode tryChain) {
+        super(source, token, finish);
+
+        this.labelNode  = labelNode;
+        this.targetNode = targetNode;
+        this.tryChain   = tryChain;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param labeledNode source node
+     * @param cs          copy state
+     */
+    protected LabeledNode(final LabeledNode labeledNode, final CopyState cs) {
+        super(labeledNode);
+
+        this.labelNode         = (LabelNode)cs.existingOrCopy(labeledNode.labelNode);
+        this.targetNode        = cs.existingOrSame(labeledNode.targetNode);
+        this.tryChain          = (TryNode)cs.existingOrSame(labeledNode.tryChain);
+        this.scopeNestingLevel = labeledNode.scopeNestingLevel;
+    }
+
+    /**
+     * Get the label
+     * @return the label
+     */
+    public LabelNode getLabel() {
+        return labelNode;
+    }
+
+    /**
+     * Get the target node
+     * @return the target node
+     */
+    public Node getTargetNode() {
+        return targetNode;
+    }
+
+    /**
+     * Get the surrounding try chain
+     * @return the try chain
+     */
+    public TryNode getTryChain() {
+        return tryChain;
+    }
+
+    /**
+     * Get the scope nesting level
+     * @return nesting level
+     */
+    public int getScopeNestingLevel() {
+        return scopeNestingLevel;
+    }
+
+    /**
+     * Set scope nesting level
+     * @param level the new level
+     */
+    public void setScopeNestingLevel(final int level) {
+        scopeNestingLevel = level;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java b/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java
new file mode 100644
index 0000000..ef1c05e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java
@@ -0,0 +1,97 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR Node representing a line number
+ */
+
+public class LineNumberNode extends Node {
+    /** Line number */
+    private final int lineNumber;
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param lineNumber the line number
+     */
+    public LineNumberNode(final Source source, final long token, final int lineNumber) {
+        super(source, token, Token.descPosition(token));
+
+        this.lineNumber = lineNumber;
+    }
+
+   private LineNumberNode(final LineNumberNode lineNumberNode) {
+        super(lineNumberNode);
+
+        this.lineNumber = lineNumberNode.getLineNumber();
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new LineNumberNode(this);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("[|");
+        sb.append(lineNumber);
+        sb.append("|]");
+    }
+
+    @Override
+    public boolean isAtom() {
+        return true;
+    }
+
+    /**
+     * Get the line number
+     * @return line number
+     */
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public boolean isDebug() {
+        return true;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
new file mode 100644
index 0000000..f1bf1b8
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
@@ -0,0 +1,953 @@
+/*
+ * 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.ir;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import jdk.nashorn.internal.codegen.CompileUnit;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Lexer.LexerToken;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.Undefined;
+
+/**
+ * Literal nodes represent JavaScript values.
+ *
+ * @param <T> the literal type
+ */
+public abstract class LiteralNode<T> extends Node implements PropertyKey {
+    /** Literal value */
+    protected T value;
+
+     /**
+     * Constructor
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param value   the value of the literal
+     */
+    protected LiteralNode(final Source source, final long token, final int finish, final T value) {
+        super(source, token, finish);
+        this.value = value;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param literalNode source node
+     */
+    protected LiteralNode(final LiteralNode<T> literalNode) {
+        super(literalNode);
+        this.value = literalNode.value;
+    }
+
+    @Override
+    public boolean isAtom() {
+        return true;
+    }
+
+    /**
+     * Check if the literal value is null
+     * @return true if literal value is null
+     */
+    public boolean isNull() {
+        return value == null;
+    }
+
+    @Override
+    public int hashCode() {
+        return value == null ? 0 : value.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!(other instanceof LiteralNode<?>)) {
+            return false;
+        }
+        final LiteralNode<?> otherNode = (LiteralNode<?>)other;
+        if (otherNode.isNull()) {
+            return isNull();
+        }
+        return ((LiteralNode<?>)other).getValue().equals(value);
+    }
+
+    /**
+     * Check if the literal value is boolean true
+     * @return true if literal value is boolean true
+     */
+    public boolean isTrue() {
+        return JSType.toBoolean(value);
+    }
+
+    @Override
+    public Type getType() {
+        return Type.typeFor(value.getClass());
+    }
+
+    @Override
+    public String getPropertyName() {
+        return JSType.toString(getObject());
+    }
+
+    /**
+     * Fetch boolean value of node.
+     *
+     * @return boolean value of node.
+     */
+    public boolean getBoolean() {
+        return JSType.toBoolean(value);
+    }
+
+    /**
+     * Fetch int32 value of node.
+     *
+     * @return Int32 value of node.
+     */
+    public int getInt32() {
+        return JSType.toInt32(value);
+    }
+
+    /**
+     * Fetch uint32 value of node.
+     *
+     * @return uint32 value of node.
+     */
+    public long getUint32() {
+        return JSType.toUint32(value);
+    }
+
+    /**
+     * Fetch long value of node
+     *
+     * @return long value of node
+     */
+    public long getLong() {
+        return JSType.toLong(value);
+    }
+
+    /**
+     * Fetch double value of node.
+     *
+     * @return double value of node.
+     */
+    public double getNumber() {
+        return JSType.toNumber(value);
+    }
+
+    /**
+     * Get the array value of the node
+     *
+     * @return the array value
+     */
+    public Node[] getArray() {
+        assert false : "not an array node";
+        return null;
+    }
+
+    /**
+     * Fetch String value of node.
+     *
+     * @return String value of node.
+     */
+    public String getString() {
+        return JSType.toString(value);
+    }
+
+    /**
+     * Fetch Object value of node.
+     *
+     * @return Object value of node.
+     */
+    public Object getObject() {
+        return value;
+    }
+
+    /**
+     * Test if the value is a string.
+     *
+     * @return True if value is a string.
+     */
+    public boolean isString() {
+        return value instanceof String;
+    }
+
+    /**
+     * Test if tha value is a number
+     *
+     * @return True if value is a number
+     */
+    public boolean isNumeric() {
+        return value instanceof Number;
+    }
+
+    /**
+     * Assist in IR navigation.
+     *
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        if (value == null) {
+            sb.append("null");
+        } else {
+            sb.append(value.toString());
+        }
+    }
+
+    /**
+     * Get the literal node value
+     * @return the value
+     */
+    public T getValue() {
+        return value;
+    }
+
+    /**
+     * Create a new null literal
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<Node> newInstance(final Source source, final long token, final int finish) {
+        return new NodeLiteralNode(source, token, finish);
+    }
+
+    /**
+     * Create a new null literal based on a parent node (source, token, finish)
+     *
+     * @param parent parent node
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<?> newInstance(final Node parent) {
+        return new NodeLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish());
+    }
+
+    private static class BooleanLiteralNode extends LiteralNode<Boolean> {
+
+        private BooleanLiteralNode(final Source source, final long token, final int finish, final boolean value) {
+            super(source, Token.recast(token, value ? TokenType.TRUE : TokenType.FALSE), finish, value);
+        }
+
+        private BooleanLiteralNode(final BooleanLiteralNode literalNode) {
+            super(literalNode);
+        }
+
+        @Override
+        protected Node copy(final CopyState cs) {
+            return new BooleanLiteralNode(this);
+        }
+
+        @Override
+        public boolean isTrue() {
+            return value;
+        }
+
+        @Override
+        public Type getType() {
+            return Type.BOOLEAN;
+        }
+
+        @Override
+        public Type getWidestOperationType() {
+            return Type.BOOLEAN;
+        }
+    }
+
+    /**
+     * Create a new boolean literal
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param value   true or false
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<Boolean> newInstance(final Source source, final long token, final int finish, final boolean value) {
+        return new BooleanLiteralNode(source, token,  finish, value);
+    }
+
+    /**
+     * Create a new boolean literal based on a parent node (source, token, finish)
+     *
+     * @param parent parent node
+     * @param value  true or false
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<?> newInstance(final Node parent, final boolean value) {
+        return new BooleanLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+    }
+
+    private static class NumberLiteralNode extends LiteralNode<Number> {
+
+        private final Type type = numberGetType(value);
+
+        private NumberLiteralNode(final Source source, final long token, final int finish, final Number value) {
+            super(source, Token.recast(token, TokenType.DECIMAL), finish, value);
+        }
+
+        private NumberLiteralNode(final NumberLiteralNode literalNode) {
+            super(literalNode);
+        }
+
+        private static Type numberGetType(final Number number) {
+            if (number instanceof Integer) {
+                return Type.INT;
+            } else if (number instanceof Long) {
+                return Type.LONG;
+            } else if (number instanceof Double) {
+                return Type.NUMBER;
+            } else {
+                assert false;
+            }
+
+            return null;
+        }
+
+        @Override
+        protected Node copy(final CopyState cs) {
+            return new NumberLiteralNode(this);
+        }
+
+        @Override
+        public Type getType() {
+            return type;
+        }
+
+        @Override
+        public Type getWidestOperationType() {
+            return getType();
+        }
+
+    }
+    /**
+     * Create a new number literal
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param value   literal value
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<Number> newInstance(final Source source, final long token, final int finish, final Number value) {
+        return new NumberLiteralNode(source, token, finish, value);
+    }
+
+    /**
+     * Create a new number literal based on a parent node (source, token, finish)
+     *
+     * @param parent parent node
+     * @param value  literal value
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<?> newInstance(final Node parent, final Number value) {
+        return new NumberLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+    }
+
+    private static class UndefinedLiteralNode extends LiteralNode<Undefined> {
+        private UndefinedLiteralNode(final Source source, final long token, final int finish) {
+            super(source, Token.recast(token, TokenType.OBJECT), finish, ScriptRuntime.UNDEFINED);
+        }
+
+        private UndefinedLiteralNode(final UndefinedLiteralNode literalNode) {
+            super(literalNode);
+        }
+
+        @Override
+        protected Node copy(final CopyState cs) {
+            return new UndefinedLiteralNode(this);
+        }
+    }
+
+    /**
+     * Create a new undefined literal
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param value   undefined value, passed only for polymorphisism discrimination
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<Undefined> newInstance(final Source source, final long token, final int finish, final Undefined value) {
+        return new UndefinedLiteralNode(source, token, finish);
+    }
+
+    /**
+     * Create a new null literal based on a parent node (source, token, finish)
+     *
+     * @param parent parent node
+     * @param value  undefined value
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<?> newInstance(final Node parent, final Undefined value) {
+        return new UndefinedLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish());
+    }
+
+    private static class StringLiteralNode extends LiteralNode<String> {
+        private StringLiteralNode(final Source source, final long token, final int finish, final String value) {
+            super(source, Token.recast(token, TokenType.STRING), finish, value);
+        }
+
+        private StringLiteralNode(final StringLiteralNode literalNode) {
+            super(literalNode);
+        }
+
+        @Override
+        protected Node copy(final CopyState cs) {
+            return new StringLiteralNode(this);
+        }
+
+        @Override
+        public void toString(final StringBuilder sb) {
+            sb.append('\"');
+            sb.append(value);
+            sb.append('\"');
+        }
+    }
+
+    /**
+     * Create a new string literal
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param value   string value
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<String> newInstance(final Source source, final long token, final int finish, final String value) {
+        return new StringLiteralNode(source, token, finish, value);
+    }
+
+    /**
+     * Create a new String literal based on a parent node (source, token, finish)
+     *
+     * @param parent parent node
+     * @param value  string value
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<?> newInstance(final Node parent, final String value) {
+        return new StringLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+    }
+
+    private static class LexerTokenLiteralNode extends LiteralNode<LexerToken> {
+        private LexerTokenLiteralNode(final Source source, final long token, final int finish, final LexerToken value) {
+            super(source, Token.recast(token, TokenType.STRING), finish, value); //TODO is string the correct token type here?
+        }
+
+        private LexerTokenLiteralNode(final LexerTokenLiteralNode literalNode) {
+            super(literalNode);
+        }
+
+        @Override
+        protected Node copy(final CopyState cs) {
+            return new LexerTokenLiteralNode(this);
+        }
+
+        @Override
+        public Type getType() {
+            return Type.OBJECT;
+        }
+
+        @Override
+        public void toString(final StringBuilder sb) {
+            sb.append(value.toString());
+        }
+    }
+
+    /**
+     * Create a new literal node for a lexer token
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param value   lexer token value
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<LexerToken> newInstance(final Source source, final long token, final int finish, final LexerToken value) {
+        return new LexerTokenLiteralNode(source, token, finish, value);
+    }
+
+    /**
+     * Create a new lexer token literal based on a parent node (source, token, finish)
+     *
+     * @param parent parent node
+     * @param value  lexer token
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<?> newInstance(final Node parent, final LexerToken value) {
+        return new LexerTokenLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+    }
+
+    private static class NodeLiteralNode extends LiteralNode<Node> {
+
+        private NodeLiteralNode(final Source source, final long token, final int finish) {
+            this(source, token, finish, null);
+        }
+
+        private NodeLiteralNode(final Source source, final long token, final int finish, final Node value) {
+            super(source, Token.recast(token, TokenType.OBJECT), finish, value);
+        }
+
+        private NodeLiteralNode(final LiteralNode<Node> literalNode) {
+            super(literalNode);
+        }
+
+        @Override
+        protected Node copy(final CopyState cs) {
+            return new NodeLiteralNode(this);
+        }
+
+        @Override
+        public Node accept(final NodeVisitor visitor) {
+            if (visitor.enter(this) != null) {
+                if (value != null) {
+                    value = value.accept(visitor);
+                }
+                return visitor.leave(this);
+            }
+
+            return this;
+        }
+
+        @Override
+        public Type getType() {
+            return value == null ? Type.OBJECT : super.getType();
+        }
+
+        @Override
+        public Type getWidestOperationType() {
+            return value == null ? Type.OBJECT : value.getWidestOperationType();
+        }
+
+    }
+    /**
+     * Create a new node literal for an arbitrary node
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param value   the literal value node
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<Node> newInstance(final Source source, final long token, final int finish, final Node value) {
+        return new NodeLiteralNode(source, token, finish, value);
+    }
+
+    /**
+     * Create a new node literal based on a parent node (source, token, finish)
+     *
+     * @param parent parent node
+     * @param value  node value
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<?> newInstance(final Node parent, final Node value) {
+        return new NodeLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value);
+    }
+
+    /**
+     * Array literal node class.
+     */
+    public static class ArrayLiteralNode extends LiteralNode<Node[]> {
+        private static class PostsetMarker {
+            //empty
+        }
+
+        private static PostsetMarker POSTSET_MARKER = new PostsetMarker();
+
+        /** Array element type. */
+        private Type elementType;
+
+        /** Preset constant array. */
+        private Object presets;
+
+        /** Indices of array elements requiring computed post sets. */
+        private int[] postsets;
+
+        private List<ArrayUnit> units;
+
+        /**
+         * An ArrayUnit is a range in an ArrayLiteral. ArrayLiterals can
+         * be split if they are too large, for bytecode generation reasons
+         */
+        public static class ArrayUnit {
+            /** Compile unit associated with the postsets range. */
+            private final CompileUnit compileUnit;
+
+            /** postsets range associated with the unit (hi not inclusive). */
+            private final int lo, hi;
+
+            /**
+             * Constructor
+             * @param compileUnit compile unit
+             * @param lo lowest array index in unit
+             * @param hi highest array index in unit + 1
+             */
+            public ArrayUnit(final CompileUnit compileUnit, final int lo, final int hi) {
+                this.compileUnit = compileUnit;
+                this.lo   = lo;
+                this.hi   = hi;
+            }
+
+            /**
+             * Get the high index position of the ArrayUnit (non inclusive)
+             * @return high index position
+             */
+            public int getHi() {
+                return hi;
+            }
+
+            /**
+             * Get the low index position of the ArrayUnit (inclusive)
+             * @return low index position
+             */
+            public int getLo() {
+                return lo;
+            }
+
+            /**
+             * The array compile unit
+             * @return array compile unit
+             */
+            public CompileUnit getCompileUnit() {
+                return compileUnit;
+            }
+        }
+
+        /**
+         * Constructor
+         *
+         * @param source  the source
+         * @param token   token
+         * @param finish  finish
+         * @param value   array literal value, a Node array
+         */
+        protected ArrayLiteralNode(final Source source, final long token, final int finish, final Node[] value) {
+            super(source, Token.recast(token, TokenType.ARRAY), finish, value);
+            this.elementType = Type.UNKNOWN;
+        }
+
+        /**
+         * Copy constructor
+         * @param node source array literal node
+         */
+        protected ArrayLiteralNode(final ArrayLiteralNode node) {
+            super(node);
+            this.elementType = node.elementType;
+        }
+
+        @Override
+        protected Node copy(final CopyState cs) {
+            return new ArrayLiteralNode(this);
+        }
+
+        /**
+         * Compute things like widest element type needed. Internal use from compiler only
+         */
+        public void analyze() {
+            elementType = Type.INT;
+            analyzeElements();
+
+            if (elementType == Type.INT) {
+                presetIntArray();
+            } else if (elementType.isNumeric()) {
+                presetNumberArray();
+            } else {
+                presetObjectArray();
+            }
+        }
+
+        private void presetIntArray() {
+            final int[] array = new int[value.length];
+            final int[] computed = new int[value.length];
+            int nComputed = 0;
+
+            for (int i = 0; i < value.length; i++) {
+                final Object element = objectAsConstant(value[i]);
+
+                if (element instanceof Number) {
+                    array[i] = ((Number)element).intValue();
+                } else {
+                    computed[nComputed++] = i;
+                }
+            }
+
+            presets = array;
+            postsets = Arrays.copyOf(computed, nComputed);
+        }
+
+        private void presetNumberArray() {
+            final double[] array = new double[value.length];
+            final int[] computed = new int[value.length];
+            int nComputed = 0;
+
+            for (int i = 0; i < value.length; i++) {
+                final Object element = objectAsConstant(value[i]);
+
+                if (element instanceof Number) {
+                    array[i] = ((Number)element).doubleValue();
+                } else {
+                    computed[nComputed++] = i;
+                }
+            }
+
+            presets = array;
+            postsets = Arrays.copyOf(computed, nComputed);
+        }
+
+        private void presetObjectArray() {
+            final Object[] array = new Object[value.length];
+            final int[] computed = new int[value.length];
+            int nComputed = 0;
+
+            for (int i = 0; i < value.length; i++) {
+                final Node node = value[i];
+
+                if (node == null) {
+                    computed[nComputed++] = i;
+                } else {
+                    final Object element = objectAsConstant(node);
+
+                    if (element != POSTSET_MARKER) {
+                        array[i] = element;
+                    } else {
+                        computed[nComputed++] = i;
+                    }
+                }
+            }
+
+            presets = array;
+            postsets = Arrays.copyOf(computed, nComputed);
+        }
+
+        private void analyzeElements() {
+            for (final Node node : value) {
+                if (node == null) {
+                    elementType = elementType.widest(Type.OBJECT); //no way to represent undefined as number
+                    break;
+                }
+
+                final Symbol symbol = node.getSymbol();
+                assert symbol != null; //don't run this on unresolved nodes or you are in trouble
+                Type symbolType = symbol.getSymbolType();
+                if (symbolType.isUnknown()) {
+                    symbolType = Type.OBJECT;
+                }
+
+                if (symbolType.isBoolean()) {
+                    elementType = elementType.widest(Type.OBJECT);
+                    break;
+                }
+
+                elementType = elementType.widest(symbolType);
+
+                if (elementType.isObject()) {
+                    break;
+                }
+            }
+        }
+
+        private Object objectAsConstant(final Object object) {
+            if (object == null) {
+                return null;
+            } else if (object instanceof Number || object instanceof String || object instanceof Boolean) {
+                return object;
+            } else if (object instanceof LiteralNode) {
+                return objectAsConstant(((LiteralNode<?>)object).getValue());
+            } else if (object instanceof UnaryNode) {
+                final UnaryNode unaryNode = (UnaryNode)object;
+
+                if (unaryNode.isTokenType(TokenType.CONVERT) && unaryNode.getType().isObject()) {
+                    return objectAsConstant(unaryNode.rhs());
+                }
+            }
+
+            return POSTSET_MARKER;
+        }
+
+        @Override
+        public Node[] getArray() {
+            return value;
+        }
+
+        @Override
+        public Type getType() {
+            if (elementType.isInteger()) {
+                return Type.INT_ARRAY;
+            } else if (elementType.isNumeric()) {
+                return Type.NUMBER_ARRAY;
+            } else {
+                return Type.OBJECT_ARRAY;
+            }
+        }
+
+        /**
+         * Get the element type of this array literal
+         * @return element type
+         */
+        public Type getElementType() {
+            return elementType;
+        }
+
+        /**
+         * Get indices of arrays containing computed post sets
+         * @return post set indices
+         */
+        public int[] getPostsets() {
+            return postsets;
+        }
+
+        /**
+         * Get presets constant array
+         * @return presets array, always returns an array type
+         */
+        public Object getPresets() {
+            return presets;
+        }
+
+        /**
+         * Get the array units that make up this ArrayLiteral
+         * @see ArrayUnit
+         * @return list of array units
+         */
+        public List<ArrayUnit> getUnits() {
+            return units == null ? null : Collections.unmodifiableList(units);
+        }
+
+        /**
+         * Set the ArrayUnits that make up this ArrayLiteral
+         * @see ArrayUnit
+         * @param units list of array units
+         */
+        public void setUnits(final List<ArrayUnit> units) {
+            this.units = units;
+        }
+
+        @Override
+        public Node accept(final NodeVisitor visitor) {
+            if (visitor.enter(this) != null) {
+                for (int i = 0; i < value.length; i++) {
+                    final Node element = value[i];
+                    if (element != null) {
+                        value[i] = element.accept(visitor);
+                    }
+                }
+                return visitor.leave(this);
+            }
+            return this;
+        }
+
+        @Override
+        public void toString(final StringBuilder sb) {
+            sb.append('[');
+            boolean first = true;
+            for (final Node node : value) {
+                if (!first) {
+                    sb.append(',');
+                    sb.append(' ');
+                }
+                if (node == null) {
+                    sb.append("undefined");
+                } else {
+                    node.toString(sb);
+                }
+                first = false;
+            }
+            sb.append(']');
+        }
+    }
+
+    /**
+     * Create a new array literal of Nodes from a list of Node values
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param value   literal value list
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<Node[]> newInstance(final Source source, final long token, final int finish, final List<Node> value) {
+        return new ArrayLiteralNode(source, token, finish, value.toArray(new Node[value.size()]));
+    }
+
+
+    /**
+     * Create a new array literal based on a parent node (source, token, finish)
+     *
+     * @param parent parent node
+     * @param value  literal value list
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<?> newInstance(final Node parent, final List<Node> value) {
+        return new ArrayLiteralNode(parent.getSource(), parent.getToken(), parent.getFinish(), value.toArray(new Node[value.size()]));
+    }
+
+    /**
+     * Create a new array literal of Nodes
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param value   literal value array
+     *
+     * @return the new literal node
+     */
+    public static LiteralNode<Node[]> newInstance(final Source source, final long token, final int finish, final Node[] value) {
+        return new ArrayLiteralNode(source, token, finish, value);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Location.java b/nashorn/src/jdk/nashorn/internal/ir/Location.java
new file mode 100644
index 0000000..16ee680
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/Location.java
@@ -0,0 +1,142 @@
+/*
+ * 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.ir;
+
+import java.util.Objects;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * Used to locate an entity back to it's source file.
+ *
+ */
+
+public class Location implements Cloneable {
+    /** Source of entity. */
+    private final Source source;
+
+    /** Token descriptor. */
+    private final long token;
+
+    /**
+     * Constructor
+     *
+     * @param source the source
+     * @param token  token
+     */
+    public Location(final Source source, final long token) {
+        this.source = source;
+        this.token = token;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param location source node
+     */
+    protected Location(final Location location) {
+        this.source = location.source;
+        this.token = location.token;
+    }
+
+    @Override
+    protected Object clone() {
+        return new Location(this);
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other == null) {
+            return false;
+        }
+
+        if (other.getClass() != this.getClass()) {
+            return false;
+        }
+
+        final Location loc = (Location)other;
+        return token == loc.token && Objects.equals(source, loc.source);
+    }
+
+    @Override
+    public int hashCode() {
+        return Token.hashCode(token) ^ Objects.hashCode(source);
+    }
+
+    /**
+     * Return token position from a token descriptor.
+     *
+     * @return Start position of the token in the source.
+     */
+    public int position() {
+        return Token.descPosition(token);
+    }
+
+    /**
+     * Return token length from a token descriptor.
+     *
+     * @return Length of the token.
+     */
+    public int length() {
+        return Token.descLength(token);
+    }
+
+    /**
+     * Return token tokenType from a token descriptor.
+     *
+     * @return Type of token.
+     */
+    public TokenType tokenType() {
+        return Token.descType(token);
+    }
+
+    /**
+     * Test token tokenType.
+     *
+     * @param type a type to check this token against
+     * @return true if token types match.
+     */
+    public boolean isTokenType(final TokenType type) {
+        return Token.descType(token) == type;
+    }
+
+    /**
+     * Get the source for this location
+     * @return the source
+     */
+    public Source getSource() {
+        return source;
+    }
+
+    /**
+     * Get the token for this location
+     * @return the token
+     */
+    public long getToken() {
+        return token;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Node.java b/nashorn/src/jdk/nashorn/internal/ir/Node.java
new file mode 100644
index 0000000..24ad879
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/Node.java
@@ -0,0 +1,414 @@
+/*
+ * 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.ir;
+
+import java.util.IdentityHashMap;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * Nodes are used to compose Abstract Syntax Trees.
+ *
+ */
+public abstract class Node extends Location {
+    /** Node symbol. */
+    private Symbol symbol;
+
+    /** Start of source range. */
+    protected int start;
+
+    /** End of source range. */
+    protected int finish;
+
+    /** Has this node been resolved - i.e. emitted code already */
+    private boolean isResolved;
+
+    /** Is this node terminal */
+    private boolean isTerminal;
+
+    /** Is this a goto node */
+    private boolean hasGoto;
+
+    /** Is this a discard */
+    private boolean shouldDiscard;
+
+    /**
+     * Constructor
+     *
+     * @param source the source
+     * @param token  token
+     * @param finish finish
+     */
+    public Node(final Source source, final long token, final int finish) {
+        super(source, token);
+
+        this.start  = Token.descPosition(token);
+        this.finish = finish;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param node source node
+     */
+    protected Node(final Node node) {
+        super(node);
+
+        this.symbol        = node.symbol;
+        this.isResolved    = node.isResolved;
+        this.isTerminal    = node.isTerminal;
+        this.hasGoto       = node.hasGoto;
+        this.shouldDiscard = node.shouldDiscard;
+        this.start         = node.start;
+        this.finish        = node.finish;
+    }
+
+    /**
+     * Check if the node has a type. The default behavior is to go into the symbol
+     * and check the symbol type, but there may be overrides, for example in
+     * getters that require a different type than the internal representation
+     *
+     * @return true if a type exists
+     */
+    public boolean hasType() {
+        return getSymbol() != null;
+    }
+
+    /**
+     * Returns the type of the node. Typically this is the symbol type. No types
+     * are stored in the node itself, unless it implements TypeOverride
+     *
+     * @return the type of the node.
+     */
+    public Type getType() {
+        assert hasType() : this + " has no type";
+        return symbol.getSymbolType();
+    }
+
+    /**
+     * Is this an atom node - for example a literal or an identity
+     *
+     * @return true if atom
+     */
+    public boolean isAtom() {
+        return false;
+    }
+
+    /**
+     * Is this a loop node?
+     *
+     * @return true if atom
+     */
+    public boolean isLoop() {
+        return false;
+    }
+
+    /**
+     * Is this an assignment node - for example a var node with an init
+     * or a binary node that writes to a destination
+     *
+     * @return true if assignment
+     */
+    public boolean isAssignment() {
+        return false;
+    }
+
+    /**
+     * Is this a self modifying assignment?
+     * @return true if self modifying, e.g. a++, or a*= 17
+     */
+    public boolean isSelfModifying() {
+        return false;
+    }
+
+    /**
+     * Returns widest operation type of this operation.
+     *
+     * @return the widest type for this operation
+     */
+    public Type getWidestOperationType() {
+        return Type.OBJECT;
+    }
+
+    /**
+     * Test to see if code been generated for this node. Set isResolved if not.
+     *
+     * @return True if node has already been resolved.
+     */
+    public boolean testResolved() {
+        if (isResolved()) {
+            return true;
+        }
+
+        setIsResolved();
+
+        return false;
+    }
+
+    /**
+     * Is this a debug info node like LineNumberNode etc?
+     *
+     * @return true if this is a debug node
+     */
+    public boolean isDebug() {
+        return false;
+    }
+
+    /**
+     * Helper class used for node cloning
+     */
+    public static final class CopyState {
+        private final IdentityHashMap<Node, Node> cloneMap = new IdentityHashMap<>();
+
+        /**
+         * Find existing or create new copy of the node.
+         *
+         * @param node Node to copy.
+         *
+         * @return New object.
+         */
+        public Node existingOrCopy(final Node node) {
+            if (node != null) {
+                Node copy = cloneMap.get(node);
+
+                if (copy == null) {
+                    copy = node.copy(this);
+                    cloneMap.put(node, copy);
+                }
+
+                return copy;
+            }
+
+            return node;
+        }
+
+        /**
+         * Find existing or use old copy of the node.
+         *
+         * @param node Node to copy.
+         *
+         * @return new object.
+         */
+        public Node existingOrSame(final Node node) {
+            if (node != null) {
+                Node copy = cloneMap.get(node);
+
+                if (copy == null) {
+                    copy = node;
+                }
+
+                return copy;
+            }
+
+            return node;
+        }
+    }
+
+    /**
+     * Deep copy the node.
+     *
+     * @return Deep copy of the  Node.
+     */
+    @Override
+    public final Node clone() {
+        return copy(new CopyState());
+    }
+
+    /**
+     * Deep copy the node.
+     *
+     * @param cs CopyState passed around to re-use certain nodes.
+     * @return Deep copy of the  Node.
+     */
+    protected Node copy(final CopyState cs) {
+        return cs.existingOrCopy(this);
+    }
+
+    /**
+     * Provides a means to navigate the IR.
+     * @param visitor Node visitor.
+     * @return node the node or its replacement after visitation, null if no further visitations are required
+     */
+    public abstract Node accept(NodeVisitor visitor);
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /**
+     * String conversion helper. Fills a {@link StringBuilder} with the
+     * string version of this node
+     *
+     * @param sb a StringBuilder
+     */
+    public abstract void toString(StringBuilder sb);
+
+    /**
+     * Check if this node has terminal flags, i.e. ends or breaks control flow
+     *
+     * @return true if terminal
+     */
+    public boolean hasTerminalFlags() {
+        return isTerminal || hasGoto;
+    }
+
+    /**
+     * Copy the terminal flags state of a node to another node
+     *
+     * @param other source node
+     */
+    public void copyTerminalFlags(final Node other) {
+        isTerminal = other.isTerminal;
+        hasGoto    = other.hasGoto;
+    }
+
+    /**
+     * Check if the return value of this expression should be discarded
+     * @return true if return value is discarded
+     */
+    public boolean shouldDiscard() {
+        return shouldDiscard;
+    }
+
+    /**
+     * Setter that determines whether this node's return value should be discarded
+     * or not
+     *
+     * @param shouldDiscard true if return value is discarded, false otherwise
+     */
+    public void setDiscard(final boolean shouldDiscard) {
+        this.shouldDiscard = shouldDiscard;
+    }
+
+    /**
+     * Get the finish position for this node in the source string
+     * @return finish
+     */
+    public int getFinish() {
+        return finish;
+    }
+
+    /**
+     * Set finish position for this node in the source string
+     * @param finish finish
+     */
+    public void setFinish(final int finish) {
+        this.finish = finish;
+    }
+
+    /**
+     * Check if this function repositions control flow with goto like
+     * semantics, for example {@link BreakNode} or a {@link ForNode} with no test
+     * @return true if node has goto semantics
+     */
+    public boolean hasGoto() {
+        return hasGoto;
+    }
+
+    /**
+     * Flag this node as having goto semantics as described in {@link Node#hasGoto()}
+     */
+    public void setHasGoto() {
+        this.hasGoto = true;
+    }
+
+    /**
+     * Check whether this node is resolved, i.e. code has been generated for it
+     * @return true if node is resolved
+     */
+    public boolean isResolved() {
+        return isResolved;
+    }
+
+    /**
+     * Flag this node as resolved, i.e. code has been generated for it
+     */
+    public void setIsResolved() {
+        this.isResolved = true;
+    }
+
+    /**
+     * Get start position for node
+     * @return start position
+     */
+    public int getStart() {
+        return start;
+    }
+
+    /**
+     * Set start position for node
+     * @param start start position
+     */
+    public void setStart(final int start) {
+        this.start = start;
+    }
+
+    /**
+     * Return the Symbol the compiler has assigned to this Node. The symbol
+     * is the place where it's expression value is stored after evaluation
+     *
+     * @return the symbol
+     */
+    public Symbol getSymbol() {
+        return symbol;
+    }
+
+    /**
+     * Assign a symbol to this node. See {@link Node#getSymbol()} for explanation
+     * of what a symbol is
+     *
+     * @param symbol the symbol
+     */
+    public void setSymbol(final Symbol symbol) {
+        this.symbol = symbol;
+    }
+
+    /**
+     * Is this a terminal Node, i.e. does it end control flow like a throw or return
+     * expression does?
+     *
+     * @return true if this node is terminal
+     */
+    public boolean isTerminal() {
+        return isTerminal;
+    }
+
+    /**
+     * Set this to be a terminal node, i.e. it terminates control flow as described
+     * in {@link Node#isTerminal()}
+     *
+     * @param isTerminal true if this is a terminal node, false otherwise
+     */
+    public void setIsTerminal(final boolean isTerminal) {
+        this.isTerminal = isTerminal;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java b/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java
new file mode 100644
index 0000000..ab7e49e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java
@@ -0,0 +1,134 @@
+/*
+ * 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.ir;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation of an object literal.
+ */
+public class ObjectNode extends Node {
+    /** Literal context. */
+    @Ignore
+    private Block context;
+
+    /** Literal elements. */
+    private final List<Node> elements;
+
+    /**
+     * Constructor
+     *
+     * @param source   the source
+     * @param token    token
+     * @param finish   finish
+     * @param context  the block for this ObjectNode
+     * @param elements the elements used to initialize this ObjectNode
+     */
+    public ObjectNode(final Source source, final long token, final int finish, final Block context, final List<Node> elements) {
+        super(source, token, finish);
+
+        this.context  = context;
+        this.elements = elements;
+    }
+
+    private ObjectNode(final ObjectNode objectNode, final CopyState cs) {
+        super(objectNode);
+
+        final List<Node> newElements = new ArrayList<>();
+
+        for (final Node element : objectNode.elements) {
+            newElements.add(cs.existingOrCopy(element));
+        }
+
+        this.context  = (Block)cs.existingOrCopy(objectNode.context);
+        this.elements = newElements;
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new ObjectNode(this, cs);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            if (context != null) {
+                context = (Block)context.accept(visitor);
+            }
+
+            for (int i = 0, count = elements.size(); i < count; i++) {
+                elements.set(i, elements.get(i).accept(visitor));
+            }
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append('{');
+
+        if (!elements.isEmpty()) {
+            sb.append(' ');
+
+            boolean first = true;
+            for (final Node element : elements) {
+                if (!first) {
+                    sb.append(", ");
+                }
+                first = false;
+
+                element.toString(sb);
+            }
+            sb.append(' ');
+        }
+
+        sb.append('}');
+    }
+
+    /**
+     * Get the block that is this ObjectNode's literal context
+     * @return the block
+     */
+    public Block getContext() {
+        return context;
+    }
+
+    /**
+     * Get the elements of this literal node
+     * @return a list of elements
+     */
+    public List<Node> getElements() {
+        return Collections.unmodifiableList(elements);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/PropertyKey.java b/nashorn/src/jdk/nashorn/internal/ir/PropertyKey.java
new file mode 100644
index 0000000..e4a72aa
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/PropertyKey.java
@@ -0,0 +1,39 @@
+/*
+ * 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.ir;
+
+/**
+ * Any node that can be a property key inherits this
+ */
+public interface PropertyKey {
+
+    /**
+     * Get the property name
+     *
+     * @return the property name
+     */
+    public abstract String getPropertyName();
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java b/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java
new file mode 100644
index 0000000..7510337
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java
@@ -0,0 +1,190 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.annotations.Reference;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation of an object literal property.
+ */
+public class PropertyNode extends Node {
+
+    /** Property key. */
+    private PropertyKey key;
+
+    /** Property value. */
+    private Node value;
+
+    /** Property getter. */
+    @Reference
+    private Node getter;
+
+    /** Property getter. */
+    @Reference
+    private Node setter;
+
+    /**
+     * Constructor
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param key     the key of this property
+     * @param value   the value of this property
+     */
+    public PropertyNode(final Source source, final long token, final int finish, final PropertyKey key, final Node value) {
+        super(source, token, finish);
+
+        this.key    = key;
+        this.value  = value;
+    }
+
+    private PropertyNode(final PropertyNode propertyNode, final CopyState cs) {
+        super(propertyNode);
+
+        this.key    = (PropertyKey)cs.existingOrCopy((Node)propertyNode.key);
+        this.value  = cs.existingOrCopy(propertyNode.value);
+        this.getter = cs.existingOrSame(propertyNode.getter);
+        this.setter = cs.existingOrSame(propertyNode.setter);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new PropertyNode(this, cs);
+    }
+
+    /**
+     * Get the name of the property key
+     * @return key name
+     */
+    public String getKeyName() {
+        return key.getPropertyName();
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            key = (PropertyKey)((Node)key).accept(visitor);
+
+            if (value != null) {
+                value = value.accept(visitor);
+            }
+
+            if (getter != null) {
+                getter = getter.accept(visitor);
+            }
+
+            if (setter != null) {
+                setter = setter.accept(visitor);
+            }
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        if (value instanceof FunctionNode && ((FunctionNode)value).getIdent() != null) {
+            value.toString(sb);
+        }
+
+        if (value != null) {
+            ((Node)key).toString(sb);
+            sb.append(": ");
+            value.toString(sb);
+        }
+
+        if (getter != null) {
+            sb.append(' ');
+            getter.toString(sb);
+        }
+
+        if (setter != null) {
+            sb.append(' ');
+            setter.toString(sb);
+        }
+    }
+
+    /**
+     * Get the getter for this property
+     * @return getter or null if none exists
+     */
+    public Node getGetter() {
+        return getter;
+    }
+
+    /**
+     * Set the getter of this property, null if none
+     * @param getter getter
+     */
+    public void setGetter(final Node getter) {
+        this.getter = getter;
+    }
+
+    /**
+     * Return the key for this property node
+     * @return the key
+     */
+    public Node getKey() {
+        return (Node)key;
+    }
+
+    /**
+     * Get the setter for this property
+     * @return setter or null if none exists
+     */
+    public Node getSetter() {
+        return setter;
+    }
+
+    /**
+     * Set the setter for this property, null if none
+     * @param setter setter
+     */
+    public void setSetter(final Node setter) {
+        this.setter = setter;
+    }
+
+    /**
+     * Get the value of this property
+     * @return property value
+     */
+    public Node getValue() {
+        return value;
+    }
+
+    /**
+     * Set the value of this property
+     * @param value new value
+     */
+    public void setValue(final Node value) {
+        this.value = value;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ReferenceNode.java b/nashorn/src/jdk/nashorn/internal/ir/ReferenceNode.java
new file mode 100644
index 0000000..3cae7b5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/ReferenceNode.java
@@ -0,0 +1,91 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.annotations.Reference;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation of a reference to another entity (function.)
+ */
+public class ReferenceNode extends Node {
+    /** Node referenced. */
+    @Reference
+    private final FunctionNode reference;
+
+    /**
+     * Constructor
+     *
+     * @param source the source
+     * @param token  token
+     * @param finish finish
+     * @param reference the function node to reference
+     */
+    public ReferenceNode(final Source source, final long token, final int finish, final FunctionNode reference) {
+        super(source, token, finish);
+
+        this.reference = reference;
+    }
+
+    private ReferenceNode(final ReferenceNode referenceNode) {
+        super(referenceNode);
+
+        this.reference = referenceNode.reference;
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new ReferenceNode(this);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        if (reference == null) {
+            sb.append("null");
+        } else {
+            reference.toString(sb);
+        }
+    }
+
+    /**
+     * Get there function node reference that this node points tp
+     * @return a function node reference
+     */
+    public FunctionNode getReference() {
+        return reference;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java b/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java
new file mode 100644
index 0000000..35395b3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java
@@ -0,0 +1,166 @@
+/*
+ * 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.ir;
+
+import static jdk.nashorn.internal.parser.TokenType.RETURN;
+import static jdk.nashorn.internal.parser.TokenType.YIELD;
+
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for RETURN or YIELD statements.
+ *
+ */
+public class ReturnNode extends Node {
+    /** Optional expression. */
+    private Node expression;
+
+    /** Try chain. */
+    @Ignore
+    private final TryNode tryChain;
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param finish     finish
+     * @param expression expression to return
+     * @param tryChain   surrounding try chain.
+     */
+    public ReturnNode(final Source source, final long token, final int finish, final Node expression, final TryNode tryChain) {
+        super(source, token, finish);
+
+        this.expression = expression;
+        this.tryChain   = tryChain;
+
+        setIsTerminal(true);
+    }
+
+    private ReturnNode(final ReturnNode returnNode, final CopyState cs) {
+        super(returnNode);
+
+        this.expression = cs.existingOrCopy(returnNode.expression);
+        this.tryChain   = (TryNode)cs.existingOrSame(returnNode.tryChain);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new ReturnNode(this, cs);
+    }
+
+    /**
+     * Return true if is a RETURN node.
+     * @return true if is RETURN node.
+     */
+    public boolean isReturn() {
+        return isTokenType(RETURN);
+    }
+
+    /**
+     * Check if this return node has an expression
+     * @return true if not a void return
+     */
+    public boolean hasExpression() {
+        return expression != null;
+    }
+
+    /**
+     * Return true if is a YIELD node.
+     * @return TRUE if is YIELD node.
+     */
+    public boolean isYield() {
+        return isTokenType(YIELD);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            if (expression != null) {
+                expression = expression.accept(visitor);
+            }
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append(isYield() ? "yield" : "return ");
+
+        if (expression != null) {
+            expression.toString(sb);
+        }
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other instanceof ReturnNode) {
+            final ReturnNode otherReturn = (ReturnNode)other;
+            if (hasExpression() != otherReturn.hasExpression()) {
+                return false;
+            } else if (hasExpression()) {
+                return otherReturn.getExpression().equals(getExpression());
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return 0x4711_17 ^ (expression == null ? 0 : expression.hashCode());
+    }
+
+    /**
+     * Get the expression this node returns
+     * @return return expression, or null if void return
+     */
+    public Node getExpression() {
+        return expression;
+    }
+
+    /**
+     * Reset the expression this node returns
+     * @param expression new expression, or null if void return
+     */
+    public void setExpression(final Node expression) {
+        this.expression = expression;
+    }
+
+    /**
+     * Get the surrounding try chain for this return node
+     * @return try chain
+     */
+    public TryNode getTryChain() {
+        return tryChain;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java b/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java
new file mode 100644
index 0000000..bfc47d1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java
@@ -0,0 +1,474 @@
+/*
+ * 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.ir;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for a runtime call.
+ *
+ */
+public class RuntimeNode extends Node implements TypeOverride {
+
+    /**
+     * Request enum used for meta-information about the runtime request
+     */
+    public enum Request {
+        /** An addition with at least one object */
+        ADD(TokenType.ADD, Type.OBJECT, 2, true),
+        /** Request to enter debugger */
+        DEBUGGER,
+        /** New operator */
+        NEW,
+        /** Typeof operator */
+        TYPEOF,
+        /** void type */
+        VOID,
+        /** Reference error type */
+        REFERENCE_ERROR,
+        /** Delete operator */
+        DELETE(TokenType.DELETE, Type.BOOLEAN, 1),
+        /** Delete operator that always fails -- see Lower */
+        FAIL_DELETE(TokenType.DELETE, Type.BOOLEAN, 1, false),
+        /** === operator with at least one object */
+        EQ_STRICT(TokenType.EQ_STRICT, Type.BOOLEAN, 2, true),
+        /** == operator with at least one object */
+        EQ(TokenType.EQ, Type.BOOLEAN, 2, true),
+        /** {@literal >=} operator with at least one object */
+        GE(TokenType.GE, Type.BOOLEAN, 2, true),
+        /** {@literal >} operator with at least one object */
+        GT(TokenType.GT, Type.BOOLEAN, 2, true),
+        /** in operator */
+        IN(TokenType.IN, Type.BOOLEAN, 2),
+        /** instanceof operator */
+        INSTANCEOF(TokenType.INSTANCEOF, Type.BOOLEAN, 2),
+        /** {@literal <=} operator with at least one object */
+        LE(TokenType.LE, Type.BOOLEAN, 2, true),
+        /** {@literal <} operator with at least one object */
+        LT(TokenType.LT, Type.BOOLEAN, 2, true),
+        /** !== operator with at least one object */
+        NE_STRICT(TokenType.NE_STRICT, Type.BOOLEAN, 2, true),
+        /** != operator with at least one object */
+        NE(TokenType.NE, Type.BOOLEAN, 2, true);
+
+        /** token type */
+        private final TokenType tokenType;
+
+        /** return type for request */
+        private final Type returnType;
+
+        /** arity of request */
+        private final int arity;
+
+        /** Can the specializer turn this into something that works with 1 or more primitives? */
+        private final boolean canSpecialize;
+
+        private Request() {
+            this(TokenType.VOID, Type.OBJECT, 0);
+        }
+
+        private Request(final TokenType tokenType, final Type returnType, final int arity) {
+            this(tokenType, returnType, arity, false);
+        }
+
+        private Request(final TokenType tokenType, final Type returnType, final int arity, final boolean canSpecialize) {
+            this.tokenType     = tokenType;
+            this.returnType    = returnType;
+            this.arity         = arity;
+            this.canSpecialize = canSpecialize;
+        }
+
+        /**
+         * Can this request type be specialized?
+         *
+         * @return true if request can be specialized
+         */
+        public boolean canSpecialize() {
+            return canSpecialize;
+        }
+
+        /**
+         * Get arity
+         *
+         * @return the arity of the request
+         */
+        public int getArity() {
+            return arity;
+        }
+
+        /**
+         * Get the return type
+         *
+         * @return return type for request
+         */
+        public Type getReturnType() {
+            return returnType;
+        }
+
+        /**
+         * Get token type
+         *
+         * @return token type for request
+         */
+        public TokenType getTokenType() {
+            return tokenType;
+        }
+
+        /**
+         * Get the non-strict name for this request.
+         *
+         * @return the name without _STRICT suffix
+         */
+        public String nonStrictName() {
+            switch(this) {
+            case NE_STRICT:
+                return NE.name();
+            case EQ_STRICT:
+                return EQ.name();
+            default:
+                return name();
+            }
+        }
+
+        /**
+         * Is this an EQ or EQ_STRICT?
+         *
+         * @param request a request
+         *
+         * @return true if EQ or EQ_STRICT
+         */
+        public static boolean isEQ(final Request request) {
+            return request == EQ || request == EQ_STRICT;
+        }
+
+        /**
+         * Is this an NE or NE_STRICT?
+         *
+         * @param request a request
+         *
+         * @return true if NE or NE_STRICT
+         */
+        public static boolean isNE(final Request request) {
+            return request == NE || request == NE_STRICT;
+        }
+
+        /**
+         * If this request can be reversed, return the reverse request
+         * Eq EQ {@literal ->} NE.
+         *
+         * @param request request to reverse
+         *
+         * @return reversed request or null if not applicable
+         */
+        public static Request reverse(final Request request) {
+            switch (request) {
+            case EQ:
+            case EQ_STRICT:
+            case NE:
+            case NE_STRICT:
+                return request;
+            case LE:
+                return GE;
+            case LT:
+                return GT;
+            case GE:
+                return LE;
+            case GT:
+                return LT;
+            default:
+                return null;
+            }
+        }
+
+        /**
+         * Invert the request, only for non equals comparisons.
+         *
+         * @param request a request
+         *
+         * @return the inverted rquest, or null if not applicable
+         */
+        public static Request invert(final Request request) {
+            switch (request) {
+            case EQ:
+                return NE;
+            case EQ_STRICT:
+                return NE_STRICT;
+            case NE:
+                return EQ;
+            case NE_STRICT:
+                return EQ_STRICT;
+            case LE:
+                return GT;
+            case LT:
+                return GE;
+            case GE:
+                return LT;
+            case GT:
+                return LE;
+            default:
+                return null;
+            }
+        }
+
+        /**
+         * Check if this is a comparison
+         *
+         * @param request a request
+         *
+         * @return true if this is a comparison, null otherwise
+         */
+        public static boolean isComparison(final Request request) {
+            switch (request) {
+            case EQ:
+            case EQ_STRICT:
+            case NE:
+            case NE_STRICT:
+            case LE:
+            case LT:
+            case GE:
+            case GT:
+                return true;
+            default:
+                return false;
+            }
+        }
+    }
+
+    /** Runtime request. */
+    private final Request request;
+
+    /** Call arguments. */
+    private final List<Node> args;
+
+    /** Call site override - e.g. we know that a ScriptRuntime.ADD will return an int */
+    private Type callSiteType;
+
+    /** is final - i.e. may not be removed again, lower in the code pipeline */
+    private boolean isFinal;
+
+    /**
+     * Constructor
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param request the request
+     * @param args    arguments to request
+     */
+    public RuntimeNode(final Source source, final long token, final int finish, final Request request, final List<Node> args) {
+        super(source, token, finish);
+
+        this.request      = request;
+        this.args         = args;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param request the request
+     * @param args    arguments to request
+     */
+    public RuntimeNode(final Source source, final long token, final int finish, final Request request, final Node... args) {
+        this(source, token, finish, request, Arrays.asList(args));
+    }
+
+    /**
+     * Constructor
+     *
+     * @param parent  parent node from which to inherit source, token, finish
+     * @param request the request
+     * @param args    arguments to request
+     */
+    public RuntimeNode(final Node parent, final Request request, final Node... args) {
+        this(parent, request, Arrays.asList(args));
+    }
+
+    /**
+     * Constructor
+     *
+     * @param parent  parent node from which to inherit source, token, finish
+     * @param request the request
+     * @param args    arguments to request
+     */
+    public RuntimeNode(final Node parent, final Request request, final List<Node> args) {
+        super(parent);
+
+        this.request = request;
+        this.args    = args;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param parent  parent node from which to inherit source, token, finish and arguments
+     * @param request the request
+     */
+    public RuntimeNode(final UnaryNode parent, final Request request) {
+        this(parent, request, parent.rhs());
+    }
+
+    /**
+     * Constructor
+     *
+     * @param parent  parent node from which to inherit source, token, finish and arguments
+     * @param request the request
+     */
+    public RuntimeNode(final BinaryNode parent, final Request request) {
+        this(parent, request, parent.lhs(), parent.rhs());
+    }
+
+    private RuntimeNode(final RuntimeNode runtimeNode, final CopyState cs) {
+        super(runtimeNode);
+
+        final List<Node> newArgs = new ArrayList<>();
+
+        for (final Node arg : runtimeNode.args) {
+            newArgs.add(cs.existingOrCopy(arg));
+        }
+
+        this.request      = runtimeNode.request;
+        this.args         = newArgs;
+        this.callSiteType = runtimeNode.callSiteType;
+    }
+
+    /**
+     * Is this node final - i.e. it can never be replaced with other nodes again
+     * @return true if final
+     */
+    public boolean isFinal() {
+        return isFinal;
+    }
+
+    /**
+     * Flag this node as final - i.e it may never be replaced with other nodes again
+     */
+    public void setIsFinal() {
+        this.isFinal = true;
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new RuntimeNode(this, cs);
+    }
+
+    /**
+     * Return type for the ReferenceNode
+     */
+    @Override
+    public Type getType() {
+        return hasCallSiteType() ? callSiteType : request.getReturnType();
+    }
+
+    @Override
+    public void setType(final Type type) {
+        this.callSiteType = type;
+    }
+
+    @Override
+    public boolean canHaveCallSiteType() {
+        return request == Request.ADD;
+    }
+
+    private boolean hasCallSiteType() {
+        return callSiteType != null;
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            for (int i = 0, count = args.size(); i < count; i++) {
+                args.set(i, args.get(i).accept(visitor));
+            }
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("ScriptRuntime.");
+        sb.append(request);
+        sb.append('(');
+
+        boolean first = true;
+
+        for (final Node arg : args) {
+            if (!first) {
+                sb.append(", ");
+            } else {
+                first = false;
+            }
+
+            arg.toString(sb);
+        }
+
+        sb.append(')');
+    }
+
+    /**
+     * Get the arguments for this runtime node
+     * @return argument list
+     */
+    public List<Node> getArgs() {
+        return Collections.unmodifiableList(args);
+    }
+
+    /**
+     * Get the request that this runtime node implements
+     * @return the request
+     */
+    public Request getRequest() {
+        return request;
+    }
+
+    /**
+     * Is this runtime node, engineered to handle the "at least one object" case of the defined
+     * requests and specialize on demand, really primitive. This can happen e.g. after AccessSpecializer
+     * In that case it can be turned into a simpler primitive form in CodeGenerator
+     *
+     * @return true if all arguments now are primitive
+     */
+    public boolean isPrimitive() {
+        for (final Node arg : args) {
+            if (arg.getType().isObject()) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java b/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java
new file mode 100644
index 0000000..c09a4f0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java
@@ -0,0 +1,227 @@
+/*
+ * 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.ir;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import jdk.nashorn.internal.codegen.CompileUnit;
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.codegen.MethodEmitter;
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.annotations.Reference;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+
+/**
+ * Node indicating code is split across classes.
+ */
+public class SplitNode extends Node {
+    /** Split node method name. */
+    private final String name;
+
+    /** Compilation unit. */
+    private CompileUnit compileUnit;
+
+    /** Method emitter for current method. */
+    private MethodEmitter method;
+
+    /** Method emitter for caller method. */
+    private MethodEmitter caller;
+
+    /** Containing function. */
+    @Reference
+    private final FunctionNode functionNode;
+
+    /** A list of target labels in parent methods this split node may encounter. */
+    @Ignore
+    private final List<Label> externalTargets;
+
+    /** True if this split node or any of its children contain a return statement. */
+    private boolean hasReturn;
+
+    /** Body of split code. */
+    @Ignore
+    private Node body;
+
+    /**
+     * Constructor
+     *
+     * @param name          name of split node
+     * @param functionNode  function node to split in
+     * @param body          body of split code
+     */
+    public SplitNode(final String name, final FunctionNode functionNode, final Node body) {
+        super(body.getSource(), body.getToken(), body.getFinish());
+
+        this.name         = name;
+        this.functionNode = functionNode;
+        this.body         = body;
+        this.externalTargets = new ArrayList<>();
+    }
+
+    private SplitNode(final SplitNode splitNode, final CopyState cs) {
+        super(splitNode);
+
+        this.name         = splitNode.name;
+        this.functionNode = (FunctionNode)cs.existingOrSame(splitNode.functionNode);
+        this.body         = cs.existingOrCopy(splitNode.body);
+        this.externalTargets = new ArrayList<>();
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new SplitNode(this, cs);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        final CompileUnit   saveCompileUnit = visitor.getCurrentCompileUnit();
+        final MethodEmitter saveMethod      = visitor.getCurrentMethodEmitter();
+
+        setCaller(saveMethod);
+
+        visitor.setCurrentCompileUnit(getCompileUnit());
+        visitor.setCurrentMethodEmitter(getMethodEmitter());
+
+        try {
+            if (visitor.enter(this) != null) {
+                body = body.accept(visitor);
+
+                return visitor.leave(this);
+            }
+        } finally {
+            visitor.setCurrentCompileUnit(saveCompileUnit);
+            visitor.setCurrentMethodEmitter(saveMethod);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("<split>(");
+        sb.append(compileUnit.getClass().getSimpleName());
+        sb.append(") ");
+        body.toString(sb);
+    }
+
+    /**
+     * Get the method emitter of the caller for this split node
+     * @return caller method emitter
+     */
+    public MethodEmitter getCaller() {
+        return caller;
+    }
+
+    /**
+     * Set the caller method emitter for this split node
+     * @param caller method emitter
+     */
+    public void setCaller(final MethodEmitter caller) {
+        this.caller = caller;
+    }
+
+    /**
+     * Get the name for this split node
+     * @return name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the compile unit for this split node
+     * @return compile unit
+     */
+    public CompileUnit getCompileUnit() {
+        return compileUnit;
+    }
+
+    /**
+     * Set the compile unit for this split node
+     * @param compileUnit compile unit
+     */
+    public void setCompileUnit(final CompileUnit compileUnit) {
+        this.compileUnit = compileUnit;
+    }
+
+    /**
+     * Get the method emitter for this split node
+     * @return method emitter
+     */
+    public MethodEmitter getMethodEmitter() {
+        return method;
+    }
+
+    /**
+     * Set the method emitter for this split node
+     * @param method method emitter
+     */
+    public void setMethodEmitter(final MethodEmitter method) {
+        this.method = method;
+    }
+
+    /**
+     * Get the function node this SplitNode splits
+     * @return function node reference
+     */
+    public FunctionNode getFunctionNode() {
+        return functionNode;
+    }
+
+    /**
+     * Get the external targets for this SplitNode
+     * @return list of external targets
+     */
+    public List<Label> getExternalTargets() {
+        return Collections.unmodifiableList(externalTargets);
+    }
+
+    /**
+     * Add an external target for this SplitNode
+     * @param targetLabel target label
+     */
+    public void addExternalTarget(final Label targetLabel) {
+        externalTargets.add(targetLabel);
+    }
+
+    /**
+     * Check whether this SplitNode returns a value
+     * @return true if return
+     */
+    public boolean hasReturn() {
+        return hasReturn;
+    }
+
+    /**
+     * Set whether this SplitNode returns a value or not
+     * @param hasReturn true if return exists, false otherwise
+     */
+    public void setHasReturn(final boolean hasReturn) {
+        this.hasReturn = hasReturn;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java b/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java
new file mode 100644
index 0000000..068398e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java
@@ -0,0 +1,176 @@
+/*
+ * 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.ir;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation of a SWITCH statement.
+ */
+public class SwitchNode extends BreakableNode {
+    /** Switch expression. */
+    private Node expression;
+
+    /** Tag symbol. */
+    private Symbol tag;
+
+    /** Switch cases. */
+    private List<CaseNode> cases;
+
+    /** Switch default. */
+    @Ignore //points to one of the members in the list above, don't traverse twice
+    private CaseNode defaultCase;
+
+    /**
+     * Constructor
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     */
+    public SwitchNode(final Source source, final long token, final int finish) {
+        super(source, token, finish);
+        this.breakLabel  = new Label("switch_break");
+    }
+
+    private SwitchNode(final SwitchNode switchNode, final CopyState cs) {
+        super(switchNode);
+
+        final List<CaseNode> newCases = new ArrayList<>();
+
+        for (final CaseNode caseNode : switchNode.getCases()) {
+           newCases.add((CaseNode)cs.existingOrCopy(caseNode));
+        }
+
+        this.expression  = cs.existingOrCopy(switchNode.getExpression());
+        this.tag         = switchNode.getTag();
+        this.cases       = newCases;
+        this.defaultCase = (CaseNode)cs.existingOrCopy(switchNode.getDefaultCase());
+        this.breakLabel  = new Label(switchNode.getBreakLabel());
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new SwitchNode(this, cs);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            expression = expression.accept(visitor);
+
+            for (int i = 0, count = cases.size(); i < count; i++) {
+                cases.set(i, (CaseNode)cases.get(i).accept(visitor));
+            }
+
+            //the default case is in the cases list and should not be explicitly traversed!
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("switch (");
+        expression.toString(sb);
+        sb.append(')');
+    }
+
+    /**
+     * Get the cases in this switch
+     * @return a list of case nodes
+     */
+    public List<CaseNode> getCases() {
+        return Collections.unmodifiableList(cases);
+    }
+
+    /**
+     * Set or reset the list of cases in this switch
+     * @param cases a list of cases, case nodes
+     */
+    public void setCases(final List<CaseNode> cases) {
+        this.cases = cases;
+    }
+
+    /**
+     * Get the default case for this switch
+     * @return default case node
+     */
+    public CaseNode getDefaultCase() {
+        return defaultCase;
+    }
+
+    /**
+     * Set the default case for this switch
+     * @param defaultCase default case node
+     */
+    public void setDefaultCase(final CaseNode defaultCase) {
+        this.defaultCase = defaultCase;
+    }
+
+    /**
+     * Return the expression to switch on
+     * @return switch expression
+     */
+    public Node getExpression() {
+        return expression;
+    }
+
+    /**
+     * Set or reset the expression to switch on
+     * @param expression switch expression
+     */
+    public void setExpression(final Node expression) {
+        this.expression = expression;
+    }
+
+    /**
+     * Get the tag symbol for this switch. The tag symbol is where
+     * the switch expression result is stored
+     * @return tag symbol
+     */
+    public Symbol getTag() {
+        return tag;
+    }
+
+    /**
+     * Set the tag symbol for this switch. The tag symbol is where
+     * the switch expression result is stored
+     * @param tag a symbol
+     */
+    public void setTag(final Symbol tag) {
+        this.tag = tag;
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
new file mode 100644
index 0000000..a58a7c1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
@@ -0,0 +1,666 @@
+/*
+ * 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.ir;
+
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Maps a name to specific data.
+ */
+
+public final class Symbol implements Comparable<Symbol> {
+    /** Symbol flags. Kind ordered by precedence. */
+    public static final int IS_TEMP     = 0b0000_0001;
+    /** Is this Global */
+    public static final int IS_GLOBAL   = 0b0000_0010;
+    /** Is this a variable */
+    public static final int IS_VAR      = 0b0000_0011;
+    /** Is this a parameter */
+    public static final int IS_PARAM    = 0b0000_0100;
+    /** Is this a constant */
+    public static final int IS_CONSTANT = 0b0000_0101;
+
+    static final int KINDMASK = 0b0000_1111;
+
+    /** Is this scope */
+    public static final int IS_SCOPE         = 0b0000_0001_0000;
+    /** Is this a this symbol */
+    public static final int IS_THIS          = 0b0000_0010_0000;
+    /** Can this symbol ever be undefined */
+    public static final int CAN_BE_UNDEFINED = 0b0000_0100_0000;
+    /** Can this symbol ever have primitive types */
+    public static final int CAN_BE_PRIMITIVE = 0b0000_1000_0000;
+    /** Is this a let */
+    public static final int IS_LET           = 0b0001_0000_0000;
+    /** Is this an internal symbol, never represented explicitly in source code */
+    public static final int IS_INTERNAL      = 0b0010_0000_0000;
+
+    /** Null or name identifying symbol. */
+    private final String name;
+
+    /** Symbol flags. */
+    private int flags;
+
+    /** Defining node. */
+    private Node node;
+
+    /** Definition block. */
+    private final Block block;
+
+    /** Type of symbol. */
+    private Type type;
+
+    /** Local variable slot. -1 indicates external property. */
+    private int slot;
+
+    /** Field number in scope or property; array index in varargs when not using arguments object. */
+    private int fieldIndex;
+
+    /** Number of times this symbol is used in code */
+    private int useCount;
+
+    /** Debugging option - dump info and stack trace when symbols with given names are manipulated */
+    private static final Set<String> TRACE_SYMBOLS;
+    private static final Set<String> TRACE_SYMBOLS_STACKTRACE;
+
+    static {
+        final String stacktrace = Options.getStringProperty("nashorn.compiler.symbol.stacktrace", null);
+        final String trace;
+        if (stacktrace != null) {
+            trace = stacktrace; //stacktrace always implies trace as well
+            TRACE_SYMBOLS_STACKTRACE = new HashSet<>();
+            for (StringTokenizer st = new StringTokenizer(stacktrace, ","); st.hasMoreTokens(); ) {
+                TRACE_SYMBOLS_STACKTRACE.add(st.nextToken());
+            }
+        } else {
+            trace = Options.getStringProperty("nashorn.compiler.symbol.trace", null);
+            TRACE_SYMBOLS_STACKTRACE = null;
+        }
+
+        if (trace != null) {
+            TRACE_SYMBOLS = new HashSet<>();
+            for (StringTokenizer st = new StringTokenizer(trace, ","); st.hasMoreTokens(); ) {
+                TRACE_SYMBOLS.add(st.nextToken());
+            }
+        } else {
+            TRACE_SYMBOLS = null;
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param name  name of symbol
+     * @param flags symbol flags
+     * @param node  node this symbol is in
+     * @param block block this symbol is in
+     * @param type  type of this symbol
+     * @param slot  bytecode slot for this symbol
+     */
+    protected Symbol(final String name, final int flags, final Node node, final Block block, final Type type, final int slot) {
+        this.name       = name;
+        this.flags      = flags;
+        this.node       = node;
+        this.block      = block;
+        this.type       = type;
+        this.slot       = slot;
+        this.fieldIndex = -1;
+        trace("CREATE SYMBOL");
+    }
+
+    /**
+     * Constructor
+     *
+     * @param name  name of symbol
+     * @param flags symbol flags
+     * @param node  node this symbol is in
+     * @param block block this symbol is in
+     */
+    public Symbol(final String name, final int flags, final Node node, final Block block) {
+        this(name, flags, node, block, Type.UNKNOWN, -1);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param name  name of symbol
+     * @param flags symbol flags
+     * @param type  type of this symbol
+     */
+    public Symbol(final String name, final int flags, final Type type) {
+        this(name, flags, null, null, type, -1);
+    }
+
+    private static String align(final String string, final int max) {
+        final StringBuilder sb = new StringBuilder();
+        sb.append(string.substring(0, Math.min(string.length(), max)));
+
+        while (sb.length() < max) {
+            sb.append(' ');
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Return the type for this symbol. Normally, if there is no type override,
+     * this is where any type for any node is stored. If the node has a TypeOverride,
+     * it may override this, e.g. when asking for a scoped field as a double
+     *
+     * @return symbol type
+     */
+    public final Type getSymbolType() {
+        return type;
+    }
+
+    /**
+     * Debugging .
+     *
+     * @param stream Stream to print to.
+     */
+
+    void print(final PrintWriter stream) {
+        final String printName = align(name, 20);
+        final String printType = align(type.toString(), 10);
+        final String printSlot = align(slot == -1 ? "none" : "" + slot, 10);
+        String printFlags = "";
+
+        switch (flags & KINDMASK) {
+        case IS_TEMP:
+            printFlags = "temp " + printFlags;
+            break;
+        case IS_GLOBAL:
+            printFlags = "global " + printFlags;
+            break;
+        case IS_VAR:
+            printFlags = "var " + printFlags;
+            break;
+        case IS_PARAM:
+            printFlags = "param " + printFlags;
+            break;
+        case IS_CONSTANT:
+            printFlags = "CONSTANT " + printFlags;
+            break;
+        default:
+            break;
+        }
+
+        if (isScope()) {
+            printFlags += "scope ";
+        }
+
+        if (isInternal()) {
+            printFlags += "internal ";
+        }
+
+        if (isLet()) {
+            printFlags += "let ";
+        }
+
+        if (isThis()) {
+            printFlags += "this ";
+        }
+
+        if (!canBeUndefined()) {
+            printFlags += "always_def ";
+        }
+
+        if (canBePrimitive()) {
+            printFlags += "can_be_prim ";
+        }
+
+        stream.print(printName + ": " + printType + ", " + printSlot + ", " + printFlags);
+        stream.println();
+    }
+
+    /**
+     * Compare the the symbol kind with another.
+     *
+     * @param other Other symbol's flags.
+     * @return True if symbol has less kind.
+     */
+    public boolean less(final int other) {
+        return (flags & KINDMASK) < (other & KINDMASK);
+    }
+
+    /**
+     * Allocate a slot for this symbol.
+     *
+     * @param needsSlot True if symbol needs a slot.
+     */
+    public void setNeedsSlot(final boolean needsSlot) {
+        setSlot(needsSlot ? 0 : -1);
+    }
+
+    /**
+     * Return the number of slots required for the symbol.
+     *
+     * @return Number of slots.
+     */
+    public int slotCount() {
+        return type.isCategory2() ? 2 : 1;
+    }
+
+    /**
+     * Return the defining function (scope.)
+     *
+     * @return Defining function.
+     */
+    public FunctionNode findFunction() {
+        return block != null ? block.getFunction() : null;
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!(other instanceof Symbol)) {
+            return false;
+        }
+        final Symbol symbol = (Symbol) other;
+        return name.equals(symbol.name) && block.equals(symbol.block);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode() ^ block.hashCode();
+    }
+
+    private static String type(final String desc) {
+        switch (desc.charAt(desc.length() - 1)) {
+        case ';':
+            return desc;//"obj";
+        case 'D':
+            return "double";
+        case 'I':
+            return "int";
+        case 'J':
+            return "long";
+        case 'Z':
+            return "boolean";
+        default:
+            return "UNKNOWN";
+        }
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb   = new StringBuilder();
+        final String        desc = getSymbolType().getDescriptor();
+
+        sb.append(name).
+            append(' ').
+            append('(').
+            append(type(desc)).
+            append(')');
+
+        if (hasSlot()) {
+            sb.append(' ').
+                append('(').
+                append("slot=").
+                append(slot).
+                append(')');
+        }
+
+        if (isScope()) {
+            if(isGlobal()) {
+                sb.append(" G");
+            } else {
+                sb.append(" S");
+            }
+        }
+
+        if (canBePrimitive()) {
+            sb.append(" P?");
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public int compareTo(final Symbol other) {
+        return name.compareTo(other.name);
+    }
+
+    /**
+     * Does this symbol have an allocated bytecode slot. If not, it is scope
+     * and must be loaded from memory upon access
+     *
+     * @return true if this symbol has a local bytecode slot
+     */
+    public boolean hasSlot() {
+        return slot >= 0;
+    }
+
+    /**
+     * Check if this is a temporary symbol
+     * @return true if temporary
+     */
+    public boolean isTemp() {
+        return (flags & KINDMASK) == IS_TEMP;
+    }
+
+    /**
+     * Check if this is a symbol in scope. Scope symbols cannot, for obvious reasons
+     * be stored in byte code slots on the local frame
+     *
+     * @return true if this is scoped
+     */
+    public boolean isScope() {
+        assert ((flags & KINDMASK) != IS_GLOBAL) || ((flags & IS_SCOPE) == IS_SCOPE) : "global without scope flag";
+        return (flags & IS_SCOPE) == IS_SCOPE;
+    }
+
+    /**
+     * Flag this symbol as scope as described in {@link Symbol#isScope()}
+     */
+    public void setIsScope() {
+        if (!isScope()) {
+            trace("SET IS SCOPE");
+        }
+        flags |= IS_SCOPE;
+        if(!isGlobal()) {
+            getBlock().setNeedsScope();
+        }
+    }
+
+    /**
+     * Check if this symbol is a variable
+     * @return true if variable
+     */
+    public boolean isVar() {
+        return (flags & KINDMASK) == IS_VAR;
+    }
+
+    /**
+     * Check if this symbol is a global (undeclared) variable
+     * @return true if global
+     */
+    public boolean isGlobal() {
+        return (flags & KINDMASK) == IS_GLOBAL;
+    }
+
+    /**
+     * Check if this symbol is a function parameter
+     * @return true if parameter
+     */
+    public boolean isParam() {
+        return (flags & KINDMASK) == IS_PARAM;
+    }
+
+    /**
+     * Check whether this symbol ever has primitive assignments. Conservative
+     * @return true if primitive assignments exist
+     */
+    public boolean canBePrimitive() {
+        return (flags & CAN_BE_PRIMITIVE) == CAN_BE_PRIMITIVE;
+    }
+
+    /**
+     * Check if this symbol can ever be undefined
+     * @return true if can be undefined
+     */
+    public boolean canBeUndefined() {
+        return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED;
+    }
+
+    /**
+     * Flag this symbol as potentially undefined in parts of the program
+     */
+    public void setCanBeUndefined() {
+        assert type.isObject() : type;
+        flags |= CAN_BE_UNDEFINED;
+    }
+
+    /**
+     * Flag this symbol as potentially primitive
+     * @param type the primitive type it occurs with, currently unused but can be used for width guesses
+     */
+    public void setCanBePrimitive(final Type type) {
+        flags |= CAN_BE_PRIMITIVE;
+    }
+
+    /**
+     * Check if this symbol is a constant
+     * @return true if a constant
+     */
+    public boolean isConstant() {
+        return (flags & KINDMASK) == IS_CONSTANT;
+    }
+
+    /**
+     * Check if this is an internal symbol, without an explicit JavaScript source
+     * code equivalent
+     * @return true if internal
+     */
+    public boolean isInternal() {
+        return (flags & IS_INTERNAL) != 0;
+    }
+
+    /**
+     * Check if this symbol represents {@code this}
+     * @return true if this
+     */
+    public boolean isThis() {
+        return (flags & IS_THIS) != 0;
+    }
+
+    /**
+     * Check if this symbol is a let
+     * @return true if let
+     */
+    public boolean isLet() {
+        return (flags & IS_LET) == IS_LET;
+    }
+
+    /**
+     * Flag this symbol as a let
+     */
+    public void setIsLet() {
+        flags |= IS_LET;
+    }
+
+    /**
+     * Check if this symbol can be accessed directly with a putfield or getfield or dynamic load
+     *
+     * @param currentFunction function to check for fast scope
+     * @return true if fast scope
+     */
+    public boolean isFastScope(final FunctionNode currentFunction) {
+        if (!isScope() || !block.needsScope()) {
+            return false;
+        }
+        // Allow fast scope access if no parent function contains with or eval
+        FunctionNode func = currentFunction;
+        while (func != null) {
+            if (func.hasWith() || func.hasEval()) {
+                return false;
+            }
+            func = func.findParentFunction();
+        }
+        return true;
+    }
+
+    /**
+     * Get the block in which the symbol is defined
+     * @return a block
+     */
+    public Block getBlock() {
+        return block;
+    }
+
+    /**
+     * Get the index of the field used to store this symbol, should it be an AccessorProperty
+     * and get allocated in a JO-prefixed ScriptObject subclass.
+     *
+     * @return field index
+     */
+    public int getFieldIndex() {
+        assert fieldIndex != -1 : "fieldIndex must be initialized";
+        return fieldIndex;
+    }
+
+    /**
+     * Set the index of the field used to store this symbol, should it be an AccessorProperty
+     * and get allocated in a JO-prefixed ScriptObject subclass.
+     *
+     * @param fieldIndex field index - a positive integer
+     */
+    public void setFieldIndex(final int fieldIndex) {
+        assert this.fieldIndex == -1 : "fieldIndex must be initialized only once";
+        this.fieldIndex = fieldIndex;
+    }
+
+    /**
+     * Get the symbol flags
+     * @return flags
+     */
+    public int getFlags() {
+        return flags;
+    }
+
+    /**
+     * Set the symbol flags
+     * @param flags flags
+     */
+    public void setFlags(final int flags) {
+        this.flags = flags;
+    }
+
+    /**
+     * Get the node this symbol stores the result for
+     * @return node
+     */
+    public Node getNode() {
+        return node;
+    }
+
+    /**
+     * Set the node this symbol stores the result for
+     * @param node node
+     */
+    public void setNode(final Node node) {
+        this.node = node;
+    }
+
+    /**
+     * Get the name of this symbol
+     * @return symbol name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the byte code slot for this symbol
+     * @return byte code slot, or -1 if no slot allocated/possible
+     */
+    public int getSlot() {
+        return slot;
+    }
+
+    /**
+     * Increase the symbol's use count by one.
+     */
+    public void increaseUseCount() {
+        useCount++;
+    }
+
+    /**
+     * Get the symbol's use count
+     * @return the number of times the symbol is used in code.
+     */
+    public int getUseCount() {
+        return useCount;
+    }
+
+    /**
+     * Set the bytecode slot for this symbol
+     * @param slot valid bytecode slot, or -1 if not available
+     */
+    public void setSlot(final int slot) {
+        if (slot != this.slot) {
+            trace("SET SLOT " + slot);
+            this.slot = slot;
+        }
+    }
+
+    /**
+     * Assign a specific subclass of Object to the symbol
+     *
+     * @param type  the type
+     */
+    public void setType(final Class<?> type) {
+        assert !type.isPrimitive() && !Number.class.isAssignableFrom(type) : "Class<?> types can only be subclasses of object";
+        setType(Type.typeFor(type));
+    }
+
+    /**
+     * Assign a type to the symbol
+     *
+     * @param type the type
+     */
+    public void setType(final Type type) {
+        setTypeOverride(Type.widest(this.type, type));
+    }
+
+    /**
+     * Only use this if you know about an existing type
+     * constraint - otherwise a type can only be
+     * widened
+     *
+     * @param type  the type
+     */
+    public void setTypeOverride(final Type type) {
+        final Type old = this.type;
+        if (old != type) {
+            trace("TYPE CHANGE: " + old + "=>" + type + " == " + type);
+            this.type = type;
+        }
+    }
+
+    /**
+     * Check if this symbol is in the global scope, i.e. it is on the outermost level
+     * in the script
+     * @return true if this this is a global scope symbol
+     */
+    public boolean isTopLevel() {
+        return block instanceof FunctionNode && ((FunctionNode) block).isScript();
+    }
+
+
+    private void trace(final String desc) {
+        if (TRACE_SYMBOLS != null && (TRACE_SYMBOLS.isEmpty() || TRACE_SYMBOLS.contains(name))) {
+            Context.err("SYMBOL: '" + name + "' " + desc);
+            if (TRACE_SYMBOLS_STACKTRACE != null && (TRACE_SYMBOLS_STACKTRACE.isEmpty() || TRACE_SYMBOLS_STACKTRACE.contains(name))) {
+                new Throwable().printStackTrace(Context.getCurrentErr());
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java
new file mode 100644
index 0000000..a82991f
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java
@@ -0,0 +1,140 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * TernaryNode nodes represent three operand operations (?:).
+ */
+public class TernaryNode extends BinaryNode {
+    /** Third argument. */
+    private Node third;
+
+    /**
+     * Constructor
+     *
+     * @param source the source
+     * @param token  token
+     * @param lhs    left hand side node
+     * @param rhs    right hand side node
+     * @param third  third node
+     */
+    public TernaryNode(final Source source, final long token, final Node lhs, final Node rhs, final Node third) {
+        super(source, token, lhs, rhs);
+
+        this.finish = third.getFinish();
+        this.third = third;
+    }
+
+    private TernaryNode(final TernaryNode ternaryNode, final CopyState cs) {
+        super(ternaryNode, cs);
+
+        this.third = cs.existingOrCopy(ternaryNode.third);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new TernaryNode(this, cs);
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!super.equals(other)) {
+            return false;
+        }
+        return third.equals(((TernaryNode)other).third());
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ third().hashCode();
+    }
+
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            lhs = lhs.accept(visitor);
+            rhs = rhs.accept(visitor);
+            third = third.accept(visitor);
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        final boolean lhsParen   = tokenType().needsParens(lhs().tokenType(), true);
+        final boolean rhsParen   = tokenType().needsParens(rhs().tokenType(), false);
+        final boolean thirdParen = tokenType().needsParens(third().tokenType(), false);
+
+        if (lhsParen) {
+            sb.append('(');
+        }
+        lhs().toString(sb);
+        if (lhsParen) {
+            sb.append(')');
+        }
+
+        sb.append(" ? ");
+
+        if (rhsParen) {
+            sb.append('(');
+        }
+        rhs().toString(sb);
+        if (rhsParen) {
+            sb.append(')');
+        }
+
+        sb.append(" : ");
+
+        if (thirdParen) {
+            sb.append('(');
+        }
+        third().toString(sb);
+        if (thirdParen) {
+            sb.append(')');
+        }
+    }
+
+    /**
+     * Get the "third" node for this ternary expression, i.e. "z" in x ? y : z
+     * @return a node
+     */
+    public Node third() {
+        return third;
+    }
+
+    /**
+     * Reset the "third" node for this ternary expression, i.e. "z" in x ? y : z
+     * @param third a node
+     */
+    public void setThird(final Node third) {
+        this.third = third;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java b/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java
new file mode 100644
index 0000000..efa63d9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java
@@ -0,0 +1,118 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for THROW statements.
+ */
+public class ThrowNode extends Node {
+    /** Exception expression. */
+    private Node expression;
+
+    /** Try chain. */
+    @Ignore
+    private final TryNode tryChain;
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param finish     finish
+     * @param expression expression to throw
+     * @param tryChain   surrounding try chain
+     */
+    public ThrowNode(final Source source, final long token, final int finish, final Node expression, final TryNode tryChain) {
+        super(source, token, finish);
+
+        this.expression = expression;
+        this.tryChain = tryChain;
+        setIsTerminal(true);
+    }
+
+    private ThrowNode(final ThrowNode throwNode, final CopyState cs) {
+        super(throwNode);
+
+        this.expression = cs.existingOrCopy(throwNode.expression);
+        this.tryChain = (TryNode)cs.existingOrSame(throwNode.tryChain);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new ThrowNode(this, cs);
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            setExpression(expression.accept(visitor));
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("throw ");
+
+        if (expression != null) {
+            expression.toString(sb);
+        }
+    }
+
+    /**
+     * Get the expression that is being thrown by this node
+     * @return expression
+     */
+    public Node getExpression() {
+        return expression;
+    }
+
+    /**
+     * Reset the expression being thrown by this node
+     * @param expression new expression
+     */
+    public void setExpression(final Node expression) {
+        this.expression = expression;
+    }
+
+    /**
+     * Get surrounding tryChain for this node
+     * @return try chain
+     */
+    public TryNode getTryChain() {
+        return tryChain;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/TryNode.java b/nashorn/src/jdk/nashorn/internal/ir/TryNode.java
new file mode 100644
index 0000000..b6aa439
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/TryNode.java
@@ -0,0 +1,253 @@
+/*
+ * 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.ir;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation of a TRY statement.
+ */
+public class TryNode extends Node {
+    /** Try chain. */
+    @Ignore //don't print, will be apparent from the AST
+    private TryNode next;
+
+    /** Try statements. */
+    private Block body;
+
+    /** List of catch clauses. */
+    private List<Block> catchBlocks;
+
+    /** Finally clause. */
+    private Block finallyBody;
+
+    /** Exit label. */
+    private Label exit;
+
+    /** Exception symbol. */
+    private Symbol exception;
+
+    /** Catchall exception for finally expansion, where applicable */
+    private Symbol finallyCatchAll;
+
+    /**
+     * Constructor
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     * @param next    next try node in chain
+     */
+    public TryNode(final Source source, final long token, final int finish, final TryNode next) {
+        super(source, token, finish);
+
+        this.next = next;
+        this.exit = new Label("exit");
+    }
+
+    private TryNode(final TryNode tryNode, final CopyState cs) {
+        super(tryNode);
+
+        final List<Block> newCatchBlocks = new ArrayList<>();
+
+        for (final Block block : tryNode.catchBlocks) {
+            newCatchBlocks.add((Block)cs.existingOrCopy(block));
+        }
+
+        this.next        = (TryNode)cs.existingOrSame(tryNode.getNext());
+        this.body        = (Block)cs.existingOrCopy(tryNode.getBody());
+        this.catchBlocks = newCatchBlocks;
+        this.finallyBody = (Block)cs.existingOrCopy(tryNode.getFinallyBody());
+        this.exit        = new Label(tryNode.getExit());
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new TryNode(this, cs);
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            // Need to do first for termination analysis.
+            if (finallyBody != null) {
+                finallyBody = (Block)finallyBody.accept(visitor);
+            }
+
+            body = (Block)body.accept(visitor);
+
+            final List<Block> newCatchBlocks = new ArrayList<>(catchBlocks.size());
+            for (final Block catchBlock : catchBlocks) {
+                newCatchBlocks.add((Block)catchBlock.accept(visitor));
+            }
+            this.catchBlocks = newCatchBlocks;
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("try");
+    }
+
+    /**
+     * Get the body for this try block
+     * @return body
+     */
+    public Block getBody() {
+        return body;
+    }
+
+    /**
+     * Reset the body of this try block
+     * @param body new body
+     */
+    public void setBody(final Block body) {
+        this.body = body;
+    }
+
+    /**
+     * Get the catches for this try block
+     * @return a list of catch nodes
+     */
+    public List<CatchNode> getCatches() {
+        final List<CatchNode> catches = new ArrayList<>(catchBlocks.size());
+        for (final Block catchBlock : catchBlocks) {
+            catches.add((CatchNode)catchBlock.getStatements().get(0));
+        }
+        return catches;
+    }
+
+    /**
+     * Get the catch blocks for this try block
+     * @return a list of blocks
+     */
+    public List<Block> getCatchBlocks() {
+        return Collections.unmodifiableList(catchBlocks);
+    }
+
+    /**
+     * Set the catch blocks of this try
+     * @param catchBlocks list of catch blocks
+     */
+    public void setCatchBlocks(final List<Block> catchBlocks) {
+        this.catchBlocks = catchBlocks;
+    }
+
+    /**
+     * Get the exception symbol for this try block
+     * @return a symbol for the compiler to store the exception in
+     */
+    public Symbol getException() {
+        return exception;
+    }
+
+    /**
+     * Set the exception symbol for this try block
+     * @param exception a symbol for the compiler to store the exception in
+     */
+    public void setException(final Symbol exception) {
+        this.exception = exception;
+    }
+
+    /**
+     * Get the catch all symbol for this try block
+     * @return catch all symbol
+     */
+    public Symbol getFinallyCatchAll() {
+        return this.finallyCatchAll;
+    }
+
+    /**
+     * If a finally block exists, the synthetic catchall needs another symbol to
+     * store its throwable
+     * @param finallyCatchAll a symbol for the finally catch all exception
+     */
+    public void setFinallyCatchAll(final Symbol finallyCatchAll) {
+        this.finallyCatchAll = finallyCatchAll;
+    }
+
+    /**
+     * Get the exit label for this try block
+     * @return exit label
+     */
+    public Label getExit() {
+        return exit;
+    }
+
+    /**
+     * Set the exit label for this try block
+     * @param exit label
+     */
+    public void setExit(final Label exit) {
+        this.exit = exit;
+    }
+
+    /**
+     * Get the body of the finally clause for this try
+     * @return finally body, or null if no finally
+     */
+    public Block getFinallyBody() {
+        return finallyBody;
+    }
+
+    /**
+     * Set the finally body of this try
+     * @param finallyBody new finally body
+     */
+    public void setFinallyBody(final Block finallyBody) {
+        this.finallyBody = finallyBody;
+    }
+
+    /**
+     * Get next try node in try chain
+     * @return next try node
+     */
+    public TryNode getNext() {
+        return next;
+    }
+
+    /**
+     * Set next try node in try chain
+     * @param next next try node
+     */
+    public void setNext(final TryNode next) {
+        this.next = next;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java b/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java
new file mode 100644
index 0000000..8321318
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java
@@ -0,0 +1,58 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.codegen.types.Type;
+
+/**
+ * A type override makes it possible to change the return type of a node, if we know
+ * that the linker can provide it directly. For example, an identity node that is
+ * in the scope, can very well look like an object to the compiler of the method it
+ * is in, but if someone does (int)x, it make senses to ask for it directly
+ * with an int getter instead of loading it as an object and explicitly converting it
+ * by using JSType.toInt32. Especially in scenarios where the field is already stored
+ * as a primitive, this will be much faster than the "object is all I see" scope
+ * available in the method
+ */
+
+public interface TypeOverride {
+    /**
+     * Set the override type
+     *
+     * @param type  the type
+     */
+    public void setType(final Type type);
+
+    /**
+     * Returns true if this node can have a callsite override, e.g. all scope ident nodes
+     * which lead to dynamic getters can have it, local variable nodes (slots) can't.
+     * Call nodes can have it unconditionally and so on
+     *
+     * @return true if it is possible to assign a type override to this node
+     */
+    public boolean canHaveCallSiteType();
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java
new file mode 100644
index 0000000..7b608ed
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java
@@ -0,0 +1,223 @@
+/*
+ * 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.ir;
+
+import static jdk.nashorn.internal.parser.TokenType.BIT_NOT;
+import static jdk.nashorn.internal.parser.TokenType.CONVERT;
+import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
+import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
+
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * UnaryNode nodes represent single operand operations.
+ */
+public class UnaryNode extends Node implements Assignment<Node> {
+    /** Right hand side argument. */
+    protected Node rhs;
+
+    /**
+     * Constructor
+     *
+     * @param source the source
+     * @param token  token
+     * @param rhs    expression
+     */
+    public UnaryNode(final Source source, final long token, final Node rhs) {
+        super(source, token, Token.descPosition(token));
+
+        this.start  = Math.min(rhs.getStart(), Token.descPosition(token));
+        this.finish = Math.max(Token.descPosition(token) + Token.descLength(token), rhs.getFinish());
+        this.rhs    = rhs;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param unaryNode source node
+     * @param cs        copy state
+     */
+    protected UnaryNode(final UnaryNode unaryNode, final CopyState cs) {
+        super(unaryNode);
+
+        this.rhs = cs.existingOrCopy(unaryNode.rhs);
+    }
+
+    /**
+     * Is this an assignment - i.e. that mutates something such as a++
+     *
+     * @return true if assignment
+     */
+    @Override
+    public boolean isAssignment() {
+        switch (tokenType()) {
+        case DECPOSTFIX:
+        case DECPREFIX:
+        case INCPOSTFIX:
+        case INCPREFIX:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    @Override
+    public boolean isSelfModifying() {
+        return isAssignment();
+    }
+
+    @Override
+    public Type getWidestOperationType() {
+        return isAssignment() ? Type.NUMBER : Type.OBJECT;
+    }
+
+    @Override
+    public Node getAssignmentDest() {
+        return isAssignment() ? rhs() : null;
+    }
+
+    @Override
+    public Node getAssignmentSource() {
+        return getAssignmentDest();
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!super.equals(other)) {
+            return false;
+        }
+        return rhs.equals(((UnaryNode)other).rhs());
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ rhs().hashCode();
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new UnaryNode(this, cs);
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            rhs = rhs.accept(visitor);
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        final TokenType type      = tokenType();
+        final String    name      = type.getName();
+        final boolean   isPostfix = type == DECPOSTFIX || type == INCPOSTFIX;
+        final boolean   isConvert = type == CONVERT && getSymbol() != null;
+
+        boolean rhsParen   = type.needsParens(rhs().tokenType(), false);
+        int     convertPos = 0;
+
+        if (isConvert) {
+            convertPos = sb.length();
+            sb.append("((");
+            sb.append(getType());
+            sb.append(")");
+        }
+
+        if (!isPostfix && !isConvert) {
+            if (name == null) {
+                sb.append(type.name());
+                rhsParen = true;
+            } else {
+                sb.append(name);
+
+                if (type.ordinal() > BIT_NOT.ordinal()) {
+                    sb.append(' ');
+                }
+            }
+        }
+
+        if (rhsParen) {
+            sb.append('(');
+        }
+        rhs().toString(sb);
+        if (rhsParen) {
+            sb.append(')');
+        }
+
+        if (isPostfix) {
+            sb.append(type == DECPOSTFIX ? "--" : "++");
+        }
+
+        if (isConvert) {
+            // strip extra cast parenthesis which makes the printout harder to read
+            final boolean endsWithParenthesis = sb.charAt(sb.length() - 1) == ')';
+            if (!endsWithParenthesis) {
+                sb.append(')');
+            } else {
+                sb.setCharAt(convertPos, ' ');
+            }
+        }
+
+        //TODO - conversions still have too many parenthesis - makes --print-lower-parse hard to read
+    }
+
+    /**
+     * Get the right hand side of this if it is inherited by a binary expression,
+     * or just the expression itself if still Unary
+     *
+     * @see BinaryNode
+     *
+     * @return right hand side or expression node
+     */
+    public Node rhs() {
+        return rhs;
+    }
+
+    /**
+     * Reset the right hand side of this if it is inherited by a binary expression,
+     * or just the expression itself if still Unary
+     *
+     * @see BinaryNode
+     *
+     * @param rhs right hand side or expression node
+     */
+    public void setRHS(final Node rhs) {
+        this.rhs = rhs;
+    }
+
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/VarNode.java b/nashorn/src/jdk/nashorn/internal/ir/VarNode.java
new file mode 100644
index 0000000..07b6f8e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/VarNode.java
@@ -0,0 +1,208 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * Node represents a var/let declaration.
+ */
+public class VarNode extends Node implements Assignment<IdentNode> {
+    /** Var name. */
+    private IdentNode name;
+
+    /** Initialization expression. */
+    private Node init;
+
+    /** Is this a function var node */
+    private boolean isFunctionVarNode;
+
+    /**
+     * Constructor
+     *
+     * @param source the source
+     * @param token  token
+     * @param finish finish
+     * @param name   name of variable
+     * @param init   init node or null if just a declaration
+     */
+    public VarNode(final Source source, final long token, final int finish, final IdentNode name, final Node init) {
+        super(source, token, finish);
+
+        this.name  = name;
+        this.init  = init;
+        if (init != null) {
+            this.name.setIsInitializedHere();
+        }
+    }
+
+    private VarNode(final VarNode varNode, final CopyState cs) {
+        super(varNode);
+
+        this.name = (IdentNode)cs.existingOrCopy(varNode.name);
+        this.init = cs.existingOrCopy(varNode.init);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new VarNode(this, cs);
+    }
+
+    @Override
+    public boolean isAssignment() {
+        return hasInit();
+    }
+
+    @Override
+    public IdentNode getAssignmentDest() {
+        return isAssignment() ? name : null;
+    }
+
+    @Override
+    public Node getAssignmentSource() {
+        return isAssignment() ? getInit() : null;
+    }
+
+    /**
+     * Does this variable declaration have an init value
+     * @return true if an init exists, false otherwise
+     */
+    public boolean hasInit() {
+        return init != null;
+    }
+
+    /**
+     * Test to see if two VarNodes are the same.
+     * @param other Other VarNode.
+     * @return True if the VarNodes are the same.
+     */
+    @Override
+    public boolean equals(final Object other) {
+        if (other instanceof VarNode) {
+            final VarNode otherNode    = (VarNode)other;
+            final boolean nameMatches  = name.equals(otherNode.name);
+            if (hasInit() != otherNode.hasInit()) {
+                return false;
+            } else if (init == null) {
+                return nameMatches;
+            } else {
+                return nameMatches && init.equals(otherNode.init);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode() ^ (init == null ? 0 : init.hashCode());
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            name = (IdentNode)name.accept(visitor);
+
+            if (init != null) {
+                init = init.accept(visitor);
+            }
+
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("var ");
+        name.toString(sb);
+
+        if (init != null) {
+            sb.append(" = ");
+            init.toString(sb);
+        }
+    }
+
+    /**
+     * If this is an assignment of the form {@code var x = init;}, get the init part.
+     * @return the expression to initialize the variable to, null if just a declaration
+     */
+    public Node getInit() {
+        return init;
+    }
+
+    /**
+     * Reset the initialization expression
+     * @param init new initialization expression
+     */
+    public void setInit(final Node init) {
+        this.init = init;
+    }
+
+    /**
+     * Get the identifier for the variable
+     * @return IdentNode representing the variable being set or declared
+     */
+    public IdentNode getName() {
+        return name;
+    }
+
+    /**
+     * Reset the identifier for this VarNode
+     * @param name new IdentNode representing the variable being set or declared
+     */
+    public void setName(final IdentNode name) {
+        this.name = name;
+    }
+
+    /**
+     * Check if this is a virtual assignment of a function node. Function nodes declared
+     * with a name are hoisted to the top of the scope and appear as symbols too. This is
+     * implemented by representing them as virtual VarNode assignments added to the code
+     * during lowering
+     *
+     * @see FunctionNode
+     *
+     * @return true if this is a virtual function declaration
+     */
+    public boolean isFunctionVarNode() {
+        return isFunctionVarNode;
+    }
+
+    /**
+     * Flag this var node as a virtual function var node assignment as described in
+     * {@link VarNode#isFunctionVarNode()}
+     */
+    public void setIsFunctionVarNode() {
+        this.isFunctionVarNode = true;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java
new file mode 100644
index 0000000..c51659b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java
@@ -0,0 +1,162 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.codegen.Label;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for a WHILE statement. This is the superclass of all
+ * loop nodes
+ */
+public class WhileNode extends BreakableNode {
+    /** Test expression. */
+    protected Node test;
+
+    /** For body. */
+    protected Block body;
+
+    /** loop continue label. */
+    protected Label continueLabel;
+
+    /**
+     * Constructor
+     *
+     * @param source  the source
+     * @param token   token
+     * @param finish  finish
+     */
+    public WhileNode(final Source source, final long token, final int finish) {
+        super(source, token, finish);
+
+        this.breakLabel    = new Label("while_break");
+        this.continueLabel = new Label("while_continue");
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param whileNode source node
+     * @param cs        copy state
+     */
+    protected WhileNode(final WhileNode whileNode, final CopyState cs) {
+        super(whileNode);
+
+        this.test          = cs.existingOrCopy(whileNode.test);
+        this.body          = (Block)cs.existingOrCopy(whileNode.body);
+        this.breakLabel    = new Label(whileNode.breakLabel);
+        this.continueLabel = new Label(whileNode.continueLabel);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new WhileNode(this, cs);
+    }
+
+    @Override
+    public boolean isLoop() {
+        return true;
+    }
+
+    /**
+     * Assist in IR navigation.
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            test = test.accept(visitor);
+            body = (Block)body.accept(visitor);
+
+            return visitor.leave(this);
+        }
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("while (");
+        test.toString(sb);
+        sb.append(')');
+    }
+
+    /**
+     * Get the loop body
+     * @return body
+     */
+    public Block getBody() {
+        return body;
+    }
+
+    /**
+     * Reset the loop body
+     * @param body new body
+     */
+    public void setBody(final Block body) {
+        this.body = body;
+    }
+
+    /**
+     * Set the break label (described in {@link WhileNode#getBreakLabel()} for this while node
+     * @param breakLabel break label
+     */
+    public void setBreakLabel(final Label breakLabel) {
+        this.breakLabel = breakLabel;
+    }
+
+    /**
+     * Get the continue label for this while node, i.e. location to go to on continue
+     * @return continue label
+     */
+    public Label getContinueLabel() {
+        return continueLabel;
+    }
+
+    /**
+     * Set the continue label (described in {@link WhileNode#getContinueLabel()} for this while node
+     * @param continueLabel continue label
+     */
+    public void setContinueLabel(final Label continueLabel) {
+        this.continueLabel = continueLabel;
+    }
+
+    /**
+     * Get the test expression for this loop, that upon evaluation to true does another iteration
+     * @return test expression
+     */
+    public Node getTest() {
+        return test;
+    }
+
+    /**
+     * Set the test expression for this loop
+     * @param test test expression, null if infinite loop
+     */
+    public void setTest(final Node test) {
+        this.test = test;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/WithNode.java b/nashorn/src/jdk/nashorn/internal/ir/WithNode.java
new file mode 100644
index 0000000..52f4e9b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/WithNode.java
@@ -0,0 +1,124 @@
+/*
+ * 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.ir;
+
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * IR representation for {@code with} statements.
+ */
+public class WithNode extends Node {
+   /** This expression. */
+    private Node expression;
+
+    /** Statements. */
+    private Block body;
+
+    /**
+     * Constructor
+     *
+     * @param source     the source
+     * @param token      token
+     * @param finish     finish
+     * @param expression expression in parenthesis
+     * @param body       with node body
+     */
+    public WithNode(final Source source, final long token, final int finish, final Node expression, final Block body) {
+        super(source, token, finish);
+
+        this.expression = expression;
+        this.body       = body;
+    }
+
+    private WithNode(final WithNode withNode, final CopyState cs) {
+        super(withNode);
+
+        this.expression = cs.existingOrCopy(withNode.expression);
+        this.body       = (Block)cs.existingOrCopy(withNode.body);
+    }
+
+    @Override
+    protected Node copy(final CopyState cs) {
+        return new WithNode(this, cs);
+    }
+
+    /**
+     * Assist in IR navigation.
+     *
+     * @param visitor IR navigating visitor.
+     */
+    @Override
+    public Node accept(final NodeVisitor visitor) {
+        if (visitor.enter(this) != null) {
+            expression = expression.accept(visitor);
+            body = (Block)body.accept(visitor);
+            return visitor.leave(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb) {
+        sb.append("with (");
+        expression.toString(sb);
+        sb.append(')');
+    }
+
+    /**
+     * Get the body of this WithNode
+     * @return the body
+     */
+    public Block getBody() {
+        return body;
+    }
+
+    /**
+     * Reset the body of this with node
+     * @param body new body
+     */
+    public void setBody(final Block body) {
+        this.body = body;
+    }
+
+    /**
+     * Get the expression of this WithNode
+     * @return the expression
+     */
+    public Node getExpression() {
+        return expression;
+    }
+
+    /**
+     * Reset the expression of this with node
+     * @param expression new expression
+     */
+    public void setExpression(final Node expression) {
+        this.expression = expression;
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/ir/annotations/ChildNode.java b/nashorn/src/jdk/nashorn/internal/ir/annotations/ChildNode.java
new file mode 100644
index 0000000..181c63d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/annotations/ChildNode.java
@@ -0,0 +1,42 @@
+/*
+ * 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.ir.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This is a child node, a real node, not a reference, to an IR node that should
+ * be traversed.
+ * <p>
+ * TODO Currently not in use.  Would make e.g. accept methods simple and unified
+ * @see jdk.nashorn.internal.ir.Node
+ */
+@Retention(value=RetentionPolicy.RUNTIME)
+public @interface ChildNode {
+    /** order of traversal compared to other children */
+    public int order() default -1;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/annotations/Ignore.java b/nashorn/src/jdk/nashorn/internal/ir/annotations/Ignore.java
new file mode 100644
index 0000000..171eacc
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/annotations/Ignore.java
@@ -0,0 +1,43 @@
+/*
+ * 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.ir.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import jdk.nashorn.internal.ir.debug.ASTWriter;
+
+/**
+ * This signifies a node that should be ignored in traversal, for example
+ * a reference to an already traversed node, or various metadata that
+ * has no actual IR representations, but yet reside in the node.
+ *
+ * @see ASTWriter
+ * @see jdk.nashorn.internal.ir.Node
+ */
+@Retention(value=RetentionPolicy.RUNTIME)
+public @interface Ignore {
+    // Empty
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/annotations/ParentNode.java b/nashorn/src/jdk/nashorn/internal/ir/annotations/ParentNode.java
new file mode 100644
index 0000000..6a9de3a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/annotations/ParentNode.java
@@ -0,0 +1,44 @@
+/*
+ * 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.ir.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Signifies a parent of a node, i.e. node that should not be traversed if we
+ * go down the AST. In automatic parsing this can be handled by @Reference
+ * annotations instead, as all parents are references.
+ * <p>
+ * TODO The use case is automating and creating one implementation of something like
+ * Node.getParent()
+ *
+ * @see jdk.nashorn.internal.ir.Node
+ */
+@Retention(value=RetentionPolicy.RUNTIME)
+public @interface ParentNode {
+    // EMPTY
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java b/nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java
new file mode 100644
index 0000000..1dd002c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java
@@ -0,0 +1,42 @@
+/*
+ * 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.ir.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Reference node in AST, i.e. anything not a copy. Important for
+ * AST traversal and cloning. Cloning currently as a rule uses
+ * existingOrSame for references and otherwise existingOrCopy
+ * <p>
+ * TODO this could probably be automated using the @Reference annotation.
+ */
+
+@Retention(value=RetentionPolicy.RUNTIME)
+public @interface Reference {
+    // EMPTY
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java
new file mode 100644
index 0000000..3c66aa1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java
@@ -0,0 +1,249 @@
+/*
+ * 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.ir.debug;
+
+import java.lang.reflect.Field;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.TernaryNode;
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import jdk.nashorn.internal.ir.annotations.ParentNode;
+import jdk.nashorn.internal.ir.annotations.Reference;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.runtime.Context;
+
+/**
+ * AST-as-text visualizer. Sometimes you want tree form and not source
+ * code. This works for both lowered and unlowered IR
+ *
+ * see the flags --print-ast and --print-ast-lower
+ */
+
+public final class ASTWriter {
+    /** Root node from which to start the traversal */
+    private final Node root;
+
+    private static final int TABWIDTH = 4;
+
+    /**
+     * Constructor
+     * @param root root of the AST to visualize
+     */
+    public ASTWriter(final Node root) {
+        this.root = root;
+    }
+
+    /**
+     * Use the ASTWriter by instantiating it and retrieving its String
+     * representation
+     *
+     * @return the string representation of the AST
+     */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        printAST(sb, null, "root", root, 0);
+        return sb.toString();
+    }
+
+    @SuppressWarnings("unchecked")
+    private void printAST(final StringBuilder sb, final Field field, final String name, final Node node, final int indent) {
+        ASTWriter.indent(sb, indent);
+        if (node == null) {
+            sb.append("[Object ");
+            sb.append(name);
+            sb.append(" null]\n");
+            return;
+        }
+
+        final boolean isReference = field != null && field.getAnnotation(Reference.class) != null;
+
+        Class<?> clazz = node.getClass();
+        String   type  = clazz.getName();
+
+        type = type.substring(type.lastIndexOf('.') + 1, type.length());
+//        type += "@" + Debug.id(node) + "#" + node.getSymbol();
+
+        final List<Field> children = new LinkedList<>();
+
+        if (!isReference) {
+            enqueueChildren(node, clazz, children);
+        }
+
+        String status = "";
+
+        if (node.shouldDiscard()) {
+            status += " Discard";
+        }
+
+        if (node.isTerminal()) {
+            status += " Terminal";
+        }
+
+        if (node.hasGoto()) {
+            status += " Goto ";
+        }
+
+        if (node.getSymbol() != null) {
+            status += node.getSymbol();
+        }
+
+        status = status.trim();
+        if (!"".equals(status)) {
+            status = " [" + status + "]";
+        }
+
+        if (node.getSymbol() != null) {
+            String tname = node.getType().toString();
+            if (tname.indexOf('.') != -1) {
+                tname = tname.substring(tname.lastIndexOf('.') + 1, tname.length());
+            }
+            status += " (" + tname + ")";
+        }
+
+        if (children.isEmpty()) {
+            sb.append("[").
+                append(type).
+                append(' ').
+                append(name).
+                append(" = '").
+                append(node).
+                append("'").
+                append(status).
+                append("] ").
+                append('\n');
+        } else {
+            sb.append("[").
+                append(type).
+                append(' ').
+                append(name).
+                append(' ').
+                append(Token.toString(node.getToken())).
+                append(status).
+                append("]").
+                append('\n');
+
+            for (final Field child : children) {
+                if (child.getAnnotation(ParentNode.class) != null) {
+                    continue;
+                } else if (child.getAnnotation(Ignore.class) != null) {
+                    continue;
+                }
+
+                Object value;
+                try {
+                    value = child.get(node);
+                } catch (final IllegalArgumentException | IllegalAccessException e) {
+                    Context.printStackTrace(e);
+                    return;
+                }
+
+                if (value instanceof Node) {
+                    printAST(sb, child, child.getName(), (Node)value, indent + 1);
+                } else if (value instanceof Collection) {
+                    int pos = 0;
+                    ASTWriter.indent(sb, indent + 1);
+                    sb.append("[Collection ").
+                        append(child.getName()).
+                        append("[0..").
+                        append(((Collection<Node>)value).size()).
+                        append("]]").
+                        append('\n');
+
+                    for (final Node member : (Collection<Node>)value) {
+                        printAST(sb, child, child.getName() + "[" + pos++ + "]", member, indent + 2);
+                    }
+                }
+            }
+        }
+    }
+
+    private static void enqueueChildren(final Node node, final Class<?> nodeClass, final List<Field> children) {
+        final Deque<Class<?>> stack = new ArrayDeque<>();
+
+        /**
+         * Here is some ugliness that can be overcome by proper ChildNode annotations
+         * with proper orders. Right now we basically sort all classes up to Node
+         * with super class first, as this often is the natural order, e.g. base
+         * before index for an IndexNode.
+         *
+         * Also there are special cases as this is not true for UnaryNodes(lhs) and
+         * BinaryNodes extends UnaryNode (with lhs), and TernaryNodes.
+         *
+         * TODO - generalize traversal with an order built on annotations and this
+         * will go away.
+         */
+        Class<?> clazz = nodeClass;
+        do {
+            stack.push(clazz);
+            clazz = clazz.getSuperclass();
+        } while (clazz != null);
+
+        if (node instanceof TernaryNode) {
+            // HACK juggle "third"
+            stack.push(stack.removeLast());
+        }
+        // HACK change operator order for BinaryNodes to get lhs first.
+        final Iterator<Class<?>> iter = node instanceof BinaryNode ? stack.descendingIterator() : stack.iterator();
+
+        while (iter.hasNext()) {
+            final Class<?> c = iter.next();
+            for (final Field f : c.getDeclaredFields()) {
+                try {
+                    f.setAccessible(true);
+                    final Object child = f.get(node);
+                    if (child == null) {
+                        continue;
+                    }
+
+                    if (child instanceof Node) {
+                        children.add(f);
+                    } else if (child instanceof Collection) {
+                        if (!((Collection<?>)child).isEmpty()) {
+                            children.add(f);
+                        }
+                    }
+                } catch (final IllegalArgumentException | IllegalAccessException e) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void indent(final StringBuilder sb, final int indent) {
+        for (int i = 0; i < indent; i++) {
+            for (int j = 0; j < TABWIDTH; j++) {
+                sb.append(' ');
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
new file mode 100644
index 0000000..68fb68b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
@@ -0,0 +1,1020 @@
+/*
+ * 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.ir.debug;
+
+import java.util.Arrays;
+import java.util.List;
+import jdk.nashorn.internal.codegen.CompilerConstants;
+import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BreakNode;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.CaseNode;
+import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ContinueNode;
+import jdk.nashorn.internal.ir.DoWhileNode;
+import jdk.nashorn.internal.ir.EmptyNode;
+import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.IndexNode;
+import jdk.nashorn.internal.ir.LabelNode;
+import jdk.nashorn.internal.ir.LineNumberNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
+import jdk.nashorn.internal.ir.PropertyNode;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.TernaryNode;
+import jdk.nashorn.internal.ir.ThrowNode;
+import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.WhileNode;
+import jdk.nashorn.internal.ir.WithNode;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.JSONParser;
+import jdk.nashorn.internal.parser.Lexer.RegexToken;
+import jdk.nashorn.internal.parser.Parser;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * This IR writer produces a JSON string that represents AST as a JSON string.
+ */
+public final class JSONWriter extends NodeVisitor {
+    /**
+     * Returns AST as JSON compatible string.
+     *
+     * @param env  script environment to use
+     * @param code code to be parsed
+     * @param name name of the code source (used for location)
+     * @param includeLoc tells whether to include location information for nodes or not
+     * @return JSON string representation of AST of the supplied code
+     */
+    public static String parse(final ScriptEnvironment env, final String code, final String name, final boolean includeLoc) {
+        final Parser       parser     = new Parser(env, new Source(name, code), new Context.ThrowErrorManager(), env._strict);
+        final JSONWriter   jsonWriter = new JSONWriter(includeLoc);
+        try {
+            final FunctionNode functionNode = parser.parse(CompilerConstants.RUN_SCRIPT.tag());
+            functionNode.accept(jsonWriter);
+            return jsonWriter.getString();
+        } catch (final ParserException e) {
+            e.throwAsEcmaException();
+            return null;
+        }
+    }
+
+    @Override
+    protected Node enterDefault(final Node node) {
+        objectStart();
+        location(node);
+
+        return node;
+    }
+
+    @Override
+    protected Node leaveDefault(final Node node) {
+        objectEnd();
+        return null;
+    }
+
+    @Override
+    public Node enter(final AccessNode accessNode) {
+        enterDefault(accessNode);
+
+        type("MemberExpression");
+        comma();
+
+        property("object");
+        accessNode.getBase().accept(this);
+        comma();
+
+        property("property");
+        accessNode.getProperty().accept(this);
+        comma();
+
+        property("computed", false);
+
+        return leaveDefault(accessNode);
+    }
+
+    @Override
+    public Node enter(final Block block) {
+        enterDefault(block);
+
+        type("BlockStatement");
+        comma();
+
+        array("body", block.getStatements());
+
+        return leaveDefault(block);
+    }
+
+    private static boolean isLogical(final TokenType tt) {
+        switch (tt) {
+            case AND:
+            case OR:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public Node enter(final BinaryNode binaryNode) {
+        enterDefault(binaryNode);
+
+        final String name;
+        if (binaryNode.isAssignment()) {
+            name = "AssignmentExpression";
+        } else if (isLogical(binaryNode.tokenType())) {
+            name = "LogicalExpression";
+        } else {
+            name = "BinaryExpression";
+        }
+
+        type(name);
+        comma();
+
+        property("operator", binaryNode.tokenType().getName());
+        comma();
+
+        property("left");
+        binaryNode.lhs().accept(this);
+        comma();
+
+        property("right");
+        binaryNode.rhs().accept(this);
+
+        return leaveDefault(binaryNode);
+    }
+
+    @Override
+    public Node enter(final BreakNode breakNode) {
+        enterDefault(breakNode);
+
+        type("BreakStatement");
+        comma();
+
+        final LabelNode label = breakNode.getLabel();
+        if (label != null) {
+            property("label", label.getLabel().getName());
+        } else {
+            property("label");
+            nullValue();
+        }
+
+        return leaveDefault(breakNode);
+    }
+
+    @Override
+    public Node enter(final CallNode callNode) {
+        enterDefault(callNode);
+
+        type("CallExpression");
+        comma();
+
+        property("callee");
+        callNode.getFunction().accept(this);
+        comma();
+
+        array("arguments", callNode.getArgs());
+
+        return leaveDefault(callNode);
+    }
+
+    @Override
+    public Node enter(final CaseNode caseNode) {
+        enterDefault(caseNode);
+
+        type("SwitchCase");
+        comma();
+
+        final Node test = caseNode.getTest();
+        property("test");
+        if (test != null) {
+            test.accept(this);
+        } else {
+            nullValue();
+        }
+        comma();
+
+        array("consequent", caseNode.getBody().getStatements());
+
+        return leaveDefault(caseNode);
+    }
+
+    @Override
+    public Node enter(final CatchNode catchNode) {
+        enterDefault(catchNode);
+
+        type("CatchClause");
+        comma();
+
+        property("param");
+        catchNode.getException().accept(this);
+        comma();
+
+        final Node guard = catchNode.getExceptionCondition();
+        property("guard");
+        if (guard != null) {
+            guard.accept(this);
+        } else {
+            nullValue();
+        }
+        comma();
+
+        property("body");
+        catchNode.getBody().accept(this);
+
+        return leaveDefault(catchNode);
+    }
+
+    @Override
+    public Node enter(final ContinueNode continueNode) {
+        enterDefault(continueNode);
+
+        type("ContinueStatement");
+        comma();
+
+        final LabelNode label = continueNode.getLabel();
+        if (label != null) {
+            property("label", label.getLabel().getName());
+        } else {
+            property("label");
+            nullValue();
+        }
+
+        return leaveDefault(continueNode);
+    }
+
+    @Override
+    public Node enter(final DoWhileNode doWhileNode) {
+        enterDefault(doWhileNode);
+
+        type("DoWhileStatement");
+        comma();
+
+        property("body");
+        doWhileNode.getBody().accept(this);
+        comma();
+
+        property("test");
+        doWhileNode.getTest().accept(this);
+
+        return leaveDefault(doWhileNode);
+    }
+
+    @Override
+    public Node enter(final EmptyNode emptyNode) {
+        enterDefault(emptyNode);
+
+        type("EmptyStatement");
+
+        return leaveDefault(emptyNode);
+    }
+
+    @Override
+    public Node enter(final ExecuteNode executeNode) {
+        enterDefault(executeNode);
+
+        type("ExpressionStatement");
+        comma();
+
+        property("expression");
+        executeNode.getExpression().accept(this);
+
+        return leaveDefault(executeNode);
+    }
+
+    @Override
+    public Node enter(final ForNode forNode) {
+        enterDefault(forNode);
+
+        if (forNode.isForIn() || (forNode.isForEach() && forNode.getInit() != null)) {
+            type("ForInStatement");
+            comma();
+
+            Node init = forNode.getInit();
+            assert init != null;
+            property("left");
+            init.accept(this);
+            comma();
+
+            Node modify = forNode.getModify();
+            assert modify != null;
+            property("right");
+            modify.accept(this);
+            comma();
+
+            property("body");
+            forNode.getBody().accept(this);
+            comma();
+
+            property("each", forNode.isForEach());
+        } else {
+            type("ForStatement");
+            comma();
+
+            final Node init = forNode.getInit();
+            property("init");
+            if (init != null) {
+                init.accept(this);
+            } else {
+                nullValue();
+            }
+            comma();
+
+            final Node test = forNode.getTest();
+            property("test");
+            if (test != null) {
+                test.accept(this);
+            } else {
+                nullValue();
+            }
+            comma();
+
+            final Node update = forNode.getModify();
+            property("update");
+            if (update != null) {
+                update.accept(this);
+            } else {
+                nullValue();
+            }
+            comma();
+
+            property("body");
+            forNode.getBody().accept(this);
+        }
+
+        return leaveDefault(forNode);
+    }
+
+    @Override
+    public Node enter(final FunctionNode functionNode) {
+        enterDefault(functionNode);
+
+        final boolean program = functionNode.isScript();
+        final String name;
+        if (program) {
+            name = "Program";
+        } else if (functionNode.isStatement()) {
+            name = "FunctionDeclaration";
+        } else {
+            name = "FunctionExpression";
+        }
+        type(name);
+        comma();
+
+        if (! program) {
+            property("id");
+            if (functionNode.isAnonymous()) {
+                nullValue();
+            } else {
+                functionNode.getIdent().accept(this);
+            }
+            comma();
+        }
+
+        property("rest");
+        nullValue();
+        comma();
+
+        if (!program) {
+            array("params", functionNode.getParameters());
+            comma();
+        }
+
+        // body consists of nested functions and statements
+        final List<FunctionNode> funcs = functionNode.getFunctions();
+        final List<Node> stats = functionNode.getStatements();
+        final int size = stats.size() + funcs.size();
+        int idx = 0;
+        arrayStart("body");
+
+        for (final Node func : funcs) {
+            func.accept(this);
+            if (idx != (size - 1)) {
+                comma();
+            }
+            idx++;
+        }
+
+        for (final Node stat : stats) {
+            if (! stat.isDebug()) {
+                stat.accept(this);
+                if (idx != (size - 1)) {
+                    comma();
+                }
+            }
+            idx++;
+        }
+        arrayEnd();
+
+        return leaveDefault(functionNode);
+    }
+
+    @Override
+    public Node enter(final IdentNode identNode) {
+        enterDefault(identNode);
+
+        final String name = identNode.getName();
+        if ("this".equals(name)) {
+            type("ThisExpression");
+        } else {
+            type("Identifier");
+            comma();
+            property("name", identNode.getName());
+        }
+
+        return leaveDefault(identNode);
+    }
+
+    @Override
+    public Node enter(final IfNode ifNode) {
+        enterDefault(ifNode);
+
+        type("IfStatement");
+        comma();
+
+        property("test");
+        ifNode.getTest().accept(this);
+        comma();
+
+        property("consequent");
+        ifNode.getPass().accept(this);
+        final Node elsePart = ifNode.getFail();
+        comma();
+
+        property("alternate");
+        if (elsePart != null) {
+            elsePart.accept(this);
+        } else {
+            nullValue();
+        }
+
+        return leaveDefault(ifNode);
+    }
+
+    @Override
+    public Node enter(final IndexNode indexNode) {
+        enterDefault(indexNode);
+
+        type("MemberExpression");
+        comma();
+
+        property("object");
+        indexNode.getBase().accept(this);
+        comma();
+
+        property("property");
+        indexNode.getIndex().accept(this);
+        comma();
+
+        property("computed", true);
+
+        return leaveDefault(indexNode);
+    }
+
+    @Override
+    public Node enter(final LabelNode labelNode) {
+        enterDefault(labelNode);
+
+        type("LabeledStatement");
+        comma();
+
+        property("label");
+        labelNode.getLabel().accept(this);
+        comma();
+
+        property("body");
+        labelNode.getBody().accept(this);
+
+        return leaveDefault(labelNode);
+    }
+
+    @Override
+    public Node enter(final LineNumberNode lineNumberNode) {
+        return null;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Node enter(final LiteralNode literalNode) {
+        enterDefault(literalNode);
+
+        if (literalNode instanceof LiteralNode.ArrayLiteralNode) {
+            type("ArrayExpression");
+            comma();
+
+            final Node[] value = (Node[])literalNode.getValue();
+            array("elements", Arrays.asList(value));
+        } else {
+            type("Literal");
+            comma();
+
+            property("value");
+            final Object value = literalNode.getValue();
+            if (value instanceof RegexToken) {
+                // encode RegExp literals as Strings of the form /.../<flags>
+                final RegexToken regex = (RegexToken)value;
+                final StringBuilder regexBuf = new StringBuilder();
+                regexBuf.append('/');
+                regexBuf.append(regex.getExpression());
+                regexBuf.append('/');
+                regexBuf.append(regex.getOptions());
+                buf.append(quote(regexBuf.toString()));
+            } else {
+                final String str = literalNode.getString();
+                // encode every String literal with prefix '$' so that script
+                // can differentiate b/w RegExps as Strings and Strings.
+                buf.append(literalNode.isString()? quote("$" + str) : str);
+            }
+        }
+
+        return leaveDefault(literalNode);
+    }
+
+    @Override
+    public Node enter(final ObjectNode objectNode) {
+        enterDefault(objectNode);
+
+        type("ObjectExpression");
+        comma();
+
+        array("properties", objectNode.getElements());
+
+        return leaveDefault(objectNode);
+    }
+
+    @Override
+    public Node enter(final PropertyNode propertyNode) {
+        final Node key = propertyNode.getKey();
+
+        final Node value = propertyNode.getValue();
+        if (value != null) {
+            objectStart();
+            location(propertyNode);
+
+            property("key");
+            key.accept(this);
+            comma();
+
+            property("value");
+            value.accept(this);
+            comma();
+
+            property("kind", "init");
+
+            objectEnd();
+        } else {
+            // getter
+            final Node getter = propertyNode.getGetter();
+            if (getter != null) {
+                objectStart();
+                location(propertyNode);
+
+                property("key");
+                key.accept(this);
+                comma();
+
+                property("value");
+                getter.accept(this);
+                comma();
+
+                property("kind", "get");
+
+                objectEnd();
+            }
+
+            // setter
+            final Node setter = propertyNode.getSetter();
+            if (setter != null) {
+                if (getter != null) {
+                    comma();
+                }
+                objectStart();
+                location(propertyNode);
+
+                property("key");
+                key.accept(this);
+                comma();
+
+                property("value");
+                setter.accept(this);
+                comma();
+
+                property("kind", "set");
+
+                objectEnd();
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final ReturnNode returnNode) {
+        enterDefault(returnNode);
+
+        type("ReturnStatement");
+        comma();
+
+        final Node arg = returnNode.getExpression();
+        property("argument");
+        if (arg != null) {
+            arg.accept(this);
+        } else {
+            nullValue();
+        }
+
+        return leaveDefault(returnNode);
+    }
+
+    @Override
+    public Node enter(final RuntimeNode runtimeNode) {
+        final RuntimeNode.Request req = runtimeNode.getRequest();
+
+        if (req == RuntimeNode.Request.DEBUGGER) {
+            enterDefault(runtimeNode);
+
+            type("DebuggerStatement");
+
+            return leaveDefault(runtimeNode);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final SplitNode splitNode) {
+        return null;
+    }
+
+    @Override
+    public Node enter(final SwitchNode switchNode) {
+        enterDefault(switchNode);
+
+        type("SwitchStatement");
+        comma();
+
+        property("discriminant");
+        switchNode.getExpression().accept(this);
+        comma();
+
+        array("cases", switchNode.getCases());
+
+        return leaveDefault(switchNode);
+    }
+
+    @Override
+    public Node enter(final TernaryNode ternaryNode) {
+        enterDefault(ternaryNode);
+
+        type("ConditionalExpression");
+        comma();
+
+        property("test");
+        ternaryNode.lhs().accept(this);
+        comma();
+
+        property("consequent");
+        ternaryNode.rhs().accept(this);
+        comma();
+
+        property("alternate");
+        ternaryNode.third().accept(this);
+
+        return leaveDefault(ternaryNode);
+    }
+
+    @Override
+    public Node enter(final ThrowNode throwNode) {
+        enterDefault(throwNode);
+
+        type("ThrowStatement");
+        comma();
+
+        property("argument");
+        throwNode.getExpression().accept(this);
+
+        return leaveDefault(throwNode);
+    }
+
+    @Override
+    public Node enter(final TryNode tryNode) {
+        enterDefault(tryNode);
+
+        type("TryStatement");
+        comma();
+
+        property("block");
+        tryNode.getBody().accept(this);
+        comma();
+
+        array("handlers", tryNode.getCatches());
+        comma();
+
+        property("finalizer");
+        final Node finallyNode = tryNode.getFinallyBody();
+        if (finallyNode != null) {
+            finallyNode.accept(this);
+        } else {
+            nullValue();
+        }
+
+        return leaveDefault(tryNode);
+    }
+
+    @Override
+    public Node enter(final UnaryNode unaryNode) {
+        enterDefault(unaryNode);
+
+        final TokenType tokenType = unaryNode.tokenType();
+        if (tokenType == TokenType.NEW) {
+            type("NewExpression");
+            comma();
+
+            final CallNode callNode = (CallNode)unaryNode.rhs();
+            property("callee");
+            callNode.getFunction().accept(this);
+            comma();
+
+            array("arguments", callNode.getArgs());
+        } else {
+            final boolean prefix;
+            final String operator;
+            switch (tokenType) {
+                case INCPOSTFIX:
+                    prefix = false;
+                    operator = "++";
+                    break;
+                case DECPOSTFIX:
+                    prefix = false;
+                    operator = "--";
+                    break;
+                case INCPREFIX:
+                    operator = "++";
+                    prefix = true;
+                    break;
+                case DECPREFIX:
+                    operator = "--";
+                    prefix = true;
+                    break;
+                default:
+                    prefix = false;
+                    operator = tokenType.getName();
+            }
+
+            type(unaryNode.isAssignment()? "UpdateExpression" : "UnaryExpression");
+            comma();
+
+            property("operator", operator);
+            comma();
+
+            property("prefix", prefix);
+            comma();
+
+            property("argument");
+            unaryNode.rhs().accept(this);
+        }
+
+        return leaveDefault(unaryNode);
+    }
+
+    @Override
+    public Node enter(final VarNode varNode) {
+        enterDefault(varNode);
+
+        type("VariableDeclaration");
+        comma();
+
+        arrayStart("declarations");
+
+        // VariableDeclarator
+        objectStart();
+        location(varNode.getName());
+
+        type("VariableDeclarator");
+        comma();
+
+        property("id", varNode.getName().toString());
+        comma();
+
+        property("init");
+        final Node init = varNode.getInit();
+        if (init != null) {
+            init.accept(this);
+        } else {
+            nullValue();
+        }
+
+        // VariableDeclarator
+        objectEnd();
+
+        // declarations
+        arrayEnd();
+
+        return leaveDefault(varNode);
+    }
+
+    @Override
+    public Node enter(final WhileNode whileNode) {
+        enterDefault(whileNode);
+
+        type("WhileStatement");
+        comma();
+
+        property("test");
+        whileNode.getTest().accept(this);
+        comma();
+
+        property("block");
+        whileNode.getBody().accept(this);
+
+        return leaveDefault(whileNode);
+    }
+
+    @Override
+    public Node enter(final WithNode withNode) {
+        enterDefault(withNode);
+
+        type("WithStatement");
+        comma();
+
+        property("object");
+        withNode.getExpression().accept(this);
+        comma();
+
+        property("body");
+        withNode.getBody().accept(this);
+
+        return leaveDefault(withNode);
+    }
+
+    // Internals below
+
+    private JSONWriter(final boolean includeLocation) {
+        this.buf = new StringBuilder();
+        this.includeLocation = includeLocation;
+    }
+
+    private final StringBuilder buf;
+    private final boolean includeLocation;
+
+    private String getString() {
+        return buf.toString();
+    }
+
+    private void property(final String key, final String value) {
+        buf.append('"');
+        buf.append(key);
+        buf.append("\":");
+        if (value != null) {
+            buf.append('"');
+            buf.append(value);
+            buf.append('"');
+        }
+    }
+
+    private void property(final String key, final boolean value) {
+        property(key, Boolean.toString(value));
+    }
+
+    private void property(final String key, final int value) {
+        property(key, Integer.toString(value));
+    }
+
+    private void property(final String key) {
+        property(key, null);
+    }
+
+    private void type(final String value) {
+        property("type", value);
+    }
+
+    private void objectStart(final String name) {
+        buf.append('"');
+        buf.append(name);
+        buf.append("\":{");
+    }
+
+    private void objectStart() {
+        buf.append('{');
+    }
+
+    private void objectEnd() {
+        buf.append('}');
+    }
+
+    private void array(final String name, final List<? extends Node> nodes) {
+        // The size, idx comparison is just to avoid trailing comma..
+        final int size = nodes.size();
+        int idx = 0;
+        arrayStart(name);
+        for (final Node node : nodes) {
+            if (node == null || !node.isDebug()) {
+                if (node != null) {
+                    node.accept(this);
+                } else {
+                    nullValue();
+                }
+                if (idx != (size - 1)) {
+                    comma();
+                }
+            }
+            idx++;
+        }
+        arrayEnd();
+    }
+
+    private void arrayStart(final String name) {
+        buf.append('"');
+        buf.append(name);
+        buf.append('"');
+        buf.append(':');
+        buf.append('[');
+    }
+
+    private void arrayEnd() {
+        buf.append(']');
+    }
+
+    private void comma() {
+        buf.append(',');
+    }
+
+    private void nullValue() {
+        buf.append("null");
+    }
+
+    private void location(final Node node) {
+        if (includeLocation) {
+            objectStart("loc");
+
+            // source name
+            final Source src = node.getSource();
+            property("source", src.getName());
+            comma();
+
+            // start position
+            objectStart("start");
+            final int start = node.getStart();
+            property("line", src.getLine(start));
+            comma();
+            property("column", src.getColumn(start));
+            objectEnd();
+            comma();
+
+            // end position
+            objectStart("end");
+            final int end = node.getFinish();
+            property("line", src.getLine(end));
+            comma();
+            property("column", src.getColumn(end));
+            objectEnd();
+
+            // end 'loc'
+            objectEnd();
+
+            comma();
+        }
+    }
+
+    private static String quote(final String str) {
+        return JSONParser.quote(str);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java b/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java
new file mode 100644
index 0000000..11b8dbd
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java
@@ -0,0 +1,436 @@
+/*
+ * 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.ir.debug;
+
+import java.util.List;
+import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BreakNode;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.CaseNode;
+import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ContinueNode;
+import jdk.nashorn.internal.ir.DoWhileNode;
+import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.IndexNode;
+import jdk.nashorn.internal.ir.LabelNode;
+import jdk.nashorn.internal.ir.LineNumberNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ReferenceNode;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.ir.ThrowNode;
+import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.WhileNode;
+import jdk.nashorn.internal.ir.WithNode;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+/**
+ * Print out the AST as human readable source code.
+ * This works both on lowered and unlowered ASTs
+ *
+ * see the flags --print-parse and --print-lower-parse
+ */
+public final class PrintVisitor extends NodeVisitor {
+    /** Tab width */
+    private static final int TABWIDTH = 1;
+
+    /** Composing buffer. */
+    private final StringBuilder sb;
+
+    /** Indentation factor. */
+    private int indent;
+
+    /** Line separator. */
+    private final String EOLN;
+
+    /** Print line numbers */
+    private final boolean printLineNumbers;
+
+    /**
+     * Constructor.
+     */
+    public PrintVisitor() {
+        this(true);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param printLineNumbers  should line number nodes be included in the output?
+     */
+    public PrintVisitor(final boolean printLineNumbers) {
+        this.EOLN             = System.lineSeparator();
+        this.sb               = new StringBuilder();
+        this.printLineNumbers = printLineNumbers;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param root  a node from which to start printing code
+     */
+    public PrintVisitor(final Node root) {
+        this(root, true);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param root              a node from which to start printing code
+     * @param printLineNumbers  should line numbers nodes be included in the output?
+     */
+    public PrintVisitor(final Node root, final boolean printLineNumbers) {
+        this(printLineNumbers);
+        visit(root);
+    }
+
+    private void visit(final Node root) {
+        root.accept(this);
+    }
+
+    @Override
+    public String toString() {
+        return sb.append(EOLN).toString();
+    }
+
+    /**
+     * Insert spaces before a statement.
+     */
+    private void indent() {
+        for (int i = indent; i > 0; i--) {
+            sb.append(' ');
+        }
+    }
+
+    /*
+     * Visits.
+     */
+    @Override
+    public Node enter(final AccessNode accessNode) {
+        accessNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final Block block) {
+        sb.append(' ');
+        sb.append('{');
+
+        indent += TABWIDTH;
+
+        final boolean isFunction = block instanceof FunctionNode;
+
+        if (isFunction) {
+            final FunctionNode       function  = (FunctionNode)block;
+            final List<FunctionNode> functions = function.getFunctions();
+
+            for (final FunctionNode f : functions) {
+                sb.append(EOLN);
+                indent();
+                f.accept(this);
+            }
+
+            if (!functions.isEmpty()) {
+                sb.append(EOLN);
+            }
+        }
+
+        final List<Node> statements = block.getStatements();
+
+        boolean lastLineNumber = false;
+
+        for (final Node statement : statements) {
+            if (printLineNumbers || !lastLineNumber) {
+                sb.append(EOLN);
+                indent();
+            }
+
+            if (statement instanceof UnaryNode) {
+                statement.toString(sb);
+            } else {
+                statement.accept(this);
+            }
+
+            lastLineNumber = statement instanceof LineNumberNode;
+
+            final Symbol symbol = statement.getSymbol();
+
+            if (symbol != null) {
+                sb.append("  [");
+                sb.append(symbol.toString());
+                sb.append(']');
+            }
+
+            final char lastChar = sb.charAt(sb.length() - 1);
+
+            if (lastChar != '}' && lastChar != ';') {
+                if (printLineNumbers || !lastLineNumber) {
+                    sb.append(';');
+                }
+            }
+
+            if (statement.hasGoto()) {
+                sb.append(" [GOTO]");
+            }
+
+            if (statement.isTerminal()) {
+                sb.append(" [TERMINAL]");
+            }
+        }
+
+        indent -= TABWIDTH;
+
+        sb.append(EOLN);
+        indent();
+        sb.append("}");
+
+        if (isFunction) {
+            sb.append(EOLN);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final BreakNode breakNode) {
+        breakNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final CallNode callNode) {
+        callNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final ContinueNode continueNode) {
+        continueNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final DoWhileNode doWhileNode) {
+        sb.append("do");
+        doWhileNode.getBody().accept(this);
+        sb.append(' ');
+        doWhileNode.toString(sb);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final ExecuteNode executeNode) {
+        final Node expression = executeNode.getExpression();
+
+        if (expression instanceof UnaryNode) {
+            expression.toString(sb);
+        } else {
+            expression.accept(this);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final ForNode forNode) {
+        forNode.toString(sb);
+        forNode.getBody().accept(this);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final FunctionNode functionNode) {
+        functionNode.toString(sb);
+        enter((Block)functionNode);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final IfNode ifNode) {
+        ifNode.toString(sb);
+        ifNode.getPass().accept(this);
+
+        final Block fail = ifNode.getFail();
+
+        if (fail != null) {
+            sb.append(" else ");
+            fail.accept(this);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final IndexNode indexNode) {
+        indexNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final LabelNode labeledNode) {
+        indent -= TABWIDTH;
+        indent();
+        indent += TABWIDTH;
+        labeledNode.toString(sb);
+        labeledNode.getBody().accept(this);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final LineNumberNode lineNumberNode) {
+        if (printLineNumbers) {
+            lineNumberNode.toString(sb);
+        }
+
+        return null;
+    }
+
+
+    @Override
+    public Node enter(final ReferenceNode referenceNode) {
+        referenceNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final ReturnNode returnNode) {
+        returnNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final RuntimeNode runtimeNode) {
+        runtimeNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final SplitNode splitNode) {
+        splitNode.toString(sb);
+        sb.append(EOLN);
+        indent += TABWIDTH;
+        indent();
+        return splitNode;
+    }
+
+    @Override
+    public Node leave(final SplitNode splitNode) {
+        sb.append("</split>");
+        sb.append(EOLN);
+        indent -= TABWIDTH;
+        indent();
+        return splitNode;
+    }
+
+    @Override
+    public Node enter(final SwitchNode switchNode) {
+        switchNode.toString(sb);
+        sb.append(" {");
+
+        final List<CaseNode> cases = switchNode.getCases();
+
+        for (final CaseNode caseNode : cases) {
+            sb.append(EOLN);
+            indent();
+            caseNode.toString(sb);
+            indent += TABWIDTH;
+            caseNode.getBody().accept(this);
+            indent -= TABWIDTH;
+            sb.append(EOLN);
+        }
+
+        sb.append(EOLN);
+        indent();
+        sb.append("}");
+
+        return null;
+   }
+
+    @Override
+    public Node enter(final ThrowNode throwNode) {
+        throwNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final TryNode tryNode) {
+        tryNode.toString(sb);
+        tryNode.getBody().accept(this);
+
+        final List<Block> catchBlocks = tryNode.getCatchBlocks();
+
+        for (final Block catchBlock : catchBlocks) {
+            final CatchNode catchNode = (CatchNode) catchBlock.getStatements().get(0);
+            catchNode.toString(sb);
+            catchNode.getBody().accept(this);
+        }
+
+        final Block finallyBody = tryNode.getFinallyBody();
+
+        if (finallyBody != null) {
+            sb.append(" finally ");
+            finallyBody.accept(this);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final VarNode varNode) {
+        varNode.toString(sb);
+        return null;
+    }
+
+    @Override
+    public Node enter(final WhileNode whileNode) {
+        whileNode.toString(sb);
+        whileNode.getBody().accept(this);
+
+        return null;
+    }
+
+    @Override
+    public Node enter(final WithNode withNode) {
+        withNode.toString(sb);
+        withNode.getBody().accept(this);
+
+        return null;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java
new file mode 100644
index 0000000..6856282
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java
@@ -0,0 +1,1287 @@
+/*
+ * 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.ir.visitor;
+
+import jdk.nashorn.internal.codegen.CompileUnit;
+import jdk.nashorn.internal.codegen.MethodEmitter;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.UnaryNode;
+
+/**
+ * Like NodeVisitor but navigating further into operators.
+ */
+public class NodeOperatorVisitor extends NodeVisitor {
+    /**
+     * Constructor
+     */
+    public NodeOperatorVisitor() {
+        super();
+    }
+
+    /**
+     * Constructor
+     *
+     * @param compileUnit compile unit
+     * @param method      method emitter
+     */
+    public NodeOperatorVisitor(final CompileUnit compileUnit, final MethodEmitter method) {
+        super(compileUnit, method);
+    }
+
+    @Override
+    public final Node enter(final UnaryNode unaryNode) {
+        switch (unaryNode.tokenType()) {
+        case ADD:
+            return enterADD(unaryNode);
+        case BIT_NOT:
+            return enterBIT_NOT(unaryNode);
+        case CONVERT:
+            return enterCONVERT(unaryNode);
+        case DELETE:
+            return enterDELETE(unaryNode);
+        case DISCARD:
+            return enterDISCARD(unaryNode);
+        case NEW:
+            return enterNEW(unaryNode);
+        case NOT:
+            return enterNOT(unaryNode);
+        case SUB:
+            return enterSUB(unaryNode);
+        case TYPEOF:
+            return enterTYPEOF(unaryNode);
+        case VOID:
+            return enterVOID(unaryNode);
+        case DECPREFIX:
+        case DECPOSTFIX:
+        case INCPREFIX:
+        case INCPOSTFIX:
+            return enterDECINC(unaryNode);
+        default:
+            return super.enter(unaryNode);
+        }
+    }
+
+    @Override
+    public final Node leave(final UnaryNode unaryNode) {
+        switch (unaryNode.tokenType()) {
+        case ADD:
+            return leaveADD(unaryNode);
+        case BIT_NOT:
+            return leaveBIT_NOT(unaryNode);
+        case CONVERT:
+            return leaveCONVERT(unaryNode);
+        case DELETE:
+            return leaveDELETE(unaryNode);
+        case DISCARD:
+            return leaveDISCARD(unaryNode);
+        case NEW:
+            return leaveNEW(unaryNode);
+        case NOT:
+            return leaveNOT(unaryNode);
+        case SUB:
+            return leaveSUB(unaryNode);
+        case TYPEOF:
+            return leaveTYPEOF(unaryNode);
+        case VOID:
+            return leaveVOID(unaryNode);
+        case DECPREFIX:
+        case DECPOSTFIX:
+        case INCPREFIX:
+        case INCPOSTFIX:
+            return leaveDECINC(unaryNode);
+        default:
+            return super.leave(unaryNode);
+        }
+    }
+
+    @Override
+    public final Node enter(final BinaryNode binaryNode) {
+        switch (binaryNode.tokenType()) {
+        case ADD:
+            return enterADD(binaryNode);
+        case AND:
+            return enterAND(binaryNode);
+        case ASSIGN:
+            return enterASSIGN(binaryNode);
+        case ASSIGN_ADD:
+            return enterASSIGN_ADD(binaryNode);
+        case ASSIGN_BIT_AND:
+            return enterASSIGN_BIT_AND(binaryNode);
+        case ASSIGN_BIT_OR:
+            return enterASSIGN_BIT_OR(binaryNode);
+        case ASSIGN_BIT_XOR:
+            return enterASSIGN_BIT_XOR(binaryNode);
+        case ASSIGN_DIV:
+            return enterASSIGN_DIV(binaryNode);
+        case ASSIGN_MOD:
+            return enterASSIGN_MOD(binaryNode);
+        case ASSIGN_MUL:
+            return enterASSIGN_MUL(binaryNode);
+        case ASSIGN_SAR:
+            return enterASSIGN_SAR(binaryNode);
+        case ASSIGN_SHL:
+            return enterASSIGN_SHL(binaryNode);
+        case ASSIGN_SHR:
+            return enterASSIGN_SHR(binaryNode);
+        case ASSIGN_SUB:
+            return enterASSIGN_SUB(binaryNode);
+        case BIND:
+            return enterBIND(binaryNode);
+         case BIT_AND:
+            return enterBIT_AND(binaryNode);
+        case BIT_OR:
+            return enterBIT_OR(binaryNode);
+        case BIT_XOR:
+            return enterBIT_XOR(binaryNode);
+        case COMMARIGHT:
+            return enterCOMMARIGHT(binaryNode);
+        case COMMALEFT:
+            return enterCOMMALEFT(binaryNode);
+        case DIV:
+            return enterDIV(binaryNode);
+        case EQ:
+            return enterEQ(binaryNode);
+        case EQ_STRICT:
+            return enterEQ_STRICT(binaryNode);
+        case GE:
+            return enterGE(binaryNode);
+        case GT:
+            return enterGT(binaryNode);
+        case IN:
+            return enterIN(binaryNode);
+        case INSTANCEOF:
+            return enterINSTANCEOF(binaryNode);
+        case LE:
+            return enterLE(binaryNode);
+        case LT:
+            return enterLT(binaryNode);
+        case MOD:
+            return enterMOD(binaryNode);
+        case MUL:
+            return enterMUL(binaryNode);
+        case NE:
+            return enterNE(binaryNode);
+        case NE_STRICT:
+            return enterNE_STRICT(binaryNode);
+        case OR:
+            return enterOR(binaryNode);
+        case SAR:
+            return enterSAR(binaryNode);
+        case SHL:
+            return enterSHL(binaryNode);
+        case SHR:
+            return enterSHR(binaryNode);
+        case SUB:
+            return enterSUB(binaryNode);
+        default:
+            return super.enter(binaryNode);
+        }
+    }
+
+    @Override
+    public final Node leave(final BinaryNode binaryNode) {
+        switch (binaryNode.tokenType()) {
+        case ADD:
+            return leaveADD(binaryNode);
+        case AND:
+            return leaveAND(binaryNode);
+        case ASSIGN:
+            return leaveASSIGN(binaryNode);
+        case ASSIGN_ADD:
+            return leaveASSIGN_ADD(binaryNode);
+        case ASSIGN_BIT_AND:
+            return leaveASSIGN_BIT_AND(binaryNode);
+        case ASSIGN_BIT_OR:
+            return leaveASSIGN_BIT_OR(binaryNode);
+        case ASSIGN_BIT_XOR:
+            return leaveASSIGN_BIT_XOR(binaryNode);
+        case ASSIGN_DIV:
+            return leaveASSIGN_DIV(binaryNode);
+        case ASSIGN_MOD:
+            return leaveASSIGN_MOD(binaryNode);
+        case ASSIGN_MUL:
+            return leaveASSIGN_MUL(binaryNode);
+        case ASSIGN_SAR:
+            return leaveASSIGN_SAR(binaryNode);
+        case ASSIGN_SHL:
+            return leaveASSIGN_SHL(binaryNode);
+        case ASSIGN_SHR:
+            return leaveASSIGN_SHR(binaryNode);
+        case ASSIGN_SUB:
+            return leaveASSIGN_SUB(binaryNode);
+        case BIND:
+            return leaveBIND(binaryNode);
+        case BIT_AND:
+            return leaveBIT_AND(binaryNode);
+        case BIT_OR:
+            return leaveBIT_OR(binaryNode);
+        case BIT_XOR:
+            return leaveBIT_XOR(binaryNode);
+        case COMMARIGHT:
+            return leaveCOMMARIGHT(binaryNode);
+        case COMMALEFT:
+            return leaveCOMMALEFT(binaryNode);
+        case DIV:
+            return leaveDIV(binaryNode);
+        case EQ:
+            return leaveEQ(binaryNode);
+        case EQ_STRICT:
+            return leaveEQ_STRICT(binaryNode);
+        case GE:
+            return leaveGE(binaryNode);
+        case GT:
+            return leaveGT(binaryNode);
+        case IN:
+            return leaveIN(binaryNode);
+        case INSTANCEOF:
+            return leaveINSTANCEOF(binaryNode);
+        case LE:
+            return leaveLE(binaryNode);
+        case LT:
+            return leaveLT(binaryNode);
+        case MOD:
+            return leaveMOD(binaryNode);
+        case MUL:
+            return leaveMUL(binaryNode);
+        case NE:
+            return leaveNE(binaryNode);
+        case NE_STRICT:
+            return leaveNE_STRICT(binaryNode);
+        case OR:
+            return leaveOR(binaryNode);
+        case SAR:
+            return leaveSAR(binaryNode);
+        case SHL:
+            return leaveSHL(binaryNode);
+        case SHR:
+            return leaveSHR(binaryNode);
+        case SUB:
+            return leaveSUB(binaryNode);
+        default:
+            return super.leave(binaryNode);
+        }
+    }
+
+    /*
+    @Override
+    public Node enter(final TernaryNode ternaryNode) {
+        return enterDefault(ternaryNode);
+    }
+
+    @Override
+    public Node leave(final TernaryNode ternaryNode) {
+        return leaveDefault(ternaryNode);
+    }*/
+
+    /*
+     * Unary entries and exists.
+     */
+
+    /**
+     * Unary enter - callback for entering a unary +
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterADD(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a unary +
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+     public Node leaveADD(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a ~ operator
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterBIT_NOT(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a unary ~
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveBIT_NOT(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a conversion
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterCONVERT(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a conversion
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveCONVERT(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a ++ or -- operator
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterDECINC(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a ++ or -- operator
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+     public Node leaveDECINC(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a delete operator
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterDELETE(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a delete operator
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+     public Node leaveDELETE(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a discard operator
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterDISCARD(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a discard operator
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+     public Node leaveDISCARD(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a new operator
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterNEW(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a new operator
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+     public Node leaveNEW(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a ! operator
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterNOT(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a ! operator
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+     public Node leaveNOT(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a unary -
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterSUB(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a unary -
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveSUB(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a typeof
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterTYPEOF(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a typeof operator
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+     public Node leaveTYPEOF(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Unary enter - callback for entering a void
+     *
+     * @param  unaryNode the node
+     * @return processed node
+     */
+    public Node enterVOID(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Unary leave - callback for leaving a void
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+     public Node leaveVOID(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering + operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterADD(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a + operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+     public Node leaveADD(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal &&} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterAND(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a {@literal &&} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveAND(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering an assignment
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving an assignment
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering += operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_ADD(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a += operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_ADD(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal &=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_BIT_AND(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a {@literal &=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_BIT_AND(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering |= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_BIT_OR(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a |= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_BIT_OR(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering ^= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a ^= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering /= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_DIV(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a /= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_DIV(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering %= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_MOD(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a %= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_MOD(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering *= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_MUL(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a *= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_MUL(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal >>=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_SAR(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a {@literal >>=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_SAR(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering a {@literal <<=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_SHL(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a {@literal <<=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_SHL(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal >>>=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_SHR(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a {@literal >>>=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_SHR(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering -= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterASSIGN_SUB(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a -= operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveASSIGN_SUB(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering a bind operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterBIND(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a bind operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveBIND(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal &} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterBIT_AND(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a {@literal &} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveBIT_AND(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering | operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterBIT_OR(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a | operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveBIT_OR(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering ^ operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterBIT_XOR(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a  operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveBIT_XOR(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering comma left operator
+     * (a, b) where the result is a
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterCOMMALEFT(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a comma left operator
+     * (a, b) where the result is a
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering comma right operator
+     * (a, b) where the result is b
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterCOMMARIGHT(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a comma left operator
+     * (a, b) where the result is b
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveCOMMARIGHT(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering a division
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterDIV(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving a division
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveDIV(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering == operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterEQ(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving == operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveEQ(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering === operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterEQ_STRICT(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving === operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveEQ_STRICT(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal >=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterGE(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving {@literal >=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveGE(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal >} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterGT(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving {@literal >} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveGT(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering in operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterIN(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving in operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveIN(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering instanceof operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterINSTANCEOF(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving instanceof operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveINSTANCEOF(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal <=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterLE(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving {@literal <=} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveLE(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal <} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterLT(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving {@literal <} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveLT(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+    /**
+     * Binary enter - callback for entering % operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterMOD(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving % operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveMOD(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering * operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterMUL(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving * operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveMUL(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering != operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterNE(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving != operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveNE(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering a !== operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterNE_STRICT(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving !== operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveNE_STRICT(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering || operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterOR(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving || operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveOR(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal >>} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterSAR(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving {@literal >>} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveSAR(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering {@literal <<} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterSHL(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving {@literal <<} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveSHL(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+    /**
+     * Binary enter - callback for entering {@literal >>>} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterSHR(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving {@literal >>>} operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveSHR(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Binary enter - callback for entering - operator
+     *
+     * @param  binaryNode the node
+     * @return processed node
+     */
+    public Node enterSUB(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Binary leave - callback for leaving - operator
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveSUB(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java
new file mode 100644
index 0000000..9ce6fd0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java
@@ -0,0 +1,882 @@
+/*
+ * 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.ir.visitor;
+
+import jdk.nashorn.internal.codegen.CompileUnit;
+import jdk.nashorn.internal.codegen.MethodEmitter;
+import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BreakNode;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.CaseNode;
+import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ContinueNode;
+import jdk.nashorn.internal.ir.DoWhileNode;
+import jdk.nashorn.internal.ir.EmptyNode;
+import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.IndexNode;
+import jdk.nashorn.internal.ir.LabelNode;
+import jdk.nashorn.internal.ir.LineNumberNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
+import jdk.nashorn.internal.ir.PropertyNode;
+import jdk.nashorn.internal.ir.ReferenceNode;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.TernaryNode;
+import jdk.nashorn.internal.ir.ThrowNode;
+import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.WhileNode;
+import jdk.nashorn.internal.ir.WithNode;
+
+/**
+ * Visitor used to navigate the IR.
+ */
+public abstract class NodeVisitor {
+    /** Current functionNode. */
+    private FunctionNode currentFunctionNode;
+
+    /** Current compile unit used for class generation. */
+    private CompileUnit compileUnit;
+
+    /**
+     * Current method visitor used for method generation.
+     * <p>
+     * TODO: protected is just for convenience and readability, so that
+     * subclasses can directly use 'method' - might want to change that
+     */
+    protected MethodEmitter method;
+
+    /** Current block. */
+    private Block currentBlock;
+
+    /**
+     * Constructor.
+     */
+    public NodeVisitor() {
+        this(null, null);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param compileUnit compile unit for this node visitor
+     * @param method method emitter for this node visitor
+     */
+    public NodeVisitor(final CompileUnit compileUnit, final MethodEmitter method) {
+        super();
+
+        this.compileUnit = compileUnit;
+        this.method      = method;
+    }
+
+    /**
+     * Override this method to do a double inheritance pattern, e.g. avoid
+     * using
+     * <p>
+     * if (x instanceof NodeTypeA) {
+     *    ...
+     * } else if (x instanceof NodeTypeB) {
+     *    ...
+     * } else {
+     *    ...
+     * }
+     * <p>
+     * Use a NodeVisitor instead, and this method contents forms the else case.
+     *
+     * @see NodeVisitor#leaveDefault(Node)
+     * @param node the node to visit
+     * @return the node
+     */
+    protected Node enterDefault(final Node node) {
+        return node;
+    }
+
+    /**
+     * Override this method to do a double inheritance pattern, e.g. avoid
+     * using
+     * <p>
+     * if (x instanceof NodeTypeA) {
+     *    ...
+     * } else if (x instanceof NodeTypeB) {
+     *    ...
+     * } else {
+     *    ...
+     * }
+     * <p>
+     * Use a NodeVisitor instead, and this method contents forms the else case.
+     *
+     * @see NodeVisitor#enterDefault(Node)
+     * @param node the node to visit
+     * @return the node
+     */
+    protected Node leaveDefault(final Node node) {
+        return node;
+    }
+
+    /**
+     * Callback for entering an AccessNode
+     *
+     * @param  accessNode the node
+     * @return processed node, null if traversal should end, null if traversal should end
+     */
+    public Node enter(final AccessNode accessNode) {
+        return enterDefault(accessNode);
+    }
+
+    /**
+     * Callback for entering an AccessNode
+     *
+     * @param  accessNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node leave(final AccessNode accessNode) {
+        return leaveDefault(accessNode);
+    }
+
+    /**
+     * Callback for entering a Block
+     *
+     * @param  block     the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final Block block) {
+        return enterDefault(block);
+    }
+
+    /**
+     * Callback for leaving a Block
+     *
+     * @param  block the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final Block block) {
+        return leaveDefault(block);
+    }
+
+    /**
+     * Callback for entering a BinaryNode
+     *
+     * @param  binaryNode  the node
+     * @return processed   node
+     */
+    public Node enter(final BinaryNode binaryNode) {
+        return enterDefault(binaryNode);
+    }
+
+    /**
+     * Callback for leaving a BinaryNode
+     *
+     * @param  binaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final BinaryNode binaryNode) {
+        return leaveDefault(binaryNode);
+    }
+
+    /**
+     * Callback for entering a BreakNode
+     *
+     * @param  breakNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final BreakNode breakNode) {
+        return enterDefault(breakNode);
+    }
+
+    /**
+     * Callback for leaving a BreakNode
+     *
+     * @param  breakNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final BreakNode breakNode) {
+        return leaveDefault(breakNode);
+    }
+
+    /**
+     * Callback for entering a CallNode
+     *
+     * @param  callNode  the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final CallNode callNode) {
+        return enterDefault(callNode);
+    }
+
+    /**
+     * Callback for leaving a CallNode
+     *
+     * @param  callNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final CallNode callNode) {
+        return leaveDefault(callNode);
+    }
+
+    /**
+     * Callback for entering a CaseNode
+     *
+     * @param  caseNode  the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final CaseNode caseNode) {
+        return enterDefault(caseNode);
+    }
+
+    /**
+     * Callback for leaving a CaseNode
+     *
+     * @param  caseNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final CaseNode caseNode) {
+        return leaveDefault(caseNode);
+    }
+
+    /**
+     * Callback for entering a CatchNode
+     *
+     * @param  catchNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final CatchNode catchNode) {
+        return enterDefault(catchNode);
+    }
+
+    /**
+     * Callback for leaving a CatchNode
+     *
+     * @param  catchNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final CatchNode catchNode) {
+        return leaveDefault(catchNode);
+    }
+
+    /**
+     * Callback for entering a ContinueNode
+     *
+     * @param  continueNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final ContinueNode continueNode) {
+        return enterDefault(continueNode);
+    }
+
+    /**
+     * Callback for leaving a ContinueNode
+     *
+     * @param  continueNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final ContinueNode continueNode) {
+        return leaveDefault(continueNode);
+    }
+
+    /**
+     * Callback for entering a DoWhileNode
+     *
+     * @param  doWhileNode the node
+     * @return processed   node
+     */
+    public Node enter(final DoWhileNode doWhileNode) {
+        return enterDefault(doWhileNode);
+    }
+
+    /**
+     * Callback for leaving a DoWhileNode
+     *
+     * @param  doWhileNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final DoWhileNode doWhileNode) {
+        return leaveDefault(doWhileNode);
+    }
+
+    /**
+     * Callback for entering an EmptyNode
+     *
+     * @param  emptyNode   the node
+     * @return processed   node
+     */
+    public Node enter(final EmptyNode emptyNode) {
+        return enterDefault(emptyNode);
+    }
+
+    /**
+     * Callback for leaving an EmptyNode
+     *
+     * @param  emptyNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final EmptyNode emptyNode) {
+        return leaveDefault(emptyNode);
+    }
+
+    /**
+     * Callback for entering an ExecuteNode
+     *
+     * @param  executeNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final ExecuteNode executeNode) {
+        return enterDefault(executeNode);
+    }
+
+    /**
+     * Callback for leaving an ExecuteNode
+     *
+     * @param  executeNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final ExecuteNode executeNode) {
+        return leaveDefault(executeNode);
+    }
+
+    /**
+     * Callback for entering a ForNode
+     *
+     * @param  forNode   the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final ForNode forNode) {
+        return enterDefault(forNode);
+    }
+
+    /**
+     * Callback for leaving a ForNode
+     *
+     * @param  forNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final ForNode forNode) {
+        return leaveDefault(forNode);
+    }
+
+    /**
+     * Callback for entering a FunctionNode
+     *
+     * @param  functionNode the node
+     * @return processed    node
+     */
+    public Node enter(final FunctionNode functionNode) {
+        return enterDefault(functionNode);
+    }
+
+    /**
+     * Callback for leaving a FunctionNode
+     *
+     * @param  functionNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final FunctionNode functionNode) {
+        return leaveDefault(functionNode);
+    }
+
+    /**
+     * Callback for entering an IdentNode
+     *
+     * @param  identNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final IdentNode identNode) {
+        return enterDefault(identNode);
+    }
+
+    /**
+     * Callback for leaving an IdentNode
+     *
+     * @param  identNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final IdentNode identNode) {
+        return leaveDefault(identNode);
+    }
+
+    /**
+     * Callback for entering an IfNode
+     *
+     * @param  ifNode    the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final IfNode ifNode) {
+        return enterDefault(ifNode);
+    }
+
+    /**
+     * Callback for leaving an IfNode
+     *
+     * @param  ifNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final IfNode ifNode) {
+        return leaveDefault(ifNode);
+    }
+
+    /**
+     * Callback for entering an IndexNode
+     *
+     * @param  indexNode  the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final IndexNode indexNode) {
+        return enterDefault(indexNode);
+    }
+
+    /**
+     * Callback for leaving an IndexNode
+     *
+     * @param  indexNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final IndexNode indexNode) {
+        return leaveDefault(indexNode);
+    }
+
+    /**
+     * Callback for entering a LabelNode
+     *
+     * @param  labelNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final LabelNode labelNode) {
+        return enterDefault(labelNode);
+    }
+
+    /**
+     * Callback for leaving a LabelNode
+     *
+     * @param  labelNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final LabelNode labelNode) {
+        return leaveDefault(labelNode);
+    }
+
+    /**
+     * Callback for entering a LineNumberNode
+     *
+     * @param  lineNumberNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final LineNumberNode lineNumberNode) {
+        return enterDefault(lineNumberNode);
+    }
+
+    /**
+     * Callback for leaving a LineNumberNode
+     *
+     * @param  lineNumberNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final LineNumberNode lineNumberNode) {
+        return leaveDefault(lineNumberNode);
+    }
+
+    /**
+     * Callback for entering a LiteralNode
+     *
+     * @param  literalNode the node
+     * @return processed   node
+     */
+    @SuppressWarnings("rawtypes")
+    public Node enter(final LiteralNode literalNode) {
+        return enterDefault(literalNode);
+    }
+
+    /**
+     * Callback for leaving a LiteralNode
+     *
+     * @param  literalNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    @SuppressWarnings("rawtypes")
+    public Node leave(final LiteralNode literalNode) {
+        return leaveDefault(literalNode);
+    }
+
+    /**
+     * Callback for entering an ObjectNode
+     *
+     * @param  objectNode the node
+     * @return processed  node
+     */
+    public Node enter(final ObjectNode objectNode) {
+        return enterDefault(objectNode);
+    }
+
+    /**
+     * Callback for leaving an ObjectNode
+     *
+     * @param  objectNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final ObjectNode objectNode) {
+        return leaveDefault(objectNode);
+    }
+
+    /**
+     * Callback for entering a PropertyNode
+     *
+     * @param  propertyNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final PropertyNode propertyNode) {
+        return enterDefault(propertyNode);
+    }
+
+    /**
+     * Callback for leaving a PropertyNode
+     *
+     * @param  propertyNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final PropertyNode propertyNode) {
+        return leaveDefault(propertyNode);
+    }
+
+    /**
+     * Callback for entering a ReferenceNode
+     *
+     * @param  referenceNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final ReferenceNode referenceNode) {
+        return enterDefault(referenceNode);
+    }
+
+    /**
+     * Callback for leaving a ReferenceNode
+     *
+     * @param  referenceNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final ReferenceNode referenceNode) {
+        return leaveDefault(referenceNode);
+    }
+
+    /**
+     * Callback for entering a ReturnNode
+     *
+     * @param  returnNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final ReturnNode returnNode) {
+        return enterDefault(returnNode);
+    }
+
+    /**
+     * Callback for leaving a ReturnNode
+     *
+     * @param  returnNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final ReturnNode returnNode) {
+        return leaveDefault(returnNode);
+    }
+
+    /**
+     * Callback for entering a RuntimeNode
+     *
+     * @param  runtimeNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final RuntimeNode runtimeNode) {
+        return enterDefault(runtimeNode);
+    }
+
+    /**
+     * Callback for leaving a RuntimeNode
+     *
+     * @param  runtimeNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final RuntimeNode runtimeNode) {
+        return leaveDefault(runtimeNode);
+    }
+
+    /**
+     * Callback for entering a SplitNode
+     *
+     * @param  splitNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final SplitNode splitNode) {
+        return enterDefault(splitNode);
+    }
+
+    /**
+     * Callback for leaving a SplitNode
+     *
+     * @param  splitNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final SplitNode splitNode) {
+        return leaveDefault(splitNode);
+    }
+
+    /**
+     * Callback for entering a SwitchNode
+     *
+     * @param  switchNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final SwitchNode switchNode) {
+        return enterDefault(switchNode);
+    }
+
+    /**
+     * Callback for leaving a SwitchNode
+     *
+     * @param  switchNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final SwitchNode switchNode) {
+        return leaveDefault(switchNode);
+    }
+
+    /**
+     * Callback for entering a TernaryNode
+     *
+     * @param  ternaryNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final TernaryNode ternaryNode) {
+        return enterDefault(ternaryNode);
+    }
+
+    /**
+     * Callback for leaving a TernaryNode
+     *
+     * @param  ternaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final TernaryNode ternaryNode) {
+        return leaveDefault(ternaryNode);
+    }
+
+    /**
+     * Callback for entering a ThrowNode
+     *
+     * @param  throwNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final ThrowNode throwNode) {
+        return enterDefault(throwNode);
+    }
+
+    /**
+     * Callback for leaving a ThrowNode
+     *
+     * @param  throwNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final ThrowNode throwNode) {
+        return leaveDefault(throwNode);
+    }
+
+    /**
+     * Callback for entering a TryNode
+     *
+     * @param  tryNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final TryNode tryNode) {
+        return enterDefault(tryNode);
+    }
+
+    /**
+     * Callback for leaving a TryNode
+     *
+     * @param  tryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final TryNode tryNode) {
+        return leaveDefault(tryNode);
+    }
+
+    /**
+     * Callback for entering a UnaryNode
+     *
+     * @param  unaryNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final UnaryNode unaryNode) {
+        return enterDefault(unaryNode);
+    }
+
+    /**
+     * Callback for leaving a UnaryNode
+     *
+     * @param  unaryNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final UnaryNode unaryNode) {
+        return leaveDefault(unaryNode);
+    }
+
+    /**
+     * Callback for entering a VarNode
+     *
+     * @param  varNode   the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final VarNode varNode) {
+        return enterDefault(varNode);
+    }
+
+    /**
+     * Callback for leaving a VarNode
+     *
+     * @param  varNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final VarNode varNode) {
+        return leaveDefault(varNode);
+    }
+
+    /**
+     * Callback for entering a WhileNode
+     *
+     * @param  whileNode the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final WhileNode whileNode) {
+        return enterDefault(whileNode);
+    }
+
+    /**
+     * Callback for leaving a WhileNode
+     *
+     * @param  whileNode the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final WhileNode whileNode) {
+        return leaveDefault(whileNode);
+    }
+
+    /**
+     * Callback for entering a WithNode
+     *
+     * @param  withNode  the node
+     * @return processed node, null if traversal should end
+     */
+    public Node enter(final WithNode withNode) {
+        return enterDefault(withNode);
+    }
+
+    /**
+     * Callback for leaving a WithNode
+     *
+     * @param  withNode  the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leave(final WithNode withNode) {
+        return leaveDefault(withNode);
+    }
+
+    /**
+     * Get the current function node for this NodeVisitor
+     * @see FunctionNode
+     * @return the function node being visited
+     */
+    public FunctionNode getCurrentFunctionNode() {
+        return currentFunctionNode;
+    }
+
+    /**
+     * Reset the current function node being visited for this NodeVisitor
+     * @see FunctionNode
+     * @param currentFunctionNode a new function node to traverse
+     */
+    public void setCurrentFunctionNode(final FunctionNode currentFunctionNode) {
+        this.currentFunctionNode = currentFunctionNode;
+    }
+
+    /**
+     * Get the current compile unit for this NodeVisitor
+     * @see CompileUnit
+     * @return a compile unit, or null if not a compiling NodeVisitor
+     */
+    public CompileUnit getCurrentCompileUnit() {
+        return compileUnit;
+    }
+
+    /**
+     * Set the current compile unit for this NodeVisitor
+     * @see CompileUnit
+     * @param compileUnit a new compile unit
+     */
+    public void setCurrentCompileUnit(final CompileUnit compileUnit) {
+        this.compileUnit = compileUnit;
+    }
+
+    /**
+     * Get the current method emitter for this NodeVisitor
+     * @see MethodEmitter
+     * @return the method emitter
+     */
+    public MethodEmitter getCurrentMethodEmitter() {
+        return method;
+    }
+
+    /**
+     * Reset the current method emitter for this NodeVisitor
+     * @see MethodEmitter
+     * @param method a new method emitter
+     */
+    public void setCurrentMethodEmitter(final MethodEmitter method) {
+        this.method = method;
+    }
+
+    /**
+     * Get the current Block being traversed for this NodeVisitor
+     * @return the current block
+     */
+    public Block getCurrentBlock() {
+        return currentBlock;
+    }
+
+    /**
+     * Reset the Block to be traversed for this NodeVisitor
+     * @param currentBlock the new current block
+     */
+    public void setCurrentBlock(final Block currentBlock) {
+        this.currentBlock = currentBlock;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java b/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java
new file mode 100644
index 0000000..a454527
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java
@@ -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));
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java
new file mode 100644
index 0000000..2161c78
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java
@@ -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;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java
new file mode 100644
index 0000000..c7dd83b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java
@@ -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);
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java b/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java
new file mode 100644
index 0000000..73397b5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java
@@ -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.  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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.sameValue;
+
+import java.util.Objects;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Accessor Property descriptor is used to represent attributes an object property
+ * that either has a getter or a setter.
+ *
+ * See ECMA 8.10 The Property Descriptor and Property Identifier Specification Types
+ *
+ */
+@ScriptClass("AccessorPropertyDescriptor")
+public final class AccessorPropertyDescriptor extends ScriptObject implements PropertyDescriptor {
+    /** is this property configurable? */
+    @Property
+    public Object configurable;
+
+    /** is this property enumerable? */
+    @Property
+    public Object enumerable;
+
+    /** getter for property */
+    @Property
+    public Object get;
+
+    /** setter for property */
+    @Property
+    public Object set;
+
+    AccessorPropertyDescriptor() {
+        this(false, false, UNDEFINED, UNDEFINED);
+    }
+
+    AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set) {
+        this.configurable = configurable;
+        this.enumerable   = enumerable;
+        this.get          = get;
+        this.set          = set;
+        setProto(Global.objectPrototype());
+    }
+
+    @Override
+    public boolean isConfigurable() {
+        return JSType.toBoolean(configurable);
+    }
+
+    @Override
+    public boolean isEnumerable() {
+        return JSType.toBoolean(enumerable);
+    }
+
+    @Override
+    public boolean isWritable() {
+        // Not applicable for this. But simplifies flag calculations.
+        return true;
+    }
+
+    @Override
+    public Object getValue() {
+        throw new UnsupportedOperationException("value");
+    }
+
+    @Override
+    public ScriptFunction getGetter() {
+        return (get instanceof ScriptFunction) ? (ScriptFunction)get : null;
+    }
+
+    @Override
+    public ScriptFunction getSetter() {
+        return (set instanceof ScriptFunction) ? (ScriptFunction)set : null;
+    }
+
+    @Override
+    public void setConfigurable(final boolean flag) {
+        this.configurable = flag;
+    }
+
+    @Override
+    public void setEnumerable(final boolean flag) {
+        this.enumerable = flag;
+    }
+
+    @Override
+    public void setWritable(final boolean flag) {
+        throw new UnsupportedOperationException("set writable");
+    }
+
+    @Override
+    public void setValue(final Object value) {
+        throw new UnsupportedOperationException("set value");
+    }
+
+    @Override
+    public void setGetter(final Object getter) {
+        this.get = getter;
+    }
+
+    @Override
+    public void setSetter(final Object setter) {
+        this.set = setter;
+    }
+
+    @Override
+    public PropertyDescriptor fillFrom(final ScriptObject sobj) {
+        final boolean strict = isStrictContext();
+
+        if (sobj.has(CONFIGURABLE)) {
+            this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
+        } else {
+            delete(CONFIGURABLE, strict);
+        }
+
+        if (sobj.has(ENUMERABLE)) {
+            this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
+        } else {
+            delete(ENUMERABLE, strict);
+        }
+
+        if (sobj.has(GET)) {
+            final Object getter = sobj.get(GET);
+            if (getter == UNDEFINED || getter instanceof ScriptFunction) {
+                this.get = getter;
+            } else {
+                throw typeError("not.a.function", ScriptRuntime.safeToString(getter));
+            }
+        } else {
+            delete(GET, strict);
+        }
+
+        if (sobj.has(SET)) {
+            final Object setter = sobj.get(SET);
+            if (setter == UNDEFINED || setter instanceof ScriptFunction) {
+                this.set = setter;
+            } else {
+                throw typeError("not.a.function", ScriptRuntime.safeToString(setter));
+            }
+        } else {
+            delete(SET, strict);
+        }
+
+        return this;
+    }
+
+    @Override
+    public int type() {
+        return ACCESSOR;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (! (obj instanceof AccessorPropertyDescriptor)) {
+            return false;
+        }
+
+        final AccessorPropertyDescriptor other = (AccessorPropertyDescriptor)obj;
+        return sameValue(configurable, other.configurable) &&
+               sameValue(enumerable, other.enumerable) &&
+               sameValue(get, other.get) &&
+               sameValue(set, other.set);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 41 * hash + Objects.hashCode(this.configurable);
+        hash = 41 * hash + Objects.hashCode(this.enumerable);
+        hash = 41 * hash + Objects.hashCode(this.get);
+        hash = 41 * hash + Objects.hashCode(this.set);
+        return hash;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
new file mode 100644
index 0000000..a442a38
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
@@ -0,0 +1,370 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Getter;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+@ScriptClass("ArrayBufferView")
+abstract class ArrayBufferView extends ScriptObject {
+
+    ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+        checkConstructorArgs(buffer, byteOffset, elementLength);
+        this.setProto(getPrototype());
+        this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
+    }
+
+    private void checkConstructorArgs(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+        if (byteOffset < 0 || elementLength < 0) {
+            throw new RuntimeException("byteOffset or length must not be negative");
+        }
+        if (byteOffset + elementLength * bytesPerElement() > buffer.getByteLength()) {
+            throw new RuntimeException("byteOffset + byteLength out of range");
+        }
+        if (byteOffset % bytesPerElement() != 0) {
+            throw new RuntimeException("byteOffset must be a multiple of the element size");
+        }
+    }
+
+    private int bytesPerElement() {
+        return factory().bytesPerElement;
+    }
+
+    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+    public static Object BYTES_PER_ELEMENT(final Object self) {
+        return ((ArrayBufferView)self).bytesPerElement();
+    }
+
+    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+    public static Object buffer(final Object self) {
+        return ((ArrayDataImpl)((ArrayBufferView)self).getArray()).buffer;
+    }
+
+    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+    public static Object byteOffset(final Object self) {
+        return ((ArrayDataImpl)((ArrayBufferView)self).getArray()).byteOffset;
+    }
+
+    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+    public static Object byteLength(final Object self) {
+        final ArrayBufferView view = (ArrayBufferView)self;
+        return ((ArrayDataImpl)view.getArray()).elementLength * view.bytesPerElement();
+    }
+
+    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+    public static Object length(final Object self) {
+        return ((ArrayBufferView)self).elementLength();
+    }
+
+    @Override
+    public final Object getLength() {
+        return elementLength();
+    }
+
+    private int elementLength() {
+        return ((ArrayDataImpl)getArray()).elementLength;
+    }
+
+    protected static abstract class ArrayDataImpl extends ArrayData {
+        protected final NativeArrayBuffer buffer;
+        protected final int byteOffset;
+        private final int elementLength;
+
+        protected ArrayDataImpl(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+            super(elementLength);
+            this.buffer = buffer;
+            this.byteOffset = byteOffset;
+            this.elementLength = elementLength;
+        }
+
+        @Override
+        public Object[] asObjectArray() {
+            final Object[] array = new Object[elementLength];
+            for (int i = 0; i < elementLength; i++) {
+                array[i] = getObjectImpl(i);
+            }
+            return array;
+        }
+
+        @Override
+        public ArrayData ensure(final long safeIndex) {
+            return this;
+        }
+
+        @Override
+        public void setLength(final long length) {
+            //empty?
+            //TODO is this right?
+        }
+
+        @Override
+        public ArrayData shrink(final long newLength) {
+            return this;
+        }
+
+        @Override
+        public ArrayData set(final int index, final Object value, final boolean strict) {
+            if (has(index)) {
+                setImpl(index, value);
+            }
+            return this;
+        }
+
+        @Override
+        public ArrayData set(final int index, final int value, final boolean strict) {
+            if (has(index)) {
+                setImpl(index, value);
+            }
+            return this;
+        }
+
+        @Override
+        public ArrayData set(final int index, final long value, final boolean strict) {
+            if (has(index)) {
+                setImpl(index, value);
+            }
+            return this;
+        }
+
+        @Override
+        public ArrayData set(final int index, final double value, final boolean strict) {
+            if (has(index)) {
+                setImpl(index, value);
+            }
+            return this;
+        }
+
+        @Override
+        public int getInt(final int index) {
+            return getIntImpl(index);
+        }
+
+        @Override
+        public long getLong(final int index) {
+            return getLongImpl(index);
+        }
+
+        @Override
+        public double getDouble(final int index) {
+            return getDoubleImpl(index);
+        }
+
+        @Override
+        public Object getObject(final int index) {
+            return getObjectImpl(index);
+        }
+
+        @Override
+        public boolean has(final int index) {
+            return index >= 0 && index < elementLength;
+        }
+
+        @Override
+        public boolean canDelete(final int index, final boolean strict) {
+            return false;
+        }
+
+        @Override
+        public boolean canDelete(final long fromIndex, final long toIndex, final boolean strict) {
+            return false;
+        }
+
+        @Override
+        public ArrayData delete(final int index) {
+            return this;
+        }
+
+        @Override
+        public ArrayData delete(final long fromIndex, final long toIndex) {
+            return this;
+        }
+
+        @Override
+        protected ArrayData convert(final Class<?> type) {
+            return this;
+        }
+
+        @Override
+        public void shiftLeft(final int by) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ArrayData shiftRight(final int by) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Object pop() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ArrayData slice(final long from, final long to) {
+            throw new UnsupportedOperationException();
+        }
+
+        protected abstract int getIntImpl(int key);
+
+        protected long getLongImpl(final int key) {
+            return getIntImpl(key);
+        }
+
+        protected double getDoubleImpl(final int key) {
+            return getIntImpl(key);
+        }
+
+        protected Object getObjectImpl(final int key) {
+            return getIntImpl(key);
+        }
+
+        protected abstract void setImpl(int key, int value);
+
+        protected void setImpl(final int key, final long value) {
+            setImpl(key, (int)value);
+        }
+
+        protected void setImpl(final int key, final double value) {
+            setImpl(key, JSType.toInt32(value));
+        }
+
+        protected void setImpl(final int key, final Object value) {
+            setImpl(key, JSType.toInt32(value));
+        }
+
+        protected abstract int byteIndex(int index);
+    }
+
+    protected static abstract class Factory {
+        final int bytesPerElement;
+
+        public Factory(final int bytesPerElement) {
+            this.bytesPerElement = bytesPerElement;
+        }
+
+        public final ArrayBufferView construct(final int elementLength) {
+            return construct(new NativeArrayBuffer(elementLength * bytesPerElement), 0, elementLength);
+        }
+
+        public abstract ArrayBufferView construct(NativeArrayBuffer buffer, int byteOffset, int elementLength);
+
+        public abstract ArrayData createArrayData(NativeArrayBuffer buffer, int byteOffset, int elementLength);
+    }
+
+    protected abstract Factory factory();
+
+    protected abstract ScriptObject getPrototype();
+
+    protected boolean isFloatArray() {
+        return false;
+    }
+
+    protected static ArrayBufferView constructorImpl(final Object[] args, final Factory factory) {
+        final Object arg0 = args.length != 0 ? args[0] : 0;
+        final ArrayBufferView dst;
+        final int length;
+        if (arg0 instanceof NativeArrayBuffer) {
+            // Constructor(ArrayBuffer buffer, optional unsigned long byteOffset, optional unsigned long length)
+            final NativeArrayBuffer buffer = (NativeArrayBuffer) arg0;
+            final int byteOffset = args.length > 1 ? JSType.toInt32(args[1]) : 0;
+            if (args.length > 2) {
+                length = JSType.toInt32(args[2]);
+            } else {
+                if ((buffer.getByteLength() - byteOffset) % factory.bytesPerElement != 0) {
+                    throw new RuntimeException("buffer.byteLength - byteOffset must be a multiple of the element size");
+                }
+                length = (buffer.getByteLength() - byteOffset) / factory.bytesPerElement;
+            }
+            return factory.construct(buffer, byteOffset, length);
+        } else if (arg0 instanceof ArrayBufferView) {
+            // Constructor(TypedArray array)
+            length = ((ArrayBufferView)arg0).elementLength();
+            dst = factory.construct(length);
+        } else if (arg0 instanceof NativeArray) {
+            // Constructor(type[] array)
+            length = (int) (((NativeArray) arg0).getArray().length() & 0x7fff_ffff);
+            dst = factory.construct(length);
+        } else {
+            // Constructor(unsigned long length)
+            length = JSType.toInt32(arg0);
+            return factory.construct(length);
+        }
+
+        copyElements(dst, length, (ScriptObject)arg0, 0);
+        return dst;
+    }
+
+    protected static Object setImpl(final Object self, final Object array, final Object offset0) {
+        final ArrayBufferView dest = ((ArrayBufferView)self);
+        final int length;
+        if (array instanceof ArrayBufferView) {
+            // void set(TypedArray array, optional unsigned long offset)
+            length = ((ArrayBufferView)array).elementLength();
+        } else if (array instanceof NativeArray) {
+            // void set(type[] array, optional unsigned long offset)
+            length = (int) (((NativeArray) array).getArray().length() & 0x7fff_ffff);
+        } else {
+            throw new RuntimeException("argument is not of array type");
+        }
+
+        final ScriptObject source = (ScriptObject) array;
+        final int offset = JSType.toInt32(offset0); // default=0
+
+        if (dest.elementLength() < length + offset || offset < 0) {
+            throw new RuntimeException("offset or array length out of bounds");
+        }
+
+        copyElements(dest, length, source, offset);
+
+        return ScriptRuntime.UNDEFINED;
+    }
+
+    private static void copyElements(final ArrayBufferView dest, final int length, final ScriptObject source, final int offset) {
+        if (!dest.isFloatArray()) {
+            for (int i = 0, j = offset; i < length; i++, j++) {
+                dest.set(j, source.getInt(i), false);
+            }
+        } else {
+            for (int i = 0, j = offset; i < length; i++, j++) {
+                dest.set(j, source.getDouble(i), false);
+            }
+        }
+    }
+
+    protected static Object subarrayImpl(final Object self, final Object begin0, final Object end0) {
+        final ArrayBufferView arrayView = ((ArrayBufferView)self);
+        final int elementLength = arrayView.elementLength();
+        final int begin = NativeArrayBuffer.adjustIndex(JSType.toInt32(begin0), elementLength);
+        final int end = NativeArrayBuffer.adjustIndex(end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : elementLength, elementLength);
+        final ArrayDataImpl arrayData = (ArrayDataImpl)arrayView.getArray();
+        return arrayView.factory().construct(arrayData.buffer, arrayData.byteIndex(begin), Math.max(end - begin, 0));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java
new file mode 100644
index 0000000..1e9e9d1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java
@@ -0,0 +1,51 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptFunctionData;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * A {@code ScriptFunctionImpl} subclass for functions created using {@code Function.prototype.bind}. Such functions
+ * must track their {@code [[TargetFunction]]} property for purposes of correctly implementing {@code [[HasInstance]]};
+ * see {@link ScriptFunction#isInstance(ScriptObject)}.
+ */
+class BoundScriptFunctionImpl extends ScriptFunctionImpl {
+    private final ScriptFunction targetFunction;
+
+    BoundScriptFunctionImpl(ScriptFunctionData data, ScriptFunction targetFunction) {
+        super(data);
+        this.prototype = ScriptRuntime.UNDEFINED;
+        this.targetFunction = targetFunction;
+    }
+
+    @Override
+    protected ScriptFunction getTargetFunction() {
+        return targetFunction;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java b/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java
new file mode 100644
index 0000000..e5f7de3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java
@@ -0,0 +1,197 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.sameValue;
+
+import java.util.Objects;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Data Property descriptor is used to represent attributes an object property
+ * that has data value (instead of a getter or setter function).
+ *
+ * See ECMA 8.10 The Property Descriptor and Property Identifier Specification Types
+ *
+ */
+@ScriptClass("DataPropertyDescriptor")
+public final class DataPropertyDescriptor extends ScriptObject implements PropertyDescriptor {
+    /** is this property configurable */
+    @Property
+    public Object configurable;
+
+    /** is this property enumerable */
+    @Property
+    public Object enumerable;
+
+    /** is this property writable */
+    @Property
+    public Object writable;
+
+    /** value of this property */
+    @Property
+    public Object value;
+
+    DataPropertyDescriptor() {
+        this(false, false, false, UNDEFINED);
+    }
+
+    DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value) {
+        this.configurable = configurable;
+        this.enumerable   = enumerable;
+        this.writable     = writable;
+        this.value        = value;
+        setProto(Global.objectPrototype());
+    }
+
+
+    @Override
+    public boolean isConfigurable() {
+        return JSType.toBoolean(configurable);
+    }
+
+    @Override
+    public boolean isEnumerable() {
+        return JSType.toBoolean(enumerable);
+    }
+
+    @Override
+    public boolean isWritable() {
+        return JSType.toBoolean(writable);
+    }
+
+    @Override
+    public Object getValue() {
+        return value;
+    }
+
+    @Override
+    public ScriptFunction getGetter() {
+        throw new UnsupportedOperationException("getter");
+    }
+
+    @Override
+    public ScriptFunction getSetter() {
+        throw new UnsupportedOperationException("setter");
+    }
+
+    @Override
+    public void setConfigurable(final boolean flag) {
+        this.configurable = flag;
+    }
+
+    @Override
+    public void setEnumerable(final boolean flag) {
+        this.enumerable = flag;
+    }
+
+    @Override
+    public void setWritable(final boolean flag) {
+        this.writable = flag;
+    }
+
+    @Override
+    public void setValue(final Object value) {
+        this.value = value;
+    }
+
+    @Override
+    public void setGetter(final Object getter) {
+        throw new UnsupportedOperationException("set getter");
+    }
+
+    @Override
+    public void setSetter(final Object setter) {
+        throw new UnsupportedOperationException("set setter");
+    }
+
+    @Override
+    public PropertyDescriptor fillFrom(final ScriptObject sobj) {
+        final boolean strict = isStrictContext();
+        if (sobj.has(CONFIGURABLE)) {
+            this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
+        } else {
+            delete(CONFIGURABLE, strict);
+        }
+
+        if (sobj.has(ENUMERABLE)) {
+            this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
+        } else {
+            delete(ENUMERABLE, strict);
+        }
+
+        if (sobj.has(WRITABLE)) {
+            this.writable = JSType.toBoolean(sobj.get(WRITABLE));
+        } else {
+            delete(WRITABLE, strict);
+        }
+
+        if (sobj.has(VALUE)) {
+            this.value = sobj.get(VALUE);
+        } else {
+            delete(VALUE, strict);
+        }
+
+        return this;
+    }
+
+    @Override
+    public int type() {
+        return DATA;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (! (obj instanceof DataPropertyDescriptor)) {
+            return false;
+        }
+
+        final DataPropertyDescriptor other = (DataPropertyDescriptor)obj;
+        return sameValue(configurable, other.configurable) &&
+               sameValue(enumerable, other.enumerable) &&
+               sameValue(writable, other.writable) &&
+               sameValue(value, other.value);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 5;
+        hash = 43 * hash + Objects.hashCode(this.configurable);
+        hash = 43 * hash + Objects.hashCode(this.enumerable);
+        hash = 43 * hash + Objects.hashCode(this.writable);
+        hash = 43 * hash + Objects.hashCode(this.value);
+        return hash;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/DateParser.java b/nashorn/src/jdk/nashorn/internal/objects/DateParser.java
new file mode 100644
index 0000000..544525b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/DateParser.java
@@ -0,0 +1,705 @@
+/*
+ * 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.objects;
+
+import static java.lang.Character.DECIMAL_DIGIT_NUMBER;
+import static java.lang.Character.LOWERCASE_LETTER;
+import static java.lang.Character.OTHER_PUNCTUATION;
+import static java.lang.Character.SPACE_SEPARATOR;
+import static java.lang.Character.UPPERCASE_LETTER;
+
+import java.util.HashMap;
+
+/**
+ * JavaScript date parser. This class first tries to parse a date string
+ * according to the extended ISO 8601 format specified in ES5 15.9.1.15.
+ * If that fails, it falls back to legacy mode in which it accepts a range
+ * of different formats.
+ *
+ * <p>This class is neither thread-safe nor reusable. Calling the
+ * <tt>parse()</tt> method more than once will yield undefined results.</p>
+ */
+public class DateParser {
+
+    /** Constant for index position of parsed year value. */
+    public final static int YEAR        = 0;
+    /** Constant for index position of parsed month value. */
+    public final static int MONTH       = 1;
+    /** Constant for index position of parsed day value. */
+    public final static int DAY         = 2;
+    /** Constant for index position of parsed hour value. */
+    public final static int HOUR        = 3;
+    /** Constant for index position of parsed minute value. */
+    public final static int MINUTE      = 4;
+    /** Constant for index position of parsed second value. */
+    public final static int SECOND      = 5;
+    /** Constant for index position of parsed millisecond value. */
+    public final static int MILLISECOND = 6;
+    /** Constant for index position of parsed time zone offset value. */
+    public final static int TIMEZONE    = 7;
+
+    private enum Token {
+        UNKNOWN, NUMBER, SEPARATOR, PARENTHESIS, NAME, SIGN, END
+    }
+
+    private final String string;
+    private final int length;
+    private final Integer[] fields;
+    private int pos = 0;
+    private Token token;
+    private int tokenLength;
+    private Name nameValue;
+    private int numValue;
+    private int currentField = YEAR;
+    private int yearSign = 0;
+    private boolean namedMonth = false;
+
+    private final static HashMap<String,Name> names = new HashMap<>();
+
+    static {
+        addName("monday", Name.DAY_OF_WEEK, 0);
+        addName("tuesday", Name.DAY_OF_WEEK, 0);
+        addName("wednesday", Name.DAY_OF_WEEK, 0);
+        addName("thursday", Name.DAY_OF_WEEK, 0);
+        addName("friday", Name.DAY_OF_WEEK, 0);
+        addName("saturday", Name.DAY_OF_WEEK, 0);
+        addName("sunday", Name.DAY_OF_WEEK, 0);
+        addName("january", Name.MONTH_NAME, 1);
+        addName("february", Name.MONTH_NAME, 2);
+        addName("march", Name.MONTH_NAME, 3);
+        addName("april", Name.MONTH_NAME, 4);
+        addName("may", Name.MONTH_NAME, 5);
+        addName("june", Name.MONTH_NAME, 6);
+        addName("july", Name.MONTH_NAME, 7);
+        addName("august", Name.MONTH_NAME, 8);
+        addName("september", Name.MONTH_NAME, 9);
+        addName("october", Name.MONTH_NAME, 10);
+        addName("november", Name.MONTH_NAME, 11);
+        addName("december", Name.MONTH_NAME, 12);
+        addName("am", Name.AM_PM, 0);
+        addName("pm", Name.AM_PM, 12);
+        addName("z", Name.TIMEZONE_ID, 0);
+        addName("gmt", Name.TIMEZONE_ID, 0);
+        addName("ut", Name.TIMEZONE_ID, 0);
+        addName("utc", Name.TIMEZONE_ID, 0);
+        addName("est", Name.TIMEZONE_ID, -5 * 60);
+        addName("edt", Name.TIMEZONE_ID, -4 * 60);
+        addName("cst", Name.TIMEZONE_ID, -6 * 60);
+        addName("cdt", Name.TIMEZONE_ID, -5 * 60);
+        addName("mst", Name.TIMEZONE_ID, -7 * 60);
+        addName("mdt", Name.TIMEZONE_ID, -6 * 60);
+        addName("pst", Name.TIMEZONE_ID, -8 * 60);
+        addName("pdt", Name.TIMEZONE_ID, -7 * 60);
+        addName("t", Name.TIME_SEPARATOR, 0);
+    }
+
+    /**
+     * Construct a new <tt>DateParser</tt> instance for parsing the given string.
+     * @param string the string to be parsed
+     */
+    public DateParser(final String string) {
+        this.string = string;
+        this.length = string.length();
+        this.fields = new Integer[TIMEZONE + 1];
+    }
+
+    /**
+     * Try parsing the given string as date according to the extended ISO 8601 format
+     * specified in ES5 15.9.1.15. Fall back to legacy mode if that fails.
+     * This method returns <tt>true</tt> if the string could be parsed.
+     * @return true if the string could be parsed as date
+     */
+    public boolean parse() {
+        return parseEcmaDate() || parseLegacyDate();
+    }
+
+    /**
+     * Try parsing the date string according to the rules laid out in ES5 15.9.1.15.
+     * The date string must conform to the following format:
+     *
+     * <pre>  [('-'|'+')yy]yyyy[-MM[-dd]][hh:mm[:ss[.sss]][Z|(+|-)hh:mm]] </pre>
+     *
+     * <p>If the string does not contain a time zone offset, the <tt>TIMEZONE</tt> field
+     * is set to <tt>0</tt> (GMT).</p>
+     * @return true if string represents a valid ES5 date string.
+     */
+    public boolean parseEcmaDate() {
+
+        if (token == null) {
+            token = next();
+        }
+
+        while (token != Token.END) {
+
+            switch (token) {
+                case NUMBER:
+                    if (currentField == YEAR && yearSign != 0) {
+                        // 15.9.1.15.1 Extended year must have six digits
+                        if (tokenLength != 6) {
+                            return false;
+                        }
+                        numValue *= yearSign;
+                    } else if (!checkEcmaField(currentField, numValue)) {
+                        return false;
+                    }
+                    if (!skipEcmaDelimiter()) {
+                        return false;
+                    }
+                    if (currentField < TIMEZONE) {
+                        set(currentField++, numValue);
+                    }
+                    break;
+
+                case NAME:
+                    if (nameValue == null) {
+                        return false;
+                    }
+                    switch (nameValue.type) {
+                        case Name.TIME_SEPARATOR:
+                            if (currentField == YEAR || currentField > HOUR) {
+                                return false;
+                            }
+                            currentField = HOUR;
+                            break;
+                        case Name.TIMEZONE_ID:
+                            if (!nameValue.key.equals("z") || !setTimezone(nameValue.value, false)) {
+                                return false;
+                            }
+                            break;
+                        default:
+                            return false;
+                    }
+                    break;
+
+                case SIGN:
+                    if (currentField == YEAR) {
+                        yearSign = numValue;
+                    } else if (currentField < SECOND || !setTimezone(readTimeZoneOffset(), true)) {
+                        // Note: Spidermonkey won't parse timezone unless time includes seconds and milliseconds
+                        return false;
+                    }
+                    break;
+
+                default:
+                    return false;
+            }
+            token = next();
+        }
+
+        return patchResult(true);
+    }
+
+    /**
+     * Try parsing the date using a fuzzy algorithm that can handle a variety of formats.
+     *
+     * <p>Numbers separated by <tt>':'</tt> are treated as time values, optionally followed by a
+     * millisecond value separated by <tt>'.'</tt>. Other number values are treated as date values.
+     * The exact sequence of day, month, and year values to apply is determined heuristically.</p>
+     *
+     * <p>English month names and selected time zone names as well as AM/PM markers are recognized
+     * and handled properly. Additionally, numeric time zone offsets such as <tt>(+|-)hh:mm</tt> or
+     * <tt>(+|-)hhmm</tt> are recognized. If the string does not contain a time zone offset
+     * the <tt>TIMEZONE</tt>field is left undefined, meaning the local time zone should be applied.</p>
+     *
+     * <p>English weekday names are recognized but ignored. All text in parentheses is ignored as well.
+     * All other text causes parsing to fail.</p>
+     *
+     * @return true if the string could be parsed
+     */
+    public boolean parseLegacyDate() {
+
+        if (yearSign != 0 || currentField > DAY) {
+            // we don't support signed years in legacy mode
+            return false;
+        }
+        if (token == null) {
+            token = next();
+        }
+
+        while (token != Token.END) {
+
+            switch (token) {
+                case NUMBER:
+                    if (skip(':')) {
+                        // A number followed by ':' is parsed as time
+                        if (!setTimeField(numValue)) {
+                            return false;
+                        }
+                        // consume remaining time tokens
+                        do {
+                            token = next();
+                            if (token != Token.NUMBER || !setTimeField(numValue)) {
+                                return false;
+                            }
+                        } while (skip(isSet(SECOND) ? '.' : ':'));
+
+                    } else {
+                        // Parse as date token
+                        if (!setDateField(numValue)) {
+                            return false;
+                        }
+                        skip('-');
+                    }
+                    break;
+
+                case NAME:
+                    if (nameValue == null) {
+                        return false;
+                    }
+                    switch (nameValue.type) {
+                        case Name.AM_PM:
+                            if (!setAmPm(nameValue.value)) {
+                                return false;
+                            }
+                            break;
+                        case Name.MONTH_NAME:
+                            if (!setMonth(nameValue.value)) {
+                                return false;
+                            }
+                            break;
+                        case Name.TIMEZONE_ID:
+                            if (!setTimezone(nameValue.value, false)) {
+                                return false;
+                            }
+                            break;
+                        case Name.TIME_SEPARATOR:
+                            return false;
+                        default:
+                            break;
+                    }
+                    if (nameValue.type != Name.TIMEZONE_ID) {
+                        skip('-');
+                    }
+                    break;
+
+                case SIGN:
+                    if (!setTimezone(readTimeZoneOffset(), true)) {
+                        return false;
+                    }
+                    break;
+
+                case PARENTHESIS:
+                    if (!skipParentheses()) {
+                        return false;
+                    }
+                    break;
+
+                case SEPARATOR:
+                    break;
+
+                default:
+                    return false;
+            }
+            token = next();
+        }
+
+        return patchResult(false);
+    }
+
+    /**
+     * Get the parsed date and time fields as an array of <tt>Integers</tt>.
+     *
+     * <p>If parsing was successful, all fields are guaranteed to be set except for the
+     * <tt>TIMEZONE</tt> field which may be <tt>null</tt>, meaning that local time zone
+     * offset should be applied.</p>
+     *
+     * @return the parsed date fields
+     */
+    public Integer[] getDateFields() {
+        return fields;
+    }
+
+    private boolean isSet(final int field) {
+        return fields[field] != null;
+    }
+
+    private Integer get(final int field) {
+        return fields[field];
+    }
+
+    private void set(final int field, final int value) {
+        fields[field] = value;
+    }
+
+    private int peek() {
+        return pos < length ? string.charAt(pos) : -1;
+    }
+
+    private boolean skip(final char c) {
+        if (pos < length && string.charAt(pos) == c) {
+            token = null;
+            pos++;
+            return true;
+        }
+        return false;
+    }
+
+    private Token next() {
+        if (pos >= length) {
+            tokenLength = 0;
+            return Token.END;
+        }
+
+        final char c = string.charAt(pos);
+
+        if (c > 0x80) {
+            tokenLength = 1;
+            pos++;
+            return Token.UNKNOWN; // We only deal with ASCII here
+        }
+
+        final int type = Character.getType(c);
+        switch (type) {
+            case DECIMAL_DIGIT_NUMBER:
+                numValue = readNumber(6);
+                return Token.NUMBER;
+            case SPACE_SEPARATOR :
+            case OTHER_PUNCTUATION:
+                tokenLength = 1;
+                pos++;
+                return Token.SEPARATOR;
+            case UPPERCASE_LETTER:
+            case LOWERCASE_LETTER:
+                nameValue = readName();
+                return Token.NAME;
+            default:
+                tokenLength = 1;
+                pos++;
+                switch (c) {
+                    case '(':
+                        return Token.PARENTHESIS;
+                    case '-':
+                    case '+':
+                        numValue = c == '-' ? -1 : 1;
+                        return Token.SIGN;
+                    default:
+                        return Token.UNKNOWN;
+                }
+        }
+    }
+
+    private static boolean checkLegacyField(final int field, final int value) {
+        switch (field) {
+            case HOUR:
+                return isHour(value);
+            case MINUTE:
+            case SECOND:
+                return isMinuteOrSecond(value);
+            case MILLISECOND:
+                return isMillisecond(value);
+            default:
+                // skip validation on other legacy fields as we don't know what's what
+                return true;
+        }
+    }
+
+    private boolean checkEcmaField(final int field, final int value) {
+        switch (field) {
+            case YEAR:
+                return tokenLength == 4;
+            case MONTH:
+                return tokenLength == 2 && isMonth(value);
+            case DAY:
+                return tokenLength == 2 && isDay(value);
+            case HOUR:
+                return tokenLength == 2 && isHour(value);
+            case MINUTE:
+            case SECOND:
+                return tokenLength == 2 && isMinuteOrSecond(value);
+            case MILLISECOND:
+                // we allow millisecond to be less than 3 digits
+                return tokenLength < 4 && isMillisecond(value);
+            default:
+                return true;
+        }
+    }
+
+    private boolean skipEcmaDelimiter() {
+        switch (currentField) {
+            case YEAR:
+            case MONTH:
+                return skip('-') || peek() == 'T' || peek() == -1;
+            case DAY:
+                return peek() == 'T' || peek() == -1;
+            case HOUR:
+            case MINUTE:
+                return skip(':') || endOfTime();
+            case SECOND:
+                return skip('.') || endOfTime();
+            default:
+                return true;
+        }
+    }
+
+    private boolean endOfTime() {
+        final int c = peek();
+        return c == -1 || c == 'Z' || c == '-' || c == '+' || c == ' ';
+    }
+
+    private static boolean isAsciiLetter(final char ch) {
+        return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z');
+    }
+
+    private static boolean isAsciiDigit(final char ch) {
+        return '0' <= ch && ch <= '9';
+    }
+
+    private int readNumber(final int maxDigits) {
+        final int start = pos;
+        int n = 0;
+        final int max = Math.min(length, pos + maxDigits);
+        while (pos < max && isAsciiDigit(string.charAt(pos))) {
+            n = n * 10 + string.charAt(pos++) - '0';
+        }
+        tokenLength = pos - start;
+        return n;
+    }
+
+    private Name readName() {
+        final int start = pos;
+        final int limit = Math.min(pos + 3, length);
+
+        // first read up to the key length
+        while (pos < limit && isAsciiLetter(string.charAt(pos))) {
+            pos++;
+        }
+        final String key = string.substring(start, pos).toLowerCase();
+        final Name name = names.get(key);
+        // then advance to end of name
+        while (pos < length && isAsciiLetter(string.charAt(pos))) {
+            pos++;
+        }
+
+        tokenLength = pos - start;
+        // make sure we have the full name or a prefix
+        if (name != null && name.matches(string, start, tokenLength)) {
+            return name;
+        }
+        return null;
+    }
+
+    private int readTimeZoneOffset() {
+        final int sign = string.charAt(pos - 1) == '+' ? 1 : -1;
+        int offset = readNumber(2);
+        skip(':');
+        offset = offset * 60 + readNumber(2);
+        return sign * offset;
+    }
+
+    private boolean skipParentheses() {
+        int parenCount = 1;
+        while (pos < length && parenCount != 0) {
+            final char c = string.charAt(pos++);
+            if (c == '(') {
+                parenCount++;
+            } else if (c == ')') {
+                parenCount--;
+            }
+        }
+        return true;
+    }
+
+    private static int getDefaultValue(final int field) {
+        switch (field) {
+            case MONTH:
+            case DAY:
+                return 1;
+            default:
+                return 0;
+        }
+    }
+
+    private static boolean isDay(final int n) {
+        return 1 <= n && n <= 31;
+    }
+
+    private static boolean isMonth(final int n) {
+        return 1 <= n && n <= 12;
+    }
+
+    private static boolean isHour(final int n) {
+        return 0 <= n && n <= 24;
+    }
+
+    private static boolean isMinuteOrSecond(final int n) {
+        return 0 <= n && n < 60;
+    }
+
+    private static boolean isMillisecond(final int n) {
+        return 0<= n && n < 1000;
+    }
+
+    private boolean setMonth(final int m) {
+        if (!isSet(MONTH)) {
+            namedMonth = true;
+            set(MONTH, m);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean setDateField(final int n) {
+        for (int field = YEAR; field != HOUR; field++) {
+            if (!isSet(field)) {
+                // no validation on legacy date fields
+                set(field, n);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean setTimeField(final int n) {
+        for (int field = HOUR; field != TIMEZONE; field++) {
+            if (!isSet(field)) {
+                if (checkLegacyField(field, n)) {
+                    set(field, n);
+                    return true;
+                }
+                return false;
+            }
+        }
+        return false;
+    }
+
+    private boolean setTimezone(final int offset, final boolean asNumericOffset) {
+        if (!isSet(TIMEZONE) || (asNumericOffset && get(TIMEZONE) == 0)) {
+            set(TIMEZONE, offset);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean setAmPm(final int offset) {
+        if (!isSet(HOUR)) {
+            return false;
+        }
+        final int hour = get(HOUR);
+        if (hour >= 0 && hour <= 12) {
+            set(HOUR, hour + offset);
+        }
+        return true;
+    }
+
+    private boolean patchResult(final boolean strict) {
+        // sanity checks - make sure we have something
+        if (!isSet(YEAR) && !isSet(HOUR)) {
+            return false;
+        }
+        if (isSet(HOUR) && !isSet(MINUTE)) {
+            return false;
+        }
+        // fill in default values for unset fields except timezone
+        for (int field = YEAR; field <= TIMEZONE; field++) {
+            if (get(field) == null) {
+                if (field == TIMEZONE && !strict) {
+                    // We only use UTC as default timezone for dates parsed complying with
+                    // the format specified in ES5 15.9.1.15. Otherwise the slot is left empty
+                    // and local timezone is used.
+                    continue;
+                }
+                final int value = getDefaultValue(field);
+                set(field, value);
+            }
+        }
+
+        if (!strict) {
+            // swap year, month, and day if it looks like the right thing to do
+            if (isDay(get(YEAR))) {
+                final int d = get(YEAR);
+                set(YEAR, get(DAY));
+                if (namedMonth) {
+                    // d-m-y
+                    set(DAY, d);
+                } else {
+                    // m-d-y
+                    final int d2 = get(MONTH);
+                    set(MONTH, d);
+                    set(DAY, d2);
+                }
+            }
+            // sanity checks now that we know what's what
+            if (!isMonth(get(MONTH)) || !isDay(get(DAY))) {
+                return false;
+            }
+
+            // add 1900 or 2000 to year if it's between 0 and 100
+            final int year = get(YEAR);
+            if (year >= 0 && year < 100) {
+                set(YEAR, year >= 50 ? 1900 + year : 2000 + year);
+            }
+        } else {
+            // 24 hour value is only allowed if all other time values are zero
+            if (get(HOUR) == 24 &&
+                    (get(MINUTE) != 0 || get(SECOND) != 0 || get(MILLISECOND) != 0)) {
+                return false;
+            }
+        }
+
+        // set month to 0-based
+        set(MONTH, get(MONTH) - 1);
+        return true;
+    }
+
+    private static void addName(final String str, final int type, final int value) {
+        final Name name = new Name(str, type, value);
+        names.put(name.key, name);
+    }
+
+    private static class Name {
+        final String name;
+        final String key;
+        final int value;
+        final int type;
+
+        final static int DAY_OF_WEEK    = -1;
+        final static int MONTH_NAME     = 0;
+        final static int AM_PM          = 1;
+        final static int TIMEZONE_ID    = 2;
+        final static int TIME_SEPARATOR = 3;
+
+        Name(final String name, final int type, final int value) {
+            assert name != null;
+            assert name.equals(name.toLowerCase());
+
+            this.name = name;
+            // use first three characters as lookup key
+            this.key = name.substring(0, Math.min(3, name.length()));
+            this.type = type;
+            this.value = value;
+        }
+
+        public boolean matches(final String str, final int offset, final int len) {
+            return name.regionMatches(true, 0, str, offset, len);
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java b/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java
new file mode 100644
index 0000000..f76f7f1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java
@@ -0,0 +1,169 @@
+/*
+ * 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.objects;
+
+import java.util.Objects;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Generic Property descriptor is used to represent attributes an object property
+ * that is neither a data property descriptor nor an accessor property descriptor.
+ *
+ * See ECMA 8.10 The Property Descriptor and Property Identifier Specification Types
+ *
+ */
+@ScriptClass("GenericPropertyDescriptor")
+public final class GenericPropertyDescriptor extends ScriptObject implements PropertyDescriptor {
+    /** Is the property configurable? */
+    @Property
+    public Object configurable;
+
+    /** Is the property writable? */
+    @Property
+    public Object enumerable;
+
+    GenericPropertyDescriptor() {
+        this(false, false);
+    }
+
+    GenericPropertyDescriptor(final boolean configurable, final boolean enumerable) {
+        this.configurable = configurable;
+        this.enumerable   = enumerable;
+        setProto(Global.objectPrototype());
+    }
+
+    @Override
+    public boolean isConfigurable() {
+        return JSType.toBoolean(configurable);
+    }
+
+    @Override
+    public boolean isEnumerable() {
+        return JSType.toBoolean(enumerable);
+    }
+
+    @Override
+    public boolean isWritable() {
+        // Not applicable for this. But simplifies flag calculations.
+        return false;
+    }
+
+    @Override
+    public Object getValue() {
+        throw new UnsupportedOperationException("value");
+    }
+
+    @Override
+    public ScriptFunction getGetter() {
+        throw new UnsupportedOperationException("get");
+    }
+
+    @Override
+    public ScriptFunction getSetter() {
+        throw new UnsupportedOperationException("set");
+    }
+
+    @Override
+    public void setConfigurable(final boolean flag) {
+        this.configurable = flag;
+    }
+
+    @Override
+    public void setEnumerable(final boolean flag) {
+        this.enumerable = flag;
+    }
+
+    @Override
+    public void setWritable(final boolean flag) {
+        throw new UnsupportedOperationException("set writable");
+    }
+
+    @Override
+    public void setValue(final Object value) {
+        throw new UnsupportedOperationException("set value");
+    }
+
+    @Override
+    public void setGetter(final Object getter) {
+        throw new UnsupportedOperationException("set getter");
+    }
+
+    @Override
+    public void setSetter(final Object setter) {
+        throw new UnsupportedOperationException("set setter");
+    }
+
+    @Override
+    public PropertyDescriptor fillFrom(final ScriptObject sobj) {
+        final boolean strict = isStrictContext();
+        if (sobj.has(CONFIGURABLE)) {
+            this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
+        } else {
+            delete(CONFIGURABLE, strict);
+        }
+
+        if (sobj.has(ENUMERABLE)) {
+            this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
+        } else {
+            delete(ENUMERABLE, strict);
+        }
+
+        return this;
+    }
+
+    @Override
+    public int type() {
+        return GENERIC;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof AccessorPropertyDescriptor)) {
+            return false;
+        }
+
+        final AccessorPropertyDescriptor other = (AccessorPropertyDescriptor)obj;
+        return ScriptRuntime.sameValue(configurable, other.configurable) &&
+               ScriptRuntime.sameValue(enumerable, other.enumerable);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 97 * hash + Objects.hashCode(this.configurable);
+        hash = 97 * hash + Objects.hashCode(this.enumerable);
+        return hash;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java
new file mode 100644
index 0000000..b89d207
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java
@@ -0,0 +1,1730 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.ref.SoftReference;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.GlobalFunctions;
+import jdk.nashorn.internal.runtime.GlobalObject;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.NativeJavaPackage;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+import jdk.nashorn.internal.runtime.Scope;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.ScriptingFunctions;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.linker.InvokeByName;
+import jdk.nashorn.internal.scripts.JO;
+
+/**
+ * Representation of global scope.
+ */
+@ScriptClass("Global")
+public final class Global extends ScriptObject implements GlobalObject, Scope {
+    private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
+    private static final InvokeByName VALUE_OF  = new InvokeByName("valueOf",  ScriptObject.class);
+
+    /** ECMA 15.1.2.2 parseInt (string , radix) */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object parseInt;
+
+    /** ECMA 15.1.2.3 parseFloat (string) */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object parseFloat;
+
+    /** ECMA 15.1.2.4 isNaN (number) */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object isNaN;
+
+    /** ECMA 15.1.2.5 isFinite (number) */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object isFinite;
+
+    /** ECMA 15.1.3.3 encodeURI */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object encodeURI;
+
+    /** ECMA 15.1.3.4 encodeURIComponent */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object encodeURIComponent;
+
+    /** ECMA 15.1.3.1 decodeURI */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object decodeURI;
+
+    /** ECMA 15.1.3.2 decodeURIComponent */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object decodeURIComponent;
+
+    /** ECMA B.2.1 escape (string) */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object escape;
+
+    /** ECMA B.2.2 unescape (string) */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object unescape;
+
+    /** Nashorn extension: global.print */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object print;
+
+    /** Nashorn extension: global.load */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object load;
+
+    /** Nashorn extension: global.exit */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object exit;
+
+    /** Nashorn extension: global.quit */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object quit;
+
+    /** Value property NaN of the Global Object - ECMA 15.1.1.1 NaN */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public final Object NaN = Double.NaN;
+
+    /** Value property Infinity of the Global Object - ECMA 15.1.1.2 Infinity */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public final Object Infinity = Double.POSITIVE_INFINITY;
+
+    /** Value property Undefined of the Global Object - ECMA 15.1.1.3 Undefined */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public final Object undefined = UNDEFINED;
+
+    /** ECMA 15.1.2.1 eval(x) */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object eval;
+
+    /** ECMA 15.1.4.1 Object constructor. */
+    @Property(name = "Object", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object object;
+
+    /** ECMA 15.1.4.2 Function constructor. */
+    @Property(name = "Function", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object function;
+
+    /** ECMA 15.1.4.3 Array constructor. */
+    @Property(name = "Array", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object array;
+
+    /** ECMA 15.1.4.4 String constructor */
+    @Property(name = "String", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object string;
+
+    /** ECMA 15.1.4.5 Boolean constructor */
+    @Property(name = "Boolean", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object _boolean;
+
+    /** ECMA 15.1.4.6 - Number constructor */
+    @Property(name = "Number", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object number;
+
+    /** ECMA 15.1.4.7 Date constructor */
+    @Property(name = "Date", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object date;
+
+    /** ECMA 15.1.4.8 RegExp constructor */
+    @Property(name = "RegExp", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object regexp;
+
+    /** ECMA 15.12 - The JSON object */
+    @Property(name = "JSON", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object json;
+
+    /** Nashorn extension: global.JSAdapter */
+    @Property(name = "JSAdapter", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object jsadapter;
+
+    /** ECMA 15.8 - The Math object */
+    @Property(name = "Math", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object math;
+
+    /** Error object */
+    @Property(name = "Error", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object error;
+
+    /** EvalError object */
+    @Property(name = "EvalError", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object evalError;
+
+    /** RangeError object */
+    @Property(name = "RangeError", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object rangeError;
+
+    /** ReferenceError object */
+    @Property(name = "ReferenceError", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object referenceError;
+
+    /** SyntaxError object */
+    @Property(name = "SyntaxError", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object syntaxError;
+
+    /** TypeError object */
+    @Property(name = "TypeError", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object typeError;
+
+    /** URIError object */
+    @Property(name = "URIError", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object uriError;
+
+    /** ArrayBuffer object */
+    @Property(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object arrayBuffer;
+
+    /** TypedArray (int8) */
+    @Property(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object int8Array;
+
+    /** TypedArray (uint8) */
+    @Property(name = "Uint8Array", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object uint8Array;
+
+    /** TypedArray (uint8) - Clamped */
+    @Property(name = "Uint8ClampedArray", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object uint8ClampedArray;
+
+    /** TypedArray (int16) */
+    @Property(name = "Int16Array", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object int16Array;
+
+    /** TypedArray (uint16) */
+    @Property(name = "Uint16Array", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object uint16Array;
+
+    /** TypedArray (int32) */
+    @Property(name = "Int32Array", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object int32Array;
+
+    /** TypedArray (uint32) */
+    @Property(name = "Uint32Array", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object uint32Array;
+
+    /** TypedArray (float32) */
+    @Property(name = "Float32Array", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object float32Array;
+
+    /** TypedArray (float64) */
+    @Property(name = "Float64Array", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object float64Array;
+
+    /** Nashorn extension: Java access - global.Packages */
+    @Property(name = "Packages", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object packages;
+
+    /** Nashorn extension: Java access - global.java */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object java;
+
+    /** Nashorn extension: Java access - global.javax */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object javax;
+
+    /** Nashorn extension: Java access - global.javaImporter */
+    @Property(name = "JavaImporter", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object javaImporter;
+
+    /** Nashorn extension: global.Java Object constructor. */
+    @Property(name = "Java", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object javaApi;
+
+    /** Nashorn extension: current script's file name */
+    @Property(name = "__FILE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public Object __FILE__;
+
+    /** Nashorn extension: current script's directory */
+    @Property(name = "__DIR__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public Object __DIR__;
+
+    /** Nashorn extension: current source line number being executed */
+    @Property(name = "__LINE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public Object __LINE__;
+
+    /** Used as Date.prototype's default value */
+    public NativeDate   DEFAULT_DATE;
+
+    /** Used as RegExp.prototype's default value */
+    public NativeRegExp DEFAULT_REGEXP;
+
+    /*
+     * Built-in constructor objects: Even if user changes dynamic values of
+     * "Object", "Array" etc., we still want to keep original values of these
+     * constructors here. For example, we need to be able to create array,
+     * regexp literals even after user overwrites global "Array" or "RegExp"
+     * constructor - see also ECMA 262 spec. Annex D.
+     */
+    private ScriptFunction builtinFunction;
+    private ScriptFunction builtinObject;
+    private ScriptFunction builtinArray;
+    private ScriptFunction builtinBoolean;
+    private ScriptFunction builtinDate;
+    private ScriptObject   builtinJSON;
+    private ScriptFunction builtinJSAdapter;
+    private ScriptObject   builtinMath;
+    private ScriptFunction builtinNumber;
+    private ScriptFunction builtinRegExp;
+    private ScriptFunction builtinString;
+    private ScriptFunction builtinError;
+    private ScriptFunction builtinEval;
+    private ScriptFunction builtinEvalError;
+    private ScriptFunction builtinRangeError;
+    private ScriptFunction builtinReferenceError;
+    private ScriptFunction builtinSyntaxError;
+    private ScriptFunction builtinTypeError;
+    private ScriptFunction builtinURIError;
+    private ScriptObject   builtinPackages;
+    private ScriptObject   builtinJava;
+    private ScriptObject   builtinJavax;
+    private ScriptObject   builtinJavaImporter;
+    private ScriptObject   builtinJavaApi;
+    private ScriptObject   builtinArrayBuffer;
+    private ScriptObject   builtinInt8Array;
+    private ScriptObject   builtinUint8Array;
+    private ScriptObject   builtinUint8ClampedArray;
+    private ScriptObject   builtinInt16Array;
+    private ScriptObject   builtinUint16Array;
+    private ScriptObject   builtinInt32Array;
+    private ScriptObject   builtinUint32Array;
+    private ScriptObject   builtinFloat32Array;
+    private ScriptObject   builtinFloat64Array;
+
+    // Flag to indicate that a split method issued a return statement
+    private int splitState = -1;
+
+    // class cache
+    private ClassCache classCache;
+
+    // Used to store the last RegExp result to support deprecated RegExp constructor properties
+    private RegExpResult lastRegExpResult;
+
+    private static final MethodHandle EVAL    = findOwnMH("eval",    Object.class, Object.class, Object.class);
+    private static final MethodHandle PRINT   = findOwnMH("print",   Object.class, Object.class, Object[].class);
+    private static final MethodHandle PRINTLN = findOwnMH("println", Object.class, Object.class, Object[].class);
+    private static final MethodHandle LOAD    = findOwnMH("load",    Object.class, Object.class, Object.class);
+    private static final MethodHandle EXIT    = findOwnMH("exit",    Object.class, Object.class, Object.class);
+
+    private final Context context;
+
+    /**
+     * Constructor
+     *
+     * @param context the context
+     */
+    public Global(final Context context) {
+        this.context = context;
+        this.setIsScope();
+        /*
+         * Duplicate global's map and use it. This way the initial Map filled
+         * by nasgen (referenced from static field in this class) is retained
+         * 'as is'. This allows multiple globals to be used within a context.
+         */
+        this.setMap(getMap().duplicate());
+
+        final int cacheSize = context.getEnv()._class_cache_size;
+        if (cacheSize > 0) {
+            classCache = new ClassCache(cacheSize);
+        }
+    }
+
+    /**
+     * Script access to "current" Global instance
+     *
+     * @return the global singleton
+     */
+    public static Global instance() {
+        ScriptObject global = Context.getGlobal();
+        if (! (global instanceof Global)) {
+            throw new IllegalStateException("no current global instance");
+        }
+        return (Global)global;
+    }
+
+    /**
+     * Script access to {@link ScriptEnvironment}
+     *
+     * @return the script environment
+     */
+    static ScriptEnvironment getEnv() {
+        return instance().context.getEnv();
+    }
+
+    /**
+     * Script access to {@link Context}
+     *
+     * @return the context
+     */
+    static Context getThisContext() {
+        return instance().context;
+    }
+
+    /**
+     * Script access check for strict mode
+     *
+     * @return true if strict mode enabled in {@link Global#getThisContext()}
+     */
+    static boolean isStrict() {
+        return getEnv()._strict;
+    }
+
+    // GlobalObject interface implementation
+
+    @Override
+    public void initBuiltinObjects() {
+        if (this.builtinObject != null) {
+            // already initialized, just return
+            return;
+        }
+
+        init();
+    }
+
+    @Override
+    public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
+        return new ScriptFunctionImpl(name, handle, scope, null, strict, false, true);
+    }
+
+    @Override
+    public Object wrapAsObject(final Object obj) {
+        if (obj instanceof Boolean) {
+            return new NativeBoolean((Boolean)obj);
+        } else if (obj instanceof Number) {
+            return new NativeNumber(((Number)obj).doubleValue());
+        } else if (obj instanceof String || obj instanceof ConsString) {
+            return new NativeString((CharSequence)obj);
+        } else if (obj instanceof Object[]) { // extension
+            return new NativeArray((Object[])obj);
+        } else if (obj instanceof double[]) { // extension
+            return new NativeArray((double[])obj);
+        } else if (obj instanceof long[]) {
+            return new NativeArray((long[])obj);
+        } else if (obj instanceof int[]) {
+            return new NativeArray((int[])obj);
+        } else {
+            // FIXME: more special cases? Map? List?
+            return obj;
+        }
+    }
+
+    @Override
+    public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
+        if (self instanceof String || self instanceof ConsString) {
+            return NativeString.lookupPrimitive(request, self);
+        } else if (self instanceof Number) {
+            return NativeNumber.lookupPrimitive(request, self);
+        } else if (self instanceof Boolean) {
+            return NativeBoolean.lookupPrimitive(request, self);
+        }
+        throw new IllegalArgumentException("Unsupported primitive: " + self);
+    }
+
+    @Override
+    public ScriptObject newObject() {
+        return newEmptyInstance();
+    }
+
+    @Override
+    public Object getDefaultValue(final ScriptObject sobj, final Class<?> typeHint) {
+        // When the [[DefaultValue]] internal method of O is called with no hint,
+        // then it behaves as if the hint were Number, unless O is a Date object
+        // in which case it behaves as if the hint were String.
+        Class<?> hint = typeHint;
+        if (hint == null) {
+            hint = Number.class;
+        }
+
+        try {
+            if (hint == String.class) {
+
+                final Object toString = TO_STRING.getGetter().invokeExact(sobj);
+                if (toString instanceof ScriptFunction) {
+                    final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
+                    if (JSType.isPrimitive(value)) {
+                        return value;
+                    }
+                }
+
+                final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
+                if (valueOf instanceof ScriptFunction) {
+                    final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
+                    if (JSType.isPrimitive(value)) {
+                        return value;
+                    }
+                }
+                throw typeError(this, "cannot.get.default.string");
+            }
+
+            if (hint == Number.class) {
+                final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
+                if (valueOf instanceof ScriptFunction) {
+                    final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
+                    if (JSType.isPrimitive(value)) {
+                        return value;
+                    }
+                }
+
+                final Object toString = TO_STRING.getGetter().invokeExact(sobj);
+                if (toString instanceof ScriptFunction) {
+                    final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
+                    if (JSType.isPrimitive(value)) {
+                        return value;
+                    }
+                }
+
+                throw typeError(this, "cannot.get.default.number");
+            }
+        } catch (final RuntimeException | Error e) {
+            throw e;
+        } catch (final Throwable t) {
+            throw new RuntimeException(t);
+        }
+
+        return UNDEFINED;
+    }
+
+    @Override
+    public boolean isError(final ScriptObject sobj) {
+        final ScriptObject errorProto = getErrorPrototype();
+        ScriptObject proto = sobj.getProto();
+        while (proto != null) {
+            if (proto == errorProto) {
+                return true;
+            }
+            proto = proto.getProto();
+        }
+        return false;
+    }
+
+    @Override
+    public ScriptObject newError(final String msg) {
+        return new NativeError(msg);
+    }
+
+    @Override
+    public ScriptObject newEvalError(final String msg) {
+        return new NativeEvalError(msg);
+    }
+
+    @Override
+    public ScriptObject newRangeError(final String msg) {
+        return new NativeRangeError(msg);
+    }
+
+    @Override
+    public ScriptObject newReferenceError(final String msg) {
+        return new NativeReferenceError(msg);
+    }
+
+    @Override
+    public ScriptObject newSyntaxError(final String msg) {
+        return new NativeSyntaxError(msg);
+    }
+
+    @Override
+    public ScriptObject newTypeError(final String msg) {
+        return new NativeTypeError(msg);
+    }
+
+    @Override
+    public ScriptObject newURIError(final String msg) {
+        return new NativeURIError(msg);
+    }
+
+    @Override
+    public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
+        return new GenericPropertyDescriptor(configurable, enumerable);
+    }
+
+    @Override
+    public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
+        return new DataPropertyDescriptor(configurable, enumerable, writable, value);
+    }
+
+    @Override
+    public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
+        final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set);
+
+        final boolean strict = context.getEnv()._strict;
+
+        if (get == null) {
+            desc.delete(PropertyDescriptor.GET, strict);
+        }
+
+        if (set == null) {
+            desc.delete(PropertyDescriptor.SET, strict);
+        }
+
+        return desc;
+    }
+
+
+    /**
+     * Cache for compiled script classes.
+     */
+    @SuppressWarnings("serial")
+    private static class ClassCache extends LinkedHashMap<Source, SoftReference<Class<?>>> {
+        private final int size;
+
+        ClassCache(int size) {
+            super(size, 0.75f, true);
+            this.size = size;
+        }
+
+        @Override
+        protected boolean removeEldestEntry(final Map.Entry<Source, SoftReference<Class<?>>> eldest) {
+            return size() >= size;
+        }
+    }
+
+    // Class cache management
+    @Override
+    public Class<?> findCachedClass(final Source source) {
+        assert classCache != null : "Class cache used without being initialized";
+        SoftReference<Class<?>> ref = classCache.get(source);
+        if (ref != null) {
+            final Class<?> clazz = ref.get();
+            if (clazz == null) {
+                classCache.remove(source);
+            }
+            return clazz;
+        }
+
+        return null;
+    }
+
+    @Override
+    public void cacheClass(final Source source, final Class<?> clazz) {
+        assert classCache != null : "Class cache used without being initialized";
+        classCache.put(source, new SoftReference<Class<?>>(clazz));
+    }
+
+    /**
+     * This is the eval used when 'indirect' eval call is made.
+     *
+     * var global = this;
+     * global.eval("print('hello')");
+     *
+     * @param self  eval scope
+     * @param str   eval string
+     *
+     * @return the result of eval
+     */
+    public static Object eval(final Object self, final Object str) {
+        return directEval(self, str, UNDEFINED, UNDEFINED, UNDEFINED);
+    }
+
+    /**
+     * Direct eval
+     *
+     * @param self     The scope of eval passed as 'self'
+     * @param str      Evaluated code
+     * @param callThis "this" to be passed to the evaluated code
+     * @param location location of the eval call
+     * @param strict   is eval called a strict mode code?
+     *
+     * @return the return value of the eval
+     *
+     * This is directly invoked from generated when eval(code) is called in user code
+     */
+    public static Object directEval(final Object self, final Object str, final Object callThis, final Object location, final Object strict) {
+        if (!(str instanceof String || str instanceof ConsString)) {
+            return str;
+        }
+        final Global global = Global.instance();
+        final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
+
+        return global.context.eval(scope, str.toString(), callThis, location, Boolean.TRUE.equals(strict));
+    }
+
+    /**
+     * Global print implementation - Nashorn extension
+     *
+     * @param self    scope
+     * @param objects arguments to print
+     *
+     * @return result of print (undefined)
+     */
+    public static Object print(final Object self, final Object... objects) {
+        return printImpl(false, objects);
+    }
+
+    /**
+     * Global println implementation - Nashorn extension
+     *
+     * @param self    scope
+     * @param objects arguments to print
+     *
+     * @return result of println (undefined)
+     */
+    public static Object println(final Object self, final Object... objects) {
+        return printImpl(true, objects);
+    }
+
+    /**
+     * Global load implementation - Nashorn extension
+     *
+     * @param self    scope
+     * @param source  source to load
+     *
+     * @return result of load (undefined)
+     *
+     * @throws IOException if source could not be read
+     */
+    public static Object load(final Object self, final Object source) throws IOException {
+        final Global global = Global.instance();
+        final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
+        return global.context.load(scope, source);
+    }
+
+    /**
+     * Global exit and quit implementation - Nashorn extension: perform a {@code System.exit} call from the script
+     *
+     * @param self  self reference
+     * @param code  exit code
+     *
+     * @return undefined (will never be reacheD)
+     */
+    public static Object exit(final Object self, final Object code) {
+        System.exit(JSType.toInt32(code));
+        return UNDEFINED;
+    }
+
+    ScriptObject getFunctionPrototype() {
+        return ScriptFunction.getPrototype(builtinFunction);
+    }
+
+    ScriptObject getObjectPrototype() {
+        return ScriptFunction.getPrototype(builtinObject);
+    }
+
+    ScriptObject getArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinArray);
+    }
+
+    ScriptObject getBooleanPrototype() {
+        return ScriptFunction.getPrototype(builtinBoolean);
+    }
+
+    ScriptObject getNumberPrototype() {
+        return ScriptFunction.getPrototype(builtinNumber);
+    }
+
+    ScriptObject getDatePrototype() {
+        return ScriptFunction.getPrototype(builtinDate);
+    }
+
+    ScriptObject getRegExpPrototype() {
+        return ScriptFunction.getPrototype(builtinRegExp);
+    }
+
+    ScriptObject getStringPrototype() {
+        return ScriptFunction.getPrototype(builtinString);
+    }
+
+    ScriptObject getErrorPrototype() {
+        return ScriptFunction.getPrototype(builtinError);
+    }
+
+    ScriptObject getEvalErrorPrototype() {
+        return ScriptFunction.getPrototype(builtinEvalError);
+    }
+
+    ScriptObject getRangeErrorPrototype() {
+        return ScriptFunction.getPrototype(builtinRangeError);
+    }
+
+    ScriptObject getReferenceErrorPrototype() {
+        return ScriptFunction.getPrototype(builtinReferenceError);
+    }
+
+    ScriptObject getSyntaxErrorPrototype() {
+        return ScriptFunction.getPrototype(builtinSyntaxError);
+    }
+
+    ScriptObject getTypeErrorPrototype() {
+        return ScriptFunction.getPrototype(builtinTypeError);
+    }
+
+    ScriptObject getURIErrorPrototype() {
+        return ScriptFunction.getPrototype(builtinURIError);
+    }
+
+    ScriptObject getJavaImporterPrototype() {
+        return ScriptFunction.getPrototype(builtinJavaImporter);
+    }
+
+    ScriptObject getJSAdapterPrototype() {
+        return ScriptFunction.getPrototype(builtinJSAdapter);
+    }
+
+    ScriptObject getArrayBufferPrototype() {
+        return ScriptFunction.getPrototype(builtinArrayBuffer);
+    }
+
+    ScriptObject getInt8ArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinInt8Array);
+    }
+
+    ScriptObject getUint8ArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinUint8Array);
+    }
+
+    ScriptObject getUint8ClampedArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinUint8ClampedArray);
+    }
+
+    ScriptObject getInt16ArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinInt16Array);
+    }
+
+    ScriptObject getUint16ArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinUint16Array);
+    }
+
+    ScriptObject getInt32ArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinInt32Array);
+    }
+
+    ScriptObject getUint32ArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinUint32Array);
+    }
+
+    ScriptObject getFloat32ArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinFloat32Array);
+    }
+
+    ScriptObject getFloat64ArrayPrototype() {
+        return ScriptFunction.getPrototype(builtinFloat64Array);
+    }
+
+    private ScriptFunction getBuiltinArray() {
+        return builtinArray;
+    }
+
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin array has not been overridden
+     */
+    public static boolean isBuiltinArray() {
+        final Global instance = Global.instance();
+        return instance.array == instance.getBuiltinArray();
+    }
+
+    private ScriptFunction getBuiltinBoolean() {
+        return builtinBoolean;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin boolean has not been overridden
+     */
+    public static boolean isBuiltinBoolean() {
+        final Global instance = Global.instance();
+        return instance._boolean == instance.getBuiltinBoolean();
+    }
+
+    private ScriptFunction getBuiltinDate() {
+        return builtinDate;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin date has not been overridden
+     */
+    public static boolean isBuiltinDate() {
+        final Global instance = Global.instance();
+        return instance.date == instance.getBuiltinDate();
+    }
+
+    private ScriptFunction getBuiltinError() {
+        return builtinError;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin error has not been overridden
+     */
+    public static boolean isBuiltinError() {
+        final Global instance = Global.instance();
+        return instance.error == instance.getBuiltinError();
+    }
+
+    private ScriptFunction getBuiltinEvalError() {
+        return builtinEvalError;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin eval error has not been overridden
+     */
+    public static boolean isBuiltinEvalError() {
+        final Global instance = Global.instance();
+        return instance.evalError == instance.getBuiltinEvalError();
+    }
+
+    private ScriptFunction getBuiltinFunction() {
+        return builtinFunction;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin function has not been overridden
+     */
+    public static boolean isBuiltinFunction() {
+        final Global instance = Global.instance();
+        return instance.function == instance.getBuiltinFunction();
+    }
+
+    private ScriptFunction getBuiltinJSAdapter() {
+        return builtinJSAdapter;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin JSAdapter has not been overridden
+     */
+    public static boolean isBuiltinJSAdapter() {
+        final Global instance = Global.instance();
+        return instance.jsadapter == instance.getBuiltinJSAdapter();
+    }
+
+    private ScriptObject getBuiltinJSON() {
+        return builtinJSON;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin JSON has has not been overridden
+     */
+    public static boolean isBuiltinJSON() {
+        final Global instance = Global.instance();
+        return instance.json == instance.getBuiltinJSON();
+    }
+
+    private ScriptObject getBuiltinJava() {
+        return builtinJava;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin Java has not been overridden
+     */
+    public static boolean isBuiltinJava() {
+        final Global instance = Global.instance();
+        return instance.java == instance.getBuiltinJava();
+    }
+
+    private ScriptObject getBuiltinJavax() {
+        return builtinJavax;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin Javax has not been overridden
+     */
+    public static boolean isBuiltinJavax() {
+        final Global instance = Global.instance();
+        return instance.javax == instance.getBuiltinJavax();
+    }
+
+    private ScriptObject getBuiltinJavaImporter() {
+        return builtinJavaImporter;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin Java importer has not been overridden
+     */
+    public static boolean isBuiltinJavaImporter() {
+        final Global instance = Global.instance();
+        return instance.javaImporter == instance.getBuiltinJavaImporter();
+    }
+
+    private ScriptObject getBuiltinMath() {
+        return builtinMath;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin math has not been overridden
+     */
+    public static boolean isBuiltinMath() {
+        final Global instance = Global.instance();
+        return instance.math == instance.getBuiltinMath();
+    }
+
+    private ScriptFunction getBuiltinNumber() {
+        return builtinNumber;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin number has not been overridden
+     */
+    public static boolean isBuiltinNumber() {
+        final Global instance = Global.instance();
+        return instance.number == instance.getBuiltinNumber();
+    }
+
+    private ScriptFunction getBuiltinObject() {
+        return builtinObject;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin object has not been overridden
+     */
+    public static boolean isBuiltinObject() {
+        final Global instance = Global.instance();
+        return instance.object == instance.getBuiltinObject();
+    }
+
+    private ScriptObject getBuiltinPackages() {
+        return builtinPackages;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin package has not been overridden
+     */
+    public static boolean isBuiltinPackages() {
+        final Global instance = Global.instance();
+        return instance.packages == instance.getBuiltinPackages();
+    }
+
+    private ScriptFunction getBuiltinRangeError() {
+        return builtinRangeError;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin range error has not been overridden
+     */
+    public static boolean isBuiltinRangeError() {
+        final Global instance = Global.instance();
+        return instance.rangeError == instance.getBuiltinRangeError();
+    }
+
+    private ScriptFunction getBuiltinReferenceError() {
+        return builtinReferenceError;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin reference error has not been overridden
+     */
+    public static boolean isBuiltinReferenceError() {
+        final Global instance = Global.instance();
+        return instance.referenceError == instance.getBuiltinReferenceError();
+    }
+
+    private ScriptFunction getBuiltinRegExp() {
+        return builtinRegExp;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin regexp has not been overridden
+     */
+    public static boolean isBuiltinRegExp() {
+        final Global instance = Global.instance();
+        return instance.regexp == instance.getBuiltinRegExp();
+    }
+
+    private ScriptFunction getBuiltinString() {
+        return builtinString;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin Java has not been overridden
+     */
+    public static boolean isBuiltinString() {
+        final Global instance = Global.instance();
+        return instance.string == instance.getBuiltinString();
+    }
+
+    private ScriptFunction getBuiltinSyntaxError() {
+        return builtinSyntaxError;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin syntax error has not been overridden
+     */
+    public static boolean isBuiltinSyntaxError() {
+        final Global instance = Global.instance();
+        return instance.syntaxError == instance.getBuiltinSyntaxError();
+    }
+
+    private ScriptFunction getBuiltinTypeError() {
+        return builtinTypeError;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin type error has not been overridden
+     */
+    public static boolean isBuiltinTypeError() {
+        final Global instance = Global.instance();
+        return instance.typeError == instance.getBuiltinTypeError();
+    }
+
+    private ScriptFunction getBuiltinURIError() {
+        return builtinURIError;
+    }
+
+    /**
+     * Called from compiled script code to test if builtin has been overridden
+     *
+     * @return true if builtin URI error has not been overridden
+     */
+    public static boolean isBuiltinURIError() {
+        final Global instance = Global.instance();
+        return instance.uriError == instance.getBuiltinURIError();
+    }
+
+    @Override
+    public String getClassName() {
+        return "global";
+    }
+
+    /**
+     * Copy function used to clone NativeRegExp objects.
+     *
+     * @param regexp a NativeRegExp to clone
+     *
+     * @return copy of the given regexp object
+     */
+    public static Object regExpCopy(final Object regexp) {
+        return new NativeRegExp((NativeRegExp)regexp);
+    }
+
+    /**
+     * Convert given object to NativeRegExp type.
+     *
+     * @param obj object to be converted
+     * @return NativeRegExp instance
+     */
+    public static NativeRegExp toRegExp(final Object obj) {
+        if (obj instanceof NativeRegExp) {
+            return (NativeRegExp)obj;
+        }
+        return new NativeRegExp(JSType.toString(obj));
+    }
+
+    /**
+     * ECMA 9.9 ToObject implementation
+     *
+     * @param obj  an item for which to run ToObject
+     * @return ToObject version of given item
+     */
+    public static Object toObject(final Object obj) {
+        if (obj == null || obj == UNDEFINED) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
+        }
+
+        if (obj instanceof ScriptObject) {
+            return obj;
+        }
+
+        return instance().wrapAsObject(obj);
+    }
+
+    /**
+     * Allocate a new object array.
+     *
+     * @param initial object values.
+     * @return the new array
+     */
+    public static NativeArray allocate(final Object[] initial) {
+        return new NativeArray(initial);
+    }
+
+    /**
+     * Allocate a new number array.
+     *
+     * @param initial number values.
+     * @return the new array
+     */
+    public static NativeArray allocate(final double[] initial) {
+        return new NativeArray(initial);
+    }
+
+    /**
+     * Allocate a new long array.
+     *
+     * @param initial number values.
+     * @return the new array
+     */
+    public static NativeArray allocate(final long[] initial) {
+        return new NativeArray(initial);
+    }
+
+    /**
+     * Allocate a new integer array.
+     *
+     * @param initial number values.
+     * @return the new array
+     */
+    public static NativeArray allocate(final int[] initial) {
+        return new NativeArray(initial);
+    }
+
+    /**
+     * Allocate a new object array for arguments.
+     *
+     * @param arguments initial arguments passed.
+     * @param callee reference to the function that uses arguments object
+     * @param numParams actual number of declared parameters
+     *
+     * @return the new array
+     */
+    public static ScriptObject allocateArguments(final Object[] arguments, final Object callee, final int numParams) {
+        return NativeArguments.allocate(arguments, (ScriptFunction)callee, numParams);
+    }
+
+    /**
+     * Called from generated to check if given function is the builtin 'eval'. If
+     * eval is used in a script, a lot of optimizations and assumptions cannot be done.
+     *
+     * @param  fn function object that is checked
+     * @return true if fn is the builtin eval
+     */
+    public static boolean isEval(final Object fn) {
+        return fn == Global.instance().builtinEval;
+    }
+
+    /**
+     * Create a new RegExp object.
+     *
+     * @param expression Regular expression.
+     * @param options    Search options.
+     *
+     * @return New RegExp object.
+     */
+    public static Object newRegExp(final String expression, final String options) {
+        if (options == null) {
+            return new NativeRegExp(expression);
+        }
+        return new NativeRegExp(expression, options);
+    }
+
+    /**
+     * Get the object prototype
+     *
+     * @return the object prototype
+     */
+    public static ScriptObject objectPrototype() {
+        return Global.instance().getObjectPrototype();
+    }
+
+    /**
+     * Create a new empty object instance.
+     *
+     * @return New empty object.
+     */
+    public static ScriptObject newEmptyInstance() {
+        final ScriptObject sobj = new JO();
+        sobj.setProto(objectPrototype());
+        return sobj;
+    }
+
+    /**
+     * Check if a given object is a ScriptObject, raises an exception if this is
+     * not the case
+     *
+     * @param obj and object to check
+     */
+    public static void checkObject(final Object obj) {
+        if (!(obj instanceof ScriptObject)) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
+        }
+    }
+
+    /**
+     * ECMA 9.10 - implementation of CheckObjectCoercible, i.e. raise an exception
+     * if this object is null or undefined.
+     *
+     * @param obj an object to check
+     */
+    public static void checkObjectCoercible(final Object obj) {
+        if (obj == null || obj == UNDEFINED) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
+        }
+    }
+
+    /**
+     * Get the current split state.
+     *
+     * @return current split state
+     */
+    @Override
+    public int getSplitState() {
+        return splitState;
+    }
+
+    /**
+     * Set the current split state.
+     *
+     * @param state current split state
+     */
+    @Override
+    public void setSplitState(final int state) {
+        splitState = state;
+    }
+
+    private void init() {
+        assert Context.getGlobal() == this : "this global is not set as current";
+
+        final ScriptEnvironment env = context.getEnv();
+        // initialize Function and Object constructor
+        initFunctionAndObject();
+
+        // Now fix Global's own proto.
+        this.setProto(getObjectPrototype());
+
+        // initialize global function properties
+        this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
+
+        this.parseInt           = ScriptFunctionImpl.makeFunction("parseInt",   GlobalFunctions.PARSEINT);
+        this.parseFloat         = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
+        this.isNaN              = ScriptFunctionImpl.makeFunction("isNaN",      GlobalFunctions.IS_NAN);
+        this.isFinite           = ScriptFunctionImpl.makeFunction("isFinite",   GlobalFunctions.IS_FINITE);
+        this.encodeURI          = ScriptFunctionImpl.makeFunction("encodeURI",  GlobalFunctions.ENCODE_URI);
+        this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
+        this.decodeURI          = ScriptFunctionImpl.makeFunction("decodeURI",  GlobalFunctions.DECODE_URI);
+        this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
+        this.escape             = ScriptFunctionImpl.makeFunction("escape",     GlobalFunctions.ESCAPE);
+        this.unescape           = ScriptFunctionImpl.makeFunction("unescape",   GlobalFunctions.UNESCAPE);
+        this.print              = ScriptFunctionImpl.makeFunction("print",      env._print_no_newline ? PRINT : PRINTLN);
+        this.load               = ScriptFunctionImpl.makeFunction("load",       LOAD);
+        this.exit               = ScriptFunctionImpl.makeFunction("exit",       EXIT);
+        this.quit               = ScriptFunctionImpl.makeFunction("quit",       EXIT);
+
+        // built-in constructors
+        this.builtinArray     = (ScriptFunction)initConstructor("Array");
+        this.builtinBoolean   = (ScriptFunction)initConstructor("Boolean");
+        this.builtinDate      = (ScriptFunction)initConstructor("Date");
+        this.builtinJSON      = initConstructor("JSON");
+        this.builtinJSAdapter = (ScriptFunction)initConstructor("JSAdapter");
+        this.builtinMath      = initConstructor("Math");
+        this.builtinNumber    = (ScriptFunction)initConstructor("Number");
+        this.builtinRegExp    = (ScriptFunction)initConstructor("RegExp");
+        this.builtinString    = (ScriptFunction)initConstructor("String");
+
+        // initialize String.prototype.length to 0
+        // add String.prototype.length
+        final ScriptObject stringPrototype = getStringPrototype();
+        stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0);
+
+        // add Array.prototype.length
+        final ScriptObject arrayPrototype = getArrayPrototype();
+        arrayPrototype.addOwnProperty("length", Attribute.NOT_ENUMERABLE|Attribute.NOT_CONFIGURABLE, 0.0);
+
+        this.DEFAULT_DATE = new NativeDate(Double.NaN);
+
+        // initialize default regexp object
+        this.DEFAULT_REGEXP = new NativeRegExp("(?:)");
+
+        // RegExp.prototype should behave like a RegExp object. So copy the
+        // properties.
+        final ScriptObject regExpProto = getRegExpPrototype();
+        regExpProto.addBoundProperties(DEFAULT_REGEXP);
+
+        // Error stuff
+        initErrorObjects();
+
+        // java access
+        initJavaAccess();
+
+        initTypedArray();
+
+        if (env._scripting) {
+            initScripting();
+        }
+
+        if (Context.DEBUG && System.getSecurityManager() == null) {
+            initDebug();
+        }
+
+        copyBuiltins();
+
+        // initialized with strings so that typeof will work as expected.
+        this.__FILE__ = "";
+        this.__DIR__  = "";
+        this.__LINE__ = 0.0;
+
+        // expose script (command line) arguments as "arguments" property of global
+        final List<String> arguments = env.getArguments();
+        final Object argsObj = wrapAsObject(arguments.toArray());
+
+        addOwnProperty("arguments", Attribute.NOT_ENUMERABLE, argsObj);
+        if (env._scripting) {
+            // synonym for "arguments" in scripting mode
+            addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, argsObj);
+        }
+    }
+
+    private void initErrorObjects() {
+        // Error objects
+        this.builtinError = (ScriptFunction)initConstructor("Error");
+        final ScriptObject errorProto = getErrorPrototype();
+        final boolean strict = Global.isStrict();
+
+        // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
+        final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK);
+        final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", NativeError.SET_STACK);
+        errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
+        final ScriptFunction getLineNumber = ScriptFunctionImpl.makeFunction("getLineNumber", NativeError.GET_LINENUMBER);
+        final ScriptFunction setLineNumber = ScriptFunctionImpl.makeFunction("setLineNumber", NativeError.SET_LINENUMBER);
+        errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber);
+        final ScriptFunction getColumnNumber = ScriptFunctionImpl.makeFunction("getColumnNumber", NativeError.GET_COLUMNNUMBER);
+        final ScriptFunction setColumnNumber = ScriptFunctionImpl.makeFunction("setColumnNumber", NativeError.SET_COLUMNNUMBER);
+        errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber);
+        final ScriptFunction getFileName = ScriptFunctionImpl.makeFunction("getFileName", NativeError.GET_FILENAME);
+        final ScriptFunction setFileName = ScriptFunctionImpl.makeFunction("setFileName", NativeError.SET_FILENAME);
+        errorProto.addOwnProperty("fileName", Attribute.NOT_ENUMERABLE, getFileName, setFileName);
+
+        // ECMA 15.11.4.2 Error.prototype.name
+        // Error.prototype.name = "Error";
+        errorProto.set(NativeError.NAME, "Error", strict);
+        // ECMA 15.11.4.3 Error.prototype.message
+        // Error.prototype.message = "";
+        errorProto.set(NativeError.MESSAGE, "", strict);
+
+        this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
+        this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
+        this.builtinReferenceError = initErrorSubtype("ReferenceError", errorProto);
+        this.builtinSyntaxError = initErrorSubtype("SyntaxError", errorProto);
+        this.builtinTypeError = initErrorSubtype("TypeError", errorProto);
+        this.builtinURIError = initErrorSubtype("URIError", errorProto);
+    }
+
+    private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
+        final ScriptObject cons = initConstructor(name);
+        final ScriptObject prototype = ScriptFunction.getPrototype(cons);
+        final boolean strict = Global.isStrict();
+        prototype.set(NativeError.NAME, name, strict);
+        prototype.set(NativeError.MESSAGE, "", strict);
+        prototype.setProto(errorProto);
+        return (ScriptFunction)cons;
+    }
+
+    private void initJavaAccess() {
+        final ScriptObject objectProto = getObjectPrototype();
+        this.builtinPackages = new NativeJavaPackage("", objectProto);
+        this.builtinJava = new NativeJavaPackage("java", objectProto);
+        this.builtinJavax = new NativeJavaPackage("javax", objectProto);
+        this.builtinJavaImporter = initConstructor("JavaImporter");
+        this.builtinJavaApi = initConstructor("Java");
+    }
+
+    private void initScripting() {
+        Object value;
+        value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE);
+        addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);
+
+        value = ScriptFunctionImpl.makeFunction("readFully", ScriptingFunctions.READFULLY);
+        addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value);
+
+        final String execName = ScriptingFunctions.EXEC_NAME;
+        value = ScriptFunctionImpl.makeFunction(execName, ScriptingFunctions.EXEC);
+        addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value);
+
+        // Nashorn extension: global.echo (scripting-mode-only)
+        // alias for "print"
+        value = get("print");
+        addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value);
+
+        // Nashorn extension: global.$OPTIONS (scripting-mode-only)
+        value = context.getEnv();
+        addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, value);
+
+        // Nashorn extension: global.$ENV (scripting-mode-only)
+        if (System.getSecurityManager() == null) {
+            // do not fill $ENV if we have a security manager around
+            // Retrieve current state of ENV variables.
+            final ScriptObject env = newEmptyInstance();
+            env.putAll(System.getenv());
+            addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env);
+        } else {
+            addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
+        }
+
+        // add other special properties for exec support
+        addOwnProperty(ScriptingFunctions.OUT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
+        addOwnProperty(ScriptingFunctions.ERR_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
+        addOwnProperty(ScriptingFunctions.EXIT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
+    }
+
+    private void initTypedArray() {
+        this.builtinArrayBuffer       = initConstructor("ArrayBuffer");
+        this.builtinInt8Array         = initConstructor("Int8Array");
+        this.builtinUint8Array        = initConstructor("Uint8Array");
+        this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray");
+        this.builtinInt16Array        = initConstructor("Int16Array");
+        this.builtinUint16Array       = initConstructor("Uint16Array");
+        this.builtinInt32Array        = initConstructor("Int32Array");
+        this.builtinUint32Array       = initConstructor("Uint32Array");
+        this.builtinFloat32Array      = initConstructor("Float32Array");
+        this.builtinFloat64Array      = initConstructor("Float64Array");
+    }
+
+    private void copyBuiltins() {
+        this.array             = this.builtinArray;
+        this._boolean          = this.builtinBoolean;
+        this.date              = this.builtinDate;
+        this.error             = this.builtinError;
+        this.evalError         = this.builtinEvalError;
+        this.function          = this.builtinFunction;
+        this.jsadapter         = this.builtinJSAdapter;
+        this.json              = this.builtinJSON;
+        this.java              = this.builtinJava;
+        this.javax             = this.builtinJavax;
+        this.javaImporter      = this.builtinJavaImporter;
+        this.javaApi           = this.builtinJavaApi;
+        this.math              = this.builtinMath;
+        this.number            = this.builtinNumber;
+        this.object            = this.builtinObject;
+        this.packages          = this.builtinPackages;
+        this.rangeError        = this.builtinRangeError;
+        this.referenceError    = this.builtinReferenceError;
+        this.regexp            = this.builtinRegExp;
+        this.string            = this.builtinString;
+        this.syntaxError       = this.builtinSyntaxError;
+        this.typeError         = this.builtinTypeError;
+        this.uriError          = this.builtinURIError;
+        this.arrayBuffer       = this.builtinArrayBuffer;
+        this.int8Array         = this.builtinInt8Array;
+        this.uint8Array        = this.builtinUint8Array;
+        this.uint8ClampedArray = this.builtinUint8ClampedArray;
+        this.int16Array        = this.builtinInt16Array;
+        this.uint16Array       = this.builtinUint16Array;
+        this.int32Array        = this.builtinInt32Array;
+        this.uint32Array       = this.builtinUint32Array;
+        this.float32Array      = this.builtinFloat32Array;
+        this.float64Array      = this.builtinFloat64Array;
+    }
+
+    private void initDebug() {
+        this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug"));
+    }
+
+    @SuppressWarnings("resource")
+    private static Object printImpl(final boolean newLine, final Object... objects) {
+        final PrintWriter out = Global.getEnv().getOut();
+
+        boolean first = true;
+        for (final Object object : objects) {
+            if (first) {
+                first = false;
+            } else {
+                out.print(' ');
+            }
+
+            out.print(JSType.toString(object));
+        }
+
+        if (newLine) {
+            out.println();
+        }
+
+        out.flush();
+
+        return UNDEFINED;
+    }
+
+    /**
+     * These classes are generated by nasgen tool and so we have to use
+     * reflection to load and create new instance of these classes.
+     */
+    private ScriptObject initConstructor(final String name) {
+        try {
+            // Assuming class name pattern for built-in JS constructors.
+            final StringBuilder sb = new StringBuilder("jdk.nashorn.internal.objects.");
+
+            sb.append("Native");
+            sb.append(name);
+            sb.append("$Constructor");
+
+            final Class<?>     funcClass = Class.forName(sb.toString());
+            final ScriptObject res       = (ScriptObject)funcClass.newInstance();
+
+            if (res instanceof ScriptFunction) {
+                // All global constructor prototypes are not-writable,
+                // not-enumerable and not-configurable.
+                final ScriptFunction func = (ScriptFunction)res;
+                func.modifyOwnProperty(func.getProperty("prototype"), Attribute.NON_ENUMERABLE_CONSTANT);
+            }
+
+            if (res.getProto() == null) {
+                res.setProto(getObjectPrototype());
+            }
+
+            return res;
+
+        } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // Function and Object constructors are inter-dependent. Also,
+    // Function.prototype
+    // functions are not properly initialized. We fix the references here.
+    // NOTE: be careful if you want to re-order the operations here. You may
+    // have
+    // to play with object references carefully!!
+    private void initFunctionAndObject() {
+        // First-n-foremost is Function
+        this.builtinFunction = (ScriptFunction)initConstructor("Function");
+
+        // create global anonymous function
+        final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction();
+        // need to copy over members of Function.prototype to anon function
+        anon.addBoundProperties(getFunctionPrototype());
+
+        // Function.prototype === Object.getPrototypeOf(Function) ===
+        // <anon-function>
+        builtinFunction.setProto(anon);
+        builtinFunction.setPrototype(anon);
+        anon.set("constructor", builtinFunction, anon.isStrict());
+        anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
+
+        // now initialize Object
+        this.builtinObject = (ScriptFunction)initConstructor("Object");
+        final ScriptObject ObjectPrototype = getObjectPrototype();
+        // Object.getPrototypeOf(Function.prototype) === Object.prototype
+        anon.setProto(ObjectPrototype);
+
+        // Function valued properties of Function.prototype were not properly
+        // initialized. Because, these were created before global.function and
+        // global.object were not initialized.
+        jdk.nashorn.internal.runtime.Property[] properties = getFunctionPrototype().getMap().getProperties();
+        for (final jdk.nashorn.internal.runtime.Property property : properties) {
+            final Object key = property.getKey();
+            final Object value = builtinFunction.get(key);
+
+            if (value instanceof ScriptFunction && value != anon) {
+                final ScriptFunction func = (ScriptFunction)value;
+                func.setProto(getFunctionPrototype());
+                final ScriptObject prototype = ScriptFunction.getPrototype(func);
+                if (prototype != null) {
+                    prototype.setProto(ObjectPrototype);
+                }
+            }
+        }
+
+        // For function valued properties of Object and Object.prototype, make
+        // sure prototype's proto chain ends with Object.prototype
+        for (final jdk.nashorn.internal.runtime.Property property : builtinObject.getMap().getProperties()) {
+            final Object key = property.getKey();
+            final Object value = builtinObject.get(key);
+
+            if (value instanceof ScriptFunction) {
+                final ScriptFunction func = (ScriptFunction)value;
+                final ScriptObject prototype = ScriptFunction.getPrototype(func);
+                if (prototype != null) {
+                    prototype.setProto(ObjectPrototype);
+                }
+            }
+        }
+
+        properties = getObjectPrototype().getMap().getProperties();
+        for (final jdk.nashorn.internal.runtime.Property property : properties) {
+            final Object key   = property.getKey();
+            final Object value = ObjectPrototype.get(key);
+
+            if (key.equals("constructor")) {
+                continue;
+            }
+
+            if (value instanceof ScriptFunction) {
+                final ScriptFunction func = (ScriptFunction)value;
+                final ScriptObject prototype = ScriptFunction.getPrototype(func);
+                if (prototype != null) {
+                    prototype.setProto(ObjectPrototype);
+                }
+            }
+        }
+    }
+
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.publicLookup(), Global.class, name, MH.type(rtype, types));
+    }
+
+    RegExpResult getLastRegExpResult() {
+        return lastRegExpResult;
+    }
+
+    void setLastRegExpResult(final RegExpResult regExpResult) {
+        this.lastRegExpResult = regExpResult;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
new file mode 100644
index 0000000..afc2b57
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
@@ -0,0 +1,626 @@
+/*
+ * 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.objects;
+
+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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.Arrays;
+import java.util.BitSet;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+import jdk.nashorn.internal.lookup.Lookup;
+
+/**
+ * ECMA 10.6 Arguments Object.
+ *
+ * Arguments object used for non-strict mode functions. For strict mode, we use
+ * a different implementation (@see NativeStrictArguments). In non-strict mode,
+ * named argument access and index argument access (arguments[i]) are linked.
+ * Modifications reflect on each other access -- till arguments indexed element
+ * is deleted. After delete, there is no link between named access and indexed
+ * access for that deleted index alone.
+ */
+public final class NativeArguments extends ScriptObject {
+
+    private static final MethodHandle G$LENGTH = findOwnMH("G$length", Object.class, Object.class);
+    private static final MethodHandle S$LENGTH = findOwnMH("S$length", void.class, Object.class, Object.class);
+    private static final MethodHandle G$CALLEE = findOwnMH("G$callee", Object.class, Object.class);
+    private static final MethodHandle S$CALLEE = findOwnMH("S$callee", void.class, Object.class, Object.class);
+
+    private static final PropertyMap nasgenmap$;
+
+    static {
+        PropertyMap map = PropertyMap.newMap(NativeArguments.class);
+        map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH);
+        map = Lookup.newProperty(map, "callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE);
+        nasgenmap$ = map;
+    }
+
+    private Object length;
+    private Object callee;
+    private ArrayData namedArgs;
+    // This is lazily initialized - only when delete is invoked at all
+    private BitSet deleted;
+
+    NativeArguments(final Object[] arguments, final Object callee, final int numParams) {
+        super(nasgenmap$);
+        setIsArguments();
+
+        setArray(ArrayData.allocate(arguments));
+        this.length = arguments.length;
+        this.callee = callee;
+
+        /**
+         * Declared number of parameters may be more or less than the actual passed
+         * runtime arguments count. We need to truncate or extend with undefined values.
+         *
+         * Example:
+         *
+         * // less declared params
+         * (function (x) { print(arguments); })(20, 44);
+         *
+         * // more declared params
+         * (function (x, y) { print(arguments); })(3);
+         */
+        final Object[] newValues = new Object[numParams];
+        if (numParams > arguments.length) {
+            Arrays.fill(newValues, UNDEFINED);
+        }
+        System.arraycopy(arguments, 0, newValues, 0, Math.min(newValues.length, arguments.length));
+        this.namedArgs = ArrayData.allocate(newValues);
+
+        // set Object.prototype as __proto__
+        this.setProto(Global.objectPrototype());
+    }
+
+    @Override
+    public String getClassName() {
+        return "Arguments";
+    }
+
+    /**
+     * getArgument is used for named argument access.
+     */
+    @Override
+    public Object getArgument(final int key) {
+        return namedArgs.has(key) ? namedArgs.getObject(key) : UNDEFINED;
+    }
+
+    /**
+     * setArgument is used for named argument set.
+     */
+    @Override
+    public void setArgument(final int key, final Object value) {
+        if (namedArgs.has(key)) {
+            namedArgs.set(key, value, false);
+        }
+    }
+
+    @Override
+    public int getInt(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
+    }
+
+    @Override
+    public int getInt(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
+    }
+
+    @Override
+    public int getInt(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
+    }
+
+    @Override
+    public int getInt(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
+    }
+
+    @Override
+    public long getLong(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
+    }
+
+    @Override
+    public long getLong(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
+    }
+
+    @Override
+    public long getLong(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
+    }
+
+    @Override
+    public long getLong(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
+    }
+
+    @Override
+    public double getDouble(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
+    }
+
+    @Override
+    public double getDouble(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
+    }
+
+    @Override
+    public double getDouble(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
+    }
+
+    @Override
+    public double getDouble(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
+    }
+
+    @Override
+    public Object get(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
+    }
+
+    @Override
+    public Object get(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
+    }
+
+    @Override
+    public Object get(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
+    }
+
+    @Override
+    public Object get(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
+    }
+
+    @Override
+    public void set(final Object key, final int value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final Object key, final long value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final Object key, final double value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final Object key, final Object value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final double key, final int value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final double key, final long value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final double key, final double value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final double key, final Object value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final long key, final int value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final long key, final long value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final long key, final double value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final long key, final Object value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final int key, final int value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final int key, final long value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final int key, final double value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final int key, final Object value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        if (isMapped(index)) {
+            namedArgs = namedArgs.set(index, value, strict);
+        } else {
+            super.set(key, value, strict);
+        }
+    }
+
+    @Override
+    public boolean has(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) || super.has(key);
+    }
+
+    @Override
+    public boolean has(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) || super.has(key);
+    }
+
+    @Override
+    public boolean has(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) || super.has(key);
+    }
+
+    @Override
+    public boolean has(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) || super.has(key);
+    }
+
+    @Override
+    public boolean hasOwnProperty(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) || super.hasOwnProperty(key);
+    }
+
+    @Override
+    public boolean hasOwnProperty(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) || super.hasOwnProperty(key);
+    }
+
+    @Override
+    public boolean hasOwnProperty(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) || super.hasOwnProperty(key);
+    }
+
+    @Override
+    public boolean hasOwnProperty(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isMapped(index) || super.hasOwnProperty(key);
+    }
+
+    @Override
+    public boolean delete(final int key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        final boolean success = super.delete(key, strict);
+        if (success && namedArgs.has(index)) {
+            setDeleted(index);
+        }
+        return success;
+    }
+
+    @Override
+    public boolean delete(final long key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        final boolean success = super.delete(key, strict);
+        if (success && namedArgs.has(index)) {
+            setDeleted(index);
+        }
+        return success;
+    }
+
+    @Override
+    public boolean delete(final double key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        final boolean success = super.delete(key, strict);
+        if (success && namedArgs.has(index)) {
+            setDeleted(index);
+        }
+        return success;
+    }
+
+    @Override
+    public boolean delete(final Object key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        final boolean success = super.delete(key, strict);
+        if (success && namedArgs.has(index)) {
+            setDeleted(index);
+        }
+        return success;
+    }
+
+    /**
+     * ECMA 15.4.5.1 [[DefineOwnProperty]] ( P, Desc, Throw ) as specialized in
+     * ECMA 10.6 for Arguments object.
+     */
+    @Override
+    public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
+        final int index = ArrayIndex.getArrayIndexNoThrow(key);
+        if (index >= 0) {
+            final boolean allowed = super.defineOwnProperty(key, propertyDesc, false);
+            if (!allowed) {
+                if (reject) {
+                    throw typeError("cant.redefine.property",  key, ScriptRuntime.safeToString(this));
+                }
+                return false;
+            }
+
+            if (isMapped(index)) {
+                // When mapped argument is redefined, if new descriptor is accessor property
+                // or data-non-writable property, we have to "unmap" (unlink).
+                final PropertyDescriptor desc = toPropertyDescriptor(Global.instance(), propertyDesc);
+                if (desc.type() == PropertyDescriptor.ACCESSOR) {
+                    setDeleted(index);
+                } else {
+                    // set "value" from new descriptor to named args
+                    if (desc.has(PropertyDescriptor.VALUE)) {
+                        namedArgs = namedArgs.set(index, desc.getValue(), false);
+                    }
+
+                    if (desc.has(PropertyDescriptor.WRITABLE) && !desc.isWritable()) {
+                        setDeleted(index);
+                    }
+                }
+            }
+
+            return true;
+        }
+
+        return super.defineOwnProperty(key, propertyDesc, reject);
+    }
+
+    // Internals below this point
+
+    // We track deletions using a bit set (delete arguments[index])
+    private boolean isDeleted(final int index) {
+        return (deleted != null) ? deleted.get(index) : false;
+    }
+
+    private void setDeleted(final int index) {
+        if (deleted == null) {
+            deleted = new BitSet((int)namedArgs.length());
+        }
+        deleted.set(index, true);
+    }
+
+    /**
+     * Are arguments[index] and corresponding named parameter linked?
+     *
+     * In non-strict mode, arguments[index] and corresponding named param
+     * are "linked" or "mapped". Modifications are tacked b/w each other - till
+     * (delete arguments[index]) is used. Once deleted, the corresponding arg
+     * is no longer 'mapped'. Please note that delete can happen only through
+     * the arguments array - named param can not be deleted. (delete is one-way).
+     */
+    private boolean isMapped(final int index) {
+        // in named args and not marked as "deleted"
+        return namedArgs.has(index) && !isDeleted(index);
+    }
+
+        /**
+     * Factory to create correct Arguments object based on strict mode.
+     *
+     * @param arguments the actual arguments array passed
+     * @param callee the callee function that uses arguments object
+     * @param numParams the number of declared (named) function parameters
+     * @return Arguments Object
+     */
+    public static ScriptObject allocate(final Object[] arguments, final ScriptFunction callee, final int numParams) {
+        // Strict functions won't always have a callee for arguments, and will pass null instead.
+        final boolean isStrict = callee == null || callee.isStrict();
+        return isStrict ? new NativeStrictArguments(arguments, numParams) : new NativeArguments(arguments, callee, numParams);
+    }
+
+    /**
+     * Length getter
+     * @param self self reference
+     * @return length property value
+     */
+    public static Object G$length(final Object self) {
+        if (self instanceof NativeArguments) {
+            return ((NativeArguments)self).getArgumentsLength();
+        }
+
+        return 0;
+    }
+
+    /**
+     * Length setter
+     * @param self self reference
+     * @param value value for length property
+     */
+    public static void S$length(final Object self, final Object value) {
+        if (self instanceof NativeArguments) {
+            ((NativeArguments)self).setArgumentsLength(value);
+        }
+    }
+
+    /**
+     * Callee getter
+     * @param self self reference
+     * @return value for callee property
+     */
+    public static Object G$callee(final Object self) {
+        if (self instanceof NativeArguments) {
+            return ((NativeArguments)self).getCallee();
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Callee setter
+     * @param self self reference
+     * @param value value for callee property
+     */
+    public static void S$callee(final Object self, final Object value) {
+        if (self instanceof NativeArguments) {
+            ((NativeArguments)self).setCallee(value);
+        }
+    }
+
+    private Object getArgumentsLength() {
+        return length;
+    }
+
+    private void setArgumentsLength(final Object length) {
+        this.length = length;
+    }
+
+    private Object getCallee() {
+        return callee;
+    }
+
+    private void setCallee(final Object callee) {
+        this.callee = callee;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.publicLookup(), NativeArguments.class, name, MH.type(rtype, types));
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
new file mode 100644
index 0000000..31c1d97
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
@@ -0,0 +1,1275 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
+import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator;
+import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator;
+
+import java.lang.invoke.MethodHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Getter;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Setter;
+import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Undefined;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
+import jdk.nashorn.internal.runtime.arrays.IteratorAction;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+import jdk.nashorn.internal.runtime.linker.InvokeByName;
+
+/**
+ * Runtime representation of a JavaScript array. NativeArray only holds numeric
+ * keyed values. All other values are stored in spill.
+ */
+@ScriptClass("Array")
+public final class NativeArray extends ScriptObject {
+    private static final InvokeByName JOIN = new InvokeByName("join", ScriptObject.class);
+
+    private static final MethodHandle EVERY_CALLBACK_INVOKER   = createIteratorCallbackInvoker(boolean.class);
+    private static final MethodHandle SOME_CALLBACK_INVOKER    = createIteratorCallbackInvoker(boolean.class);
+    private static final MethodHandle FOREACH_CALLBACK_INVOKER = createIteratorCallbackInvoker(void.class);
+    private static final MethodHandle MAP_CALLBACK_INVOKER     = createIteratorCallbackInvoker(Object.class);
+    private static final MethodHandle FILTER_CALLBACK_INVOKER  = createIteratorCallbackInvoker(boolean.class);
+
+    private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
+            Object.class, Undefined.class, Object.class, Object.class, int.class, Object.class);
+    private static final MethodHandle CALL_CMP                = Bootstrap.createDynamicInvoker("dyn:call", int.class,
+            ScriptFunction.class, Object.class, Object.class, Object.class);
+
+    private static final InvokeByName TO_LOCALE_STRING = new InvokeByName("toLocaleString", ScriptObject.class, String.class);
+
+
+    /*
+     * Constructors.
+     */
+    NativeArray() {
+        this(ArrayData.initialArray());
+    }
+
+    NativeArray(final long length) {
+        // TODO assert valid index in long before casting
+        this(ArrayData.allocate((int) length));
+    }
+
+    NativeArray(final int[] array) {
+        this(ArrayData.allocate(array));
+    }
+
+    NativeArray(final long[] array) {
+        this(ArrayData.allocate(array));
+    }
+
+    NativeArray(final double[] array) {
+        this(ArrayData.allocate(array));
+    }
+
+    NativeArray(final Object[] array) {
+        this(ArrayData.allocate(array.length));
+
+        ArrayData arrayData = this.getArray();
+        arrayData.ensure(array.length - 1);
+
+        for (int index = 0; index < array.length; index++) {
+            final Object value = array[index];
+
+            if (value == ScriptRuntime.EMPTY) {
+                arrayData = arrayData.delete(index);
+            } else {
+                arrayData = arrayData.set(index, value, isStrictContext());
+            }
+        }
+
+        this.setArray(arrayData);
+    }
+
+    private NativeArray(final ArrayData arrayData) {
+        setProto(Global.instance().getArrayPrototype());
+        this.setArray(arrayData);
+        this.setIsArray();
+    }
+
+    @Override
+    public String getClassName() {
+        return "Array";
+    }
+
+    @Override
+    public Object getLength() {
+        return getArray().length() & JSType.MAX_UINT;
+    }
+
+    /**
+     * ECMA 15.4.5.1 [[DefineOwnProperty]] ( P, Desc, Throw )
+     */
+    @Override
+    public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
+        final PropertyDescriptor desc = toPropertyDescriptor(Global.instance(), propertyDesc);
+
+        // never be undefined as "length" is always defined and can't be deleted for arrays
+        // Step 1
+        final PropertyDescriptor oldLenDesc = (PropertyDescriptor) super.getOwnPropertyDescriptor("length");
+
+        // Step 2
+        // get old length and convert to long
+        long oldLen = NativeArray.validLength(oldLenDesc.getValue(), true);
+
+        // Step 3
+        if ("length".equals(key)) {
+            // Step 3a
+            if (!desc.has(VALUE)) {
+                return super.defineOwnProperty("length", propertyDesc, reject);
+            }
+
+            // Step 3b
+            final PropertyDescriptor newLenDesc = desc;
+
+            // Step 3c and 3d - get new length and convert to long
+            final long newLen = NativeArray.validLength(newLenDesc.getValue(), true);
+
+            // Step 3e
+            newLenDesc.setValue(newLen);
+
+            // Step 3f
+            // increasing array length - just need to set new length value (and attributes if any) and return
+            if (newLen >= oldLen) {
+                return super.defineOwnProperty("length", newLenDesc, reject);
+            }
+
+            // Step 3g
+            if (!oldLenDesc.isWritable()) {
+                if (reject) {
+                    throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
+                }
+                return false;
+            }
+
+            // Step 3h and 3i
+            final boolean newWritable = (!newLenDesc.has(WRITABLE) || newLenDesc.isWritable());
+            if (!newWritable) {
+                newLenDesc.setWritable(true);
+            }
+
+            // Step 3j and 3k
+            final boolean succeeded = super.defineOwnProperty("length", newLenDesc, reject);
+            if (!succeeded) {
+                return false;
+            }
+
+            // Step 3l
+            // make sure that length is set till the point we can delete the old elements
+            while (newLen < oldLen) {
+                oldLen--;
+                final boolean deleteSucceeded = delete(oldLen, false);
+                if (!deleteSucceeded) {
+                    newLenDesc.setValue(oldLen + 1);
+                    if (!newWritable) {
+                        newLenDesc.setWritable(false);
+                    }
+                    super.defineOwnProperty("length", newLenDesc, false);
+                    if (reject) {
+                        throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
+                    }
+                    return false;
+                }
+            }
+
+            // Step 3m
+            if (!newWritable) {
+                // make 'length' property not writable
+                final ScriptObject newDesc = Global.newEmptyInstance();
+                newDesc.set(WRITABLE, false, false);
+                return super.defineOwnProperty("length", newDesc, false);
+            }
+
+            return true;
+        }
+
+        // Step 4a
+        final int index = ArrayIndex.getArrayIndexNoThrow(key);
+        if (ArrayIndex.isValidArrayIndex(index)) {
+            final long longIndex = ArrayIndex.toLongIndex(index);
+            // Step 4b
+            // setting an element beyond current length, but 'length' is not writable
+            if (longIndex >= oldLen && !oldLenDesc.isWritable()) {
+                if (reject) {
+                    throw typeError("property.not.writable", Long.toString(longIndex), ScriptRuntime.safeToString(this));
+                }
+                return false;
+            }
+
+            // Step 4c
+            // set the new array element
+            final boolean succeeded = super.defineOwnProperty(key, propertyDesc, false);
+
+            // Step 4d
+            if (!succeeded) {
+                if (reject) {
+                    throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
+                }
+                return false;
+            }
+
+            // Step 4e -- adjust new length based on new element index that is set
+            if (longIndex >= oldLen) {
+                oldLenDesc.setValue(longIndex + 1);
+                super.defineOwnProperty("length", oldLenDesc, false);
+            }
+
+            // Step 4f
+            return true;
+        }
+
+        // not an index property
+        return super.defineOwnProperty(key, propertyDesc, reject);
+    }
+
+    /**
+     * Return the array contents upcasted as an ObjectArray, regardless of
+     * representation
+     *
+     * @return an object array
+     */
+    public Object[] asObjectArray() {
+        return getArray().asObjectArray();
+    }
+
+    /**
+     * ECMA 15.4.3.2 Array.isArray ( arg )
+     *
+     * @param self self reference
+     * @param arg  argument - object to check
+     * @return true if argument is an array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object isArray(final Object self, final Object arg) {
+        return isArray(arg) || (arg == Global.instance().getArrayPrototype())
+                || (arg instanceof NativeRegExpExecResult);
+    }
+
+    /**
+     * Length getter
+     * @param self self reference
+     * @return the length of the object
+     */
+    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+    public static Object length(final Object self) {
+        if (isArray(self)) {
+            return ((NativeArray) self).getArray().length() & JSType.MAX_UINT;
+        }
+
+        return 0;
+    }
+
+    /**
+     * Length setter
+     * @param self   self reference
+     * @param length new length property
+     */
+    @Setter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+    public static void length(final Object self, final Object length) {
+        if (isArray(self)) {
+            ((NativeArray) self).setLength(validLength(length, true));
+        }
+    }
+
+    static long validLength(final Object length, final boolean reject) {
+        final double doubleLength = JSType.toNumber(length);
+        if (!Double.isNaN(doubleLength) && JSType.isRepresentableAsLong(doubleLength)) {
+            final long len = (long) doubleLength;
+            if (len >= 0 && len <= JSType.MAX_UINT) {
+                return len;
+            }
+        }
+        if (reject) {
+            throw rangeError("inappropriate.array.length", ScriptRuntime.safeToString(length));
+        }
+        return -1;
+    }
+
+    /**
+     * ECMA 15.4.4.2 Array.prototype.toString ( )
+     *
+     * @param self self reference
+     * @return string representation of array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toString(final Object self) {
+        if (self instanceof ScriptObject) {
+            final ScriptObject sobj = (ScriptObject) self;
+            try {
+                final Object join = JOIN.getGetter().invokeExact(sobj);
+                if (join instanceof ScriptFunction) {
+                    return JOIN.getInvoker().invokeExact(join, sobj);
+                }
+            } catch (final RuntimeException | Error e) {
+                throw e;
+            } catch (final Throwable t) {
+                throw new RuntimeException(t);
+            }
+        }
+
+        // FIXME: should lookup Object.prototype.toString and call that?
+        return ScriptRuntime.builtinObjectToString(self);
+    }
+
+    /**
+     * ECMA 15.4.4.3 Array.prototype.toLocaleString ( )
+     *
+     * @param self self reference
+     * @return locale specific string representation for array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toLocaleString(final Object self) {
+        final StringBuilder sb = new StringBuilder();
+        final Iterator<Object> iter = arrayLikeIterator(self, true);
+
+        while (iter.hasNext()) {
+            final Object obj = iter.next();
+
+            if (obj != null && obj != ScriptRuntime.UNDEFINED) {
+                final Object val = JSType.toScriptObject(obj);
+
+                try {
+                    if (val instanceof ScriptObject) {
+                        final ScriptObject sobj           = (ScriptObject)val;
+                        final Object       toLocaleString = TO_LOCALE_STRING.getGetter().invokeExact(sobj);
+
+                        if (toLocaleString instanceof ScriptFunction) {
+                            sb.append((String)TO_LOCALE_STRING.getInvoker().invokeExact(toLocaleString, sobj));
+                        } else {
+                            throw typeError("not.a.function", "toLocaleString");
+                        }
+                    }
+                } catch (final Error|RuntimeException t) {
+                    throw t;
+                } catch (final Throwable t) {
+                    throw new RuntimeException(t);
+                }
+            }
+
+            if (iter.hasNext()) {
+                sb.append(",");
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * ECMA 15.4.2.2 new Array (len)
+     *
+     * @param newObj was the new operator used to instantiate this array
+     * @param self   self reference
+     * @param args   arguments (length)
+     * @return the new NativeArray
+     */
+    @Constructor(arity = 1)
+    public static Object construct(final boolean newObj, final Object self, final Object... args) {
+        switch (args.length) {
+        case 0:
+            return new NativeArray(0);
+        case 1:
+            final Object len = args[0];
+            if (len instanceof Number) {
+                long length;
+                if (len instanceof Integer || len instanceof Long) {
+                    length = ((Number) len).longValue();
+                    if (length >= 0 && length < 0xffff_ffffL) {
+                        return new NativeArray(length);
+                    }
+                }
+
+                length = JSType.toUint32(len);
+
+                /*
+                 * If the argument len is a Number and ToUint32(len) is equal to
+                 * len, then the length property of the newly constructed object
+                 * is set to ToUint32(len). If the argument len is a Number and
+                 * ToUint32(len) is not equal to len, a RangeError exception is
+                 * thrown.
+                 */
+                final double numberLength = ((Number) len).doubleValue();
+                if (length != numberLength) {
+                    throw rangeError("inappropriate.array.length", JSType.toString(numberLength));
+                }
+
+                return new NativeArray(length);
+            }
+            /*
+             * If the argument len is not a Number, then the length property of
+             * the newly constructed object is set to 1 and the 0 property of
+             * the newly constructed object is set to len
+             */
+            return new NativeArray(new Object[]{args[0]});
+            //fallthru
+        default:
+            return new NativeArray(args);
+        }
+    }
+
+    /**
+     * ECMA 15.4.2.2 new Array (len)
+     *
+     * Specialized constructor for zero arguments - empty array
+     *
+     * @param newObj was the new operator used to instantiate this array
+     * @param self   self reference
+     * @return the new NativeArray
+     */
+    @SpecializedConstructor
+    public static Object construct(final boolean newObj, final Object self) {
+        return new NativeArray(0);
+    }
+
+    /**
+     * ECMA 15.4.2.2 new Array (len)
+     *
+     * Specialized constructor for one integer argument (length)
+     *
+     * @param newObj was the new operator used to instantiate this array
+     * @param self   self reference
+     * @param length array length
+     * @return the new NativeArray
+     */
+    @SpecializedConstructor
+    public static Object construct(final boolean newObj, final Object self, final int length) {
+        if (length >= 0) {
+            return new NativeArray(length);
+        }
+
+        return construct(newObj, self, new Object[]{length});
+    }
+
+    /**
+     * ECMA 15.4.2.2 new Array (len)
+     *
+     * Specialized constructor for one long argument (length)
+     *
+     * @param newObj was the new operator used to instantiate this array
+     * @param self   self reference
+     * @param length array length
+     * @return the new NativeArray
+     */
+    @SpecializedConstructor
+    public static Object construct(final boolean newObj, final Object self, final long length) {
+        if (length >= 0L && length <= JSType.MAX_UINT) {
+            return new NativeArray(length);
+        }
+
+        return construct(newObj, self, new Object[]{length});
+    }
+
+    /**
+     * ECMA 15.4.2.2 new Array (len)
+     *
+     * Specialized constructor for one double argument (length)
+     *
+     * @param newObj was the new operator used to instantiate this array
+     * @param self   self reference
+     * @param length array length
+     * @return the new NativeArray
+     */
+    @SpecializedConstructor
+    public static Object construct(final boolean newObj, final Object self, final double length) {
+        final long uint32length = JSType.toUint32(length);
+
+        if (uint32length == length) {
+            return new NativeArray(uint32length);
+        }
+
+        return construct(newObj, self, new Object[]{length});
+    }
+
+    /**
+     * ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
+     *
+     * @param self self reference
+     * @param args arguments to concat
+     * @return resulting NativeArray
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object concat(final Object self, final Object... args) {
+        final ArrayList<Object> list = new ArrayList<>();
+        final Object selfToObject = Global.toObject(self);
+
+        if (isArray(selfToObject)) {
+            final Iterator<Object> iter = arrayLikeIterator(selfToObject, true);
+            while (iter.hasNext()) {
+                list.add(iter.next());
+            }
+        } else {
+            // single element, add it
+            list.add(selfToObject);
+        }
+
+        for (final Object obj : args) {
+            if (isArray(obj) || obj instanceof Iterable || (obj != null && obj.getClass().isArray())) {
+                final Iterator<Object> iter = arrayLikeIterator(obj, true);
+                if (iter.hasNext()) {
+                    while (iter.hasNext()) {
+                        list.add(iter.next());
+                    }
+                } else if (!isArray(obj)) {
+                    list.add(obj); // add empty object, but not an empty array
+                }
+            } else {
+                // single element, add it
+                list.add(obj);
+            }
+        }
+
+        return new NativeArray(list.toArray());
+    }
+
+    /**
+     * ECMA 15.4.4.5 Array.prototype.join (separator)
+     *
+     * @param self      self reference
+     * @param separator element separator
+     * @return string representation after join
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object join(final Object self, final Object separator) {
+        final String           sep  = separator == ScriptRuntime.UNDEFINED ? "," : JSType.toString(separator);
+        final StringBuilder    sb   = new StringBuilder();
+        final Iterator<Object> iter = arrayLikeIterator(self, true);
+
+        while (iter.hasNext()) {
+            final Object obj = iter.next();
+
+            if (obj != null && obj != ScriptRuntime.UNDEFINED) {
+                sb.append(JSType.toString(obj));
+            }
+
+            if (iter.hasNext()) {
+                sb.append(sep);
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * ECMA 15.4.4.6 Array.prototype.pop ()
+     *
+     * @param self self reference
+     * @return array after pop
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object pop(final Object self) {
+        try {
+            final ScriptObject sobj = (ScriptObject)self;
+            final boolean strict    = sobj.isStrictContext();
+
+            if (bulkable(sobj)) {
+                return ((NativeArray)sobj).getArray().pop();
+            }
+
+            final long len = JSType.toUint32(sobj.getLength());
+
+            if (len == 0) {
+                sobj.set("length", 0, strict);
+                return ScriptRuntime.UNDEFINED;
+            }
+
+            final long   index   = len - 1;
+            final Object element = sobj.get(index);
+
+            sobj.delete(index, strict);
+            sobj.set("length", index, strict);
+
+            return element;
+        } catch (final ClassCastException | NullPointerException e) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    /**
+     * ECMA 15.4.4.7 Array.prototype.push (args...)
+     *
+     * @param self self reference
+     * @param args arguments to push
+     * @return array after pushes
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object push(final Object self, final Object... args) {
+        try {
+            final ScriptObject sobj   = (ScriptObject)self;
+            final boolean      strict = sobj.isStrictContext();
+
+            if (bulkable(sobj)) {
+                final NativeArray nativeArray = (NativeArray)sobj;
+                if (nativeArray.getArray().length() + args.length <= JSType.MAX_UINT) {
+                    final ArrayData newData = nativeArray.getArray().push(nativeArray.isStrictContext(), args);
+                    nativeArray.setArray(newData);
+                    return newData.length();
+                }
+                //fallthru
+            }
+
+            long len = JSType.toUint32(sobj.getLength());
+            for (final Object element : args) {
+                sobj.set(len++, element, strict);
+            }
+            sobj.set("length", len, strict);
+
+            return len;
+        } catch (final ClassCastException | NullPointerException e) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    /**
+     * ECMA 15.4.4.8 Array.prototype.reverse ()
+     *
+     * @param self self reference
+     * @return reversed array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object reverse(final Object self) {
+        try {
+            final ScriptObject sobj   = (ScriptObject)self;
+            final boolean      strict = sobj.isStrictContext();
+            final long         len    = JSType.toUint32(sobj.getLength());
+            final long         middle = len / 2;
+
+            for (long lower = 0; lower != middle; lower++) {
+                final long    upper       = len - lower - 1;
+                final Object  lowerValue  = sobj.get(lower);
+                final Object  upperValue  = sobj.get(upper);
+                final boolean lowerExists = sobj.has(lower);
+                final boolean upperExists = sobj.has(upper);
+
+                if (lowerExists && upperExists) {
+                    sobj.set(lower, upperValue, strict);
+                    sobj.set(upper, lowerValue, strict);
+                } else if (!lowerExists && upperExists) {
+                    sobj.set(lower, upperValue, strict);
+                    sobj.delete(upper, strict);
+                } else if (lowerExists && !upperExists) {
+                    sobj.delete(lower, strict);
+                    sobj.set(upper, lowerValue, strict);
+                }
+            }
+            return sobj;
+        } catch (final ClassCastException | NullPointerException e) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    /**
+     * ECMA 15.4.4.9 Array.prototype.shift ()
+     *
+     * @param self self reference
+     * @return shifted array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object shift(final Object self) {
+        final Object obj = Global.toObject(self);
+
+        Object first = ScriptRuntime.UNDEFINED;
+
+        if (!(obj instanceof ScriptObject)) {
+            return first;
+        }
+
+        final ScriptObject sobj   = (ScriptObject) obj;
+        final boolean      strict = Global.isStrict();
+
+        long len = JSType.toUint32(sobj.getLength());
+
+        if (len > 0) {
+            first = sobj.get(0);
+
+            if (bulkable(sobj)) {
+                ((NativeArray) sobj).getArray().shiftLeft(1);
+            } else {
+                for (long k = 1; k < len; k++) {
+                    sobj.set(k - 1, sobj.get(k), strict);
+                }
+            }
+            sobj.delete(--len, strict);
+        } else {
+            len = 0;
+        }
+
+        sobj.set("length", len, strict);
+
+        return first;
+    }
+
+    /**
+     * ECMA 15.4.4.10 Array.prototype.slice ( start [ , end ] )
+     *
+     * @param self  self reference
+     * @param start start of slice (inclusive)
+     * @param end   end of slice (optional, exclusive)
+     * @return sliced array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object slice(final Object self, final Object start, final Object end) {
+        final Object       obj                 = Global.toObject(self);
+        final ScriptObject sobj                = (ScriptObject)obj;
+        final long         len                 = JSType.toUint32(sobj.getLength());
+        final long         relativeStartUint32 = JSType.toUint32(start);
+        final long         relativeStart       = JSType.toInteger(start);
+
+        long k = relativeStart < 0 ?
+                Math.max(len + relativeStart, 0) :
+                Math.min(
+                    Math.max(relativeStartUint32, relativeStart),
+                    len);
+
+        final long relativeEndUint32 = end == ScriptRuntime.UNDEFINED ? len : JSType.toUint32(end);
+        final long relativeEnd       = end == ScriptRuntime.UNDEFINED ? len : JSType.toInteger(end);
+
+        final long finale = relativeEnd < 0 ?
+                Math.max(len + relativeEnd, 0) :
+                Math.min(
+                    Math.max(relativeEndUint32, relativeEnd),
+                    len);
+
+        if (k >= finale) {
+            return new NativeArray(0);
+        }
+
+        if (bulkable(sobj)) {
+            final NativeArray narray = (NativeArray) sobj;
+            return new NativeArray(narray.getArray().slice(k, finale));
+        }
+
+        final NativeArray copy = new NativeArray(0);
+        for (long n = 0; k < finale; n++, k++) {
+            copy.defineOwnProperty((int) n, sobj.get(k));
+        }
+
+        return copy;
+    }
+
+    private static ScriptFunction compareFunction(final Object comparefn) {
+        try {
+            return (ScriptFunction)comparefn;
+        } catch (final ClassCastException e) {
+            return null; //undefined or null
+        }
+    }
+
+    private static Object[] sort(final Object[] array, final Object comparefn) {
+        final ScriptFunction cmp = compareFunction(comparefn);
+
+        final List<Object> list = Arrays.asList(array);
+        final Object cmpThis = cmp == null || cmp.isStrict() ? ScriptRuntime.UNDEFINED : Global.instance();
+
+        Collections.sort(list, new Comparator<Object>() {
+            @Override
+            public int compare(final Object x, final Object y) {
+                if (x == ScriptRuntime.UNDEFINED && y == ScriptRuntime.UNDEFINED) {
+                    return 0;
+                } else if (x == ScriptRuntime.UNDEFINED) {
+                    return 1;
+                } else if (y == ScriptRuntime.UNDEFINED) {
+                    return -1;
+                }
+
+                if (cmp != null) {
+                    try {
+                        return (int)CALL_CMP.invokeExact(cmp, cmpThis, x, y);
+                    } catch (final RuntimeException | Error e) {
+                        throw e;
+                    } catch (final Throwable t) {
+                        throw new RuntimeException(t);
+                    }
+                }
+
+                return JSType.toString(x).compareTo(JSType.toString(y));
+            }
+        });
+
+        return list.toArray(new Object[array.length]);
+    }
+
+    /**
+     * ECMA 15.4.4.11 Array.prototype.sort ( comparefn )
+     *
+     * @param self       self reference
+     * @param comparefn  element comparison function
+     * @return sorted array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object sort(final Object self, final Object comparefn) {
+        try {
+            final ScriptObject sobj    = (ScriptObject) self;
+            final boolean      strict  = sobj.isStrictContext();
+            final long         len     = JSType.toUint32(sobj.getLength());
+
+            if (len > 1) {
+                final Object[] src = new Object[(int) len];
+                for (int i = 0; i < src.length; i++) {
+                    src[i] = sobj.get(i);
+                }
+
+                final Object[] sorted = sort(src, comparefn);
+                assert sorted.length == src.length;
+
+                for (int i = 0; i < sorted.length; i++) {
+                    sobj.set(i, sorted[i], strict);
+                }
+            }
+
+            return sobj;
+        } catch (final ClassCastException | NullPointerException e) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    /**
+     * ECMA 15.4.4.12 Array.prototype.splice ( start, deleteCount [ item1 [ , item2 [ , ... ] ] ] )
+     *
+     * @param self self reference
+     * @param args arguments
+     * @return result of splice
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object splice(final Object self, final Object... args) {
+        final Object obj = Global.toObject(self);
+
+        if (!(obj instanceof ScriptObject)) {
+            return ScriptRuntime.UNDEFINED;
+        }
+
+        final Object start = (args.length > 0) ? args[0] : ScriptRuntime.UNDEFINED;
+        final Object deleteCount = (args.length > 1) ? args[1] : ScriptRuntime.UNDEFINED;
+
+        Object[] items;
+
+        if (args.length > 2) {
+            items = new Object[args.length - 2];
+            System.arraycopy(args, 2, items, 0, items.length);
+        } else {
+            items = ScriptRuntime.EMPTY_ARRAY;
+        }
+
+        final ScriptObject sobj                = (ScriptObject)obj;
+        final boolean      strict              = Global.isStrict();
+        final long         len                 = JSType.toUint32(sobj.getLength());
+        final long         relativeStartUint32 = JSType.toUint32(start);
+        final long         relativeStart       = JSType.toInteger(start);
+
+        //TODO: workaround overflow of relativeStart for start > Integer.MAX_VALUE
+        final long actualStart = relativeStart < 0 ?
+            Math.max(len + relativeStart, 0) :
+            Math.min(
+                Math.max(relativeStartUint32, relativeStart),
+                len);
+
+        final long actualDeleteCount =
+            Math.min(
+                Math.max(JSType.toInteger(deleteCount), 0),
+                len - actualStart);
+
+        final NativeArray array = new NativeArray(actualDeleteCount);
+
+        for (long k = 0; k < actualDeleteCount; k++) {
+            final long from = actualStart + k;
+
+            if (sobj.has(from)) {
+                array.defineOwnProperty((int) k, sobj.get(from));
+            }
+        }
+
+        if (items.length < actualDeleteCount) {
+            for (long k = actualStart; k < (len - actualDeleteCount); k++) {
+                final long from = k + actualDeleteCount;
+                final long to   = k + items.length;
+
+                if (sobj.has(from)) {
+                    sobj.set(to, sobj.get(from), strict);
+                } else {
+                    sobj.delete(to, strict);
+                }
+            }
+
+            for (long k = len; k > (len - actualDeleteCount + items.length); k--) {
+                sobj.delete(k - 1, strict);
+            }
+        } else if (items.length > actualDeleteCount) {
+            for (long k = len - actualDeleteCount; k > actualStart; k--) {
+                final long from = k + actualDeleteCount - 1;
+                final long to   = k + items.length - 1;
+
+                if (sobj.has(from)) {
+                    final Object fromValue = sobj.get(from);
+                    sobj.set(to, fromValue, strict);
+                } else {
+                    sobj.delete(to, strict);
+                }
+            }
+        }
+
+        long k = actualStart;
+        for (int i = 0; i < items.length; i++, k++) {
+            sobj.set(k, items[i], strict);
+        }
+
+        final long newLength = len - actualDeleteCount + items.length;
+        sobj.set("length", newLength, strict);
+
+        return array;
+    }
+
+    /**
+     * ECMA 15.4.4.13 Array.prototype.unshift ( [ item1 [ , item2 [ , ... ] ] ] )
+     *
+     * @param self  self reference
+     * @param items items for unshift
+     * @return unshifted array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object unshift(final Object self, final Object... items) {
+        final Object obj = Global.toObject(self);
+
+        if (!(obj instanceof ScriptObject)) {
+            return ScriptRuntime.UNDEFINED;
+        }
+
+        final ScriptObject sobj   = (ScriptObject)obj;
+        final boolean      strict = Global.isStrict();
+        final long         len    = JSType.toUint32(sobj.getLength());
+
+        if (items == null) {
+            return ScriptRuntime.UNDEFINED;
+        }
+
+        if (bulkable(sobj)) {
+            final NativeArray nativeArray = (NativeArray) sobj;
+            nativeArray.getArray().shiftRight(items.length);
+
+            for (int j = 0; j < items.length; j++) {
+                nativeArray.setArray(nativeArray.getArray().set(j, items[j], sobj.isStrictContext()));
+            }
+        } else {
+            for (long k = len; k > 0; k--) {
+                final long from = k - 1;
+                final long to = k + items.length - 1;
+
+                if (sobj.has(from)) {
+                    final Object fromValue = sobj.get(from);
+                    sobj.set(to, fromValue, strict);
+                } else {
+                    sobj.delete(to, strict);
+                }
+            }
+
+            for (int j = 0; j < items.length; j++) {
+                sobj.set(j, items[j], strict);
+            }
+        }
+
+        final long newLength = len + items.length;
+        sobj.set("length", newLength, strict);
+
+        return newLength;
+    }
+
+    /**
+     * ECMA 15.4.4.14 Array.prototype.indexOf ( searchElement [ , fromIndex ] )
+     *
+     * @param self           self reference
+     * @param searchElement  element to search for
+     * @param fromIndex      start index of search
+     * @return index of element, or -1 if not found
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object indexOf(final Object self, final Object searchElement, final Object fromIndex) {
+        try {
+            final ScriptObject sobj = (ScriptObject)Global.toObject(self);
+            final long         len  = JSType.toUint32(sobj.getLength());
+            final long         n    = JSType.toLong(fromIndex);
+
+            if (len == 0 || n >= len) {
+                return -1;
+            }
+
+            for (long k = Math.max(0, (n < 0) ? (len - Math.abs(n)) : n); k < len; k++) {
+                if (sobj.has(k)) {
+                    if (ScriptRuntime.EQ_STRICT(sobj.get(k), searchElement)) {
+                        return k;
+                    }
+                }
+            }
+        } catch (final ClassCastException | NullPointerException e) {
+            //fallthru
+        }
+
+        return -1;
+    }
+
+    /**
+     * ECMA 15.4.4.15 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )
+     *
+     * @param self self reference
+     * @param args arguments: element to search for and optional from index
+     * @return index of element, or -1 if not found
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object lastIndexOf(final Object self, final Object... args) {
+        try {
+            final ScriptObject sobj = (ScriptObject)Global.toObject(self);
+            final long         len  = JSType.toUint32(sobj.getLength());
+
+            if (len == 0) {
+                return -1;
+            }
+
+            final Object searchElement = (args.length > 0) ? args[0] : ScriptRuntime.UNDEFINED;
+            final long   n             = (args.length > 1) ? JSType.toLong(args[1]) : (len - 1);
+
+            for (long k = (n < 0) ? (len - Math.abs(n)) : Math.min(n, len - 1); k >= 0; k--) {
+                if (sobj.has(k)) {
+                    if (ScriptRuntime.EQ_STRICT(sobj.get(k), searchElement)) {
+                        return k;
+                    }
+                }
+            }
+        } catch (final ClassCastException | NullPointerException e) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
+        }
+
+        return -1;
+    }
+
+    /**
+     * ECMA 15.4.4.16 Array.prototype.every ( callbackfn [ , thisArg ] )
+     *
+     * @param self        self reference
+     * @param callbackfn  callback function per element
+     * @param thisArg     this argument
+     * @return true if callback function return true for every element in the array, false otherwise
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object every(final Object self, final Object callbackfn, final Object thisArg) {
+        return applyEvery(Global.toObject(self), callbackfn, thisArg);
+    }
+
+    private static boolean applyEvery(final Object self, final Object callbackfn, final Object thisArg) {
+        return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, true) {
+            @Override
+            protected boolean forEach(final Object val, final int i) throws Throwable {
+                return (result = (boolean)EVERY_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self));
+            }
+        }.apply();
+    }
+
+    /**
+     * ECMA 15.4.4.17 Array.prototype.some ( callbackfn [ , thisArg ] )
+     *
+     * @param self        self reference
+     * @param callbackfn  callback function per element
+     * @param thisArg     this argument
+     * @return true if callback function returned true for any element in the array, false otherwise
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object some(final Object self, final Object callbackfn, final Object thisArg) {
+        return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) {
+            @Override
+            protected boolean forEach(final Object val, final int i) throws Throwable {
+                return !(result = (boolean)SOME_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self));
+            }
+        }.apply();
+    }
+
+    /**
+     * ECMA 15.4.4.18 Array.prototype.forEach ( callbackfn [ , thisArg ] )
+     *
+     * @param self        self reference
+     * @param callbackfn  callback function per element
+     * @param thisArg     this argument
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object forEach(final Object self, final Object callbackfn, final Object thisArg) {
+        return new IteratorAction<Object>(Global.toObject(self), callbackfn, thisArg, ScriptRuntime.UNDEFINED) {
+            @Override
+            protected boolean forEach(final Object val, final int i) throws Throwable {
+                FOREACH_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self);
+                return true;
+            }
+        }.apply();
+    }
+
+    /**
+     * ECMA 15.4.4.19 Array.prototype.map ( callbackfn [ , thisArg ] )
+     *
+     * @param self        self reference
+     * @param callbackfn  callback function per element
+     * @param thisArg     this argument
+     * @return array with elements transformed by map function
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object map(final Object self, final Object callbackfn, final Object thisArg) {
+        return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) {
+            @Override
+            protected boolean forEach(final Object val, final int i) throws Throwable {
+                final Object r = MAP_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self);
+                result.defineOwnProperty(index, r);
+                return true;
+            }
+
+            @Override
+            public void applyLoopBegin(final ArrayLikeIterator<Object> iter0) {
+                // map return array should be of same length as source array
+                // even if callback reduces source array length
+                result = new NativeArray(iter0.getLength());
+            }
+        }.apply();
+    }
+
+    /**
+     * ECMA 15.4.4.20 Array.prototype.filter ( callbackfn [ , thisArg ] )
+     *
+     * @param self        self reference
+     * @param callbackfn  callback function per element
+     * @param thisArg     this argument
+     * @return filtered array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object filter(final Object self, final Object callbackfn, final Object thisArg) {
+        return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) {
+            private int to = 0;
+
+            @Override
+            protected boolean forEach(final Object val, final int i) throws Throwable {
+                if ((boolean)FILTER_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)) {
+                    result.defineOwnProperty(to++, val);
+                }
+                return true;
+            }
+        }.apply();
+    }
+
+    private static Object reduceInner(final ArrayLikeIterator<Object> iter, final Object self, final Object... args) {
+        final Object  callbackfn          = args.length > 0 ? args[0] : ScriptRuntime.UNDEFINED;
+        final boolean initialValuePresent = args.length > 1;
+
+        Object initialValue = initialValuePresent ? args[1] : ScriptRuntime.UNDEFINED;
+
+        if (callbackfn == ScriptRuntime.UNDEFINED) {
+            throw typeError("not.a.function", "undefined");
+        }
+
+        if (!initialValuePresent) {
+            if (iter.hasNext()) {
+                initialValue = iter.next();
+            } else {
+                throw typeError("array.reduce.invalid.init");
+            }
+        }
+
+        //if initial value is ScriptRuntime.UNDEFINED - step forward once.
+        return new IteratorAction<Object>(Global.toObject(self), callbackfn, ScriptRuntime.UNDEFINED, initialValue, iter) {
+            @Override
+            protected boolean forEach(final Object val, final int i) throws Throwable {
+                // TODO: why can't I declare the second arg as Undefined.class?
+                result = REDUCE_CALLBACK_INVOKER.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self);
+                return true;
+            }
+        }.apply();
+    }
+
+    /**
+     * ECMA 15.4.4.21 Array.prototype.reduce ( callbackfn [ , initialValue ] )
+     *
+     * @param self self reference
+     * @param args arguments to reduce
+     * @return accumulated result
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object reduce(final Object self, final Object... args) {
+        return reduceInner(arrayLikeIterator(self), self, args);
+    }
+
+    /**
+     * ECMA 15.4.4.22 Array.prototype.reduceRight ( callbackfn [ , initialValue ] )
+     *
+     * @param self        self reference
+     * @param args arguments to reduce
+     * @return accumulated result
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object reduceRight(final Object self, final Object... args) {
+        return reduceInner(reverseArrayLikeIterator(self), self, args);
+    }
+
+    /**
+     * Determine if Java bulk array operations may be used on the underlying
+     * storage. This is possible only if the object's prototype chain is empty
+     * or each of the prototypes in the chain is empty.
+     *
+     * @param self the object to examine
+     * @return true if optimizable
+     */
+    private static boolean bulkable(final ScriptObject self) {
+        return self.isArray() && !hasInheritedArrayEntries(self);
+    }
+
+    private static boolean hasInheritedArrayEntries(final ScriptObject self) {
+        ScriptObject proto = self.getProto();
+        while (proto != null) {
+            if (proto.hasArrayEntries()) {
+                return true;
+            }
+            proto = proto.getProto();
+        }
+
+        return false;
+    }
+
+    private static MethodHandle createIteratorCallbackInvoker(final Class<?> rtype) {
+        return Bootstrap.createDynamicInvoker("dyn:call", rtype, Object.class, Object.class, Object.class,
+                int.class, Object.class);
+
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java
new file mode 100644
index 0000000..542b2ae
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java
@@ -0,0 +1,114 @@
+/*
+ * 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.objects;
+
+import java.util.Arrays;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Getter;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+@ScriptClass("ArrayBuffer")
+final class NativeArrayBuffer extends ScriptObject {
+    private final byte[] buffer;
+
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        if (args.length == 0) {
+            throw new RuntimeException("missing length argument");
+        }
+
+        return new NativeArrayBuffer(JSType.toInt32(args[0]));
+    }
+
+    protected NativeArrayBuffer(final byte[] byteArray) {
+        this.buffer = byteArray;
+        this.setProto(Global.instance().getArrayBufferPrototype());
+    }
+
+    protected NativeArrayBuffer(final int byteLength) {
+        this(new byte[byteLength]);
+    }
+
+    protected NativeArrayBuffer(final NativeArrayBuffer other, final int begin, final int end) {
+        this(Arrays.copyOfRange(other.buffer, begin, end));
+    }
+
+    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+    public static Object byteLength(final Object self) {
+        return ((NativeArrayBuffer)self).buffer.length;
+    }
+
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object slice(final Object self, final Object begin0, final Object end0) {
+        final NativeArrayBuffer arrayBuffer = (NativeArrayBuffer)self;
+        int begin = JSType.toInt32(begin0);
+        int end = end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : arrayBuffer.getByteLength();
+        begin = adjustIndex(begin, arrayBuffer.getByteLength());
+        end = adjustIndex(end, arrayBuffer.getByteLength());
+        return new NativeArrayBuffer((NativeArrayBuffer) self, begin, Math.max(end, begin));
+    }
+
+    /**
+     * If index is negative, it refers to an index from the end of the array, as
+     * opposed to from the beginning. The index is clamped to the valid index
+     * range for the array.
+     *
+     * @param index  The index.
+     * @param length The length of the array.
+     * @return valid index index in the range [0, length).
+     */
+    static int adjustIndex(final int index, final int length) {
+        if (index < 0) {
+            return clamp(index + length, length);
+        }
+        return clamp(index, length);
+    }
+
+    /**
+     * Clamp index into the range [0, length).
+     */
+    private static int clamp(final int index, final int length) {
+        if (index < 0) {
+            return 0;
+        } else if (index > length) {
+            return length;
+        }
+        return index;
+    }
+
+    public byte[] getByteArray() {
+        return buffer;
+    }
+
+    public int getByteLength() {
+        return buffer.length;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
new file mode 100644
index 0000000..a63f0d4
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
@@ -0,0 +1,181 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
+
+/**
+ * ECMA 15.6 Boolean Objects.
+ */
+
+@ScriptClass("Boolean")
+public final class NativeBoolean extends ScriptObject {
+    private final boolean value;
+
+    final static MethodHandle WRAPFILTER = findWrapFilter();
+
+    NativeBoolean(final boolean value) {
+        this(value, Global.instance().getBooleanPrototype());
+    }
+
+    private NativeBoolean(final boolean value, final ScriptObject proto) {
+        this.value = value;
+        this.setProto(proto);
+    }
+
+    @Override
+    public String safeToString() {
+        return "[Boolean " + toString() + "]";
+    }
+
+    @Override
+    public String toString() {
+        return Boolean.toString(getValue());
+    }
+
+    /**
+     * Get the value for this NativeBoolean
+     * @return true or false
+     */
+    public boolean getValue() {
+        return booleanValue();
+    }
+
+    /**
+     * Get the value for this NativeBoolean
+     * @return true or false
+     */
+    public boolean booleanValue() {
+        return value;
+    }
+
+    @Override
+    public String getClassName() {
+        return "Boolean";
+    }
+
+    /**
+     * ECMA 15.6.4.2 Boolean.prototype.toString ( )
+     *
+     * @param self self reference
+     * @return string representation of this boolean
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toString(final Object self) {
+        return getBoolean(self).toString();
+    }
+
+    /**
+     * ECMA 15.6.4.3 Boolean.prototype.valueOf ( )
+     *
+     * @param self self reference
+     * @return value of this boolean
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object valueOf(final Object self) {
+        return getBoolean(self);
+    }
+
+    /**
+     * ECMA 15.6.2.1 new Boolean (value)
+     *
+     * @param newObj is the new operator used to instantiate this NativeBoolean
+     * @param self   self reference
+     * @param value  value of boolean
+     * @return the new NativeBoolean
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object value) {
+        final boolean flag = JSType.toBoolean(value);
+
+        if (newObj) {
+            final ScriptObject proto = (self instanceof ScriptObject) ?
+                ((ScriptObject)self).getProto() :
+                Global.instance().getBooleanPrototype();
+
+            return new NativeBoolean(flag, proto);
+        }
+
+        return flag;
+    }
+
+    private static Boolean getBoolean(final Object self) {
+        if (self instanceof Boolean) {
+            return ((Boolean)self);
+        } else if (self instanceof NativeBoolean) {
+            return ((NativeBoolean)self).getValue();
+        } else if (self != null && self == Global.instance().getBooleanPrototype()) {
+            return false;
+        } else {
+            throw typeError("not.a.boolean", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    /**
+     * Lookup the appropriate method for an invoke dynamic call.
+     *
+     * @param request  The link request
+     * @param receiver The receiver for the call
+     * @return Link to be invoked at call site.
+     */
+    public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
+        return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER);
+    }
+
+    /**
+     * Wrap a native string in a NativeString object.
+     *
+     * @param receiver Native string.
+     * @return Wrapped object.
+     */
+    @SuppressWarnings("unused")
+    private static NativeBoolean wrapFilter(final Object receiver) {
+        return new NativeBoolean((Boolean)receiver);
+    }
+
+    private static MethodHandle findWrapFilter() {
+        try {
+            return MethodHandles.lookup().findStatic(NativeBoolean.class, "wrapFilter", MH.type(NativeBoolean.class, Object.class));
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            throw new MethodHandleFactory.LookupException(e);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
new file mode 100644
index 0000000..c4bf8e5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
@@ -0,0 +1,1328 @@
+/*
+ * 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.objects;
+
+import static java.lang.Double.NaN;
+import static java.lang.Double.isInfinite;
+import static java.lang.Double.isNaN;
+import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
+import java.util.Locale;
+import java.util.TimeZone;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.linker.InvokeByName;
+
+/**
+ * ECMA 15.9 Date Objects
+ *
+ */
+@ScriptClass("Date")
+public final class NativeDate extends ScriptObject {
+
+    private static final String INVALID_DATE = "Invalid Date";
+
+    private static final int YEAR        = 0;
+    private static final int MONTH       = 1;
+    private static final int DAY         = 2;
+    private static final int HOUR        = 3;
+    private static final int MINUTE      = 4;
+    private static final int SECOND      = 5;
+    private static final int MILLISECOND = 6;
+
+    private static final int FORMAT_DATE_TIME       = 0;
+    private static final int FORMAT_DATE            = 1;
+    private static final int FORMAT_TIME            = 2;
+    private static final int FORMAT_LOCAL_DATE_TIME = 3;
+    private static final int FORMAT_LOCAL_DATE      = 4;
+    private static final int FORMAT_LOCAL_TIME      = 5;
+
+    // Constants defined in ECMA 15.9.1.10
+    private static final double hoursPerDay      = 24;
+    private static final double minutesPerHour   = 60;
+    private static final double secondsPerMinute = 60;
+    private static final double msPerSecond   = 1_000;
+    private static final double msPerMinute  = 60_000;
+    private static final double msPerHour = 3_600_000;
+    private static final double msPerDay = 86_400_000;
+
+    private static int[][] firstDayInMonth = {
+            {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, // normal year
+            {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}  // leap year
+    };
+
+    private static String[] weekDays = {
+            "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+    };
+
+    private static String[] months = {
+            "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+    };
+
+    private static final InvokeByName TO_ISO_STRING = new InvokeByName("toISOString", ScriptObject.class, Object.class,
+            Object.class);
+
+    private double time;
+    private final TimeZone timezone;
+
+    NativeDate() {
+        this(System.currentTimeMillis());
+    }
+
+    NativeDate(final double time) {
+        final ScriptEnvironment env = Global.getEnv();
+
+        this.time = time;
+        this.timezone = env._timezone;
+        this.setProto(Global.instance().getDatePrototype());
+    }
+
+    @Override
+    public String getClassName() {
+        return "Date";
+    }
+
+    // ECMA 8.12.8 [[DefaultValue]] (hint)
+    @Override
+    public Object getDefaultValue(final Class<?> hint) {
+        // When the [[DefaultValue]] internal method of O is called with no hint,
+        // then it behaves as if the hint were Number, unless O is a Date object
+        // in which case it behaves as if the hint were String.
+        return super.getDefaultValue(hint == null ? String.class : hint);
+    }
+
+    /**
+     * Constructor - ECMA 15.9.3.1 new Date
+     *
+     * @param isNew is this Date constructed with the new operator
+     * @param self  self references
+     * @return Date representing now
+     */
+    @SpecializedConstructor
+    public static Object construct(final boolean isNew, final Object self) {
+        final NativeDate result = new NativeDate();
+        return isNew ? result : toStringImpl(result, FORMAT_DATE_TIME);
+    }
+
+    /**
+     * Constructor - ECMA 15.9.3.1 new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )
+     *
+     * @param isNew is this Date constructed with the new operator
+     * @param self  self reference
+     * @param args  arguments
+     * @return new Date
+     */
+    @Constructor(arity = 7)
+    public static Object construct(final boolean isNew, final Object self, final Object... args) {
+        NativeDate result;
+        switch (args.length) {
+        case 0:
+            result = new NativeDate();
+            break;
+
+        case 1:
+            double num;
+            final Object arg = JSType.toPrimitive(args[0]);
+            if (arg instanceof String || arg instanceof ConsString) {
+                num = parseDateString(arg.toString());
+            } else {
+                num = timeClip(JSType.toNumber(args[0]));
+            }
+            result = new NativeDate(num);
+            break;
+
+        default:
+            result = new NativeDate(0);
+            final double[] d = convertCtorArgs(args);
+            if (d == null) {
+                result.setTime(Double.NaN);
+            } else {
+                final double time = timeClip(utc(makeDate(d), result.getTimeZone()));
+                result.setTime(time);
+            }
+            break;
+         }
+
+         return isNew ? result : toStringImpl(new NativeDate(), FORMAT_DATE_TIME);
+    }
+
+    @Override
+    public String safeToString() {
+        return "[Date " + toISOStringImpl(this) + "]";
+    }
+
+    @Override
+    public String toString() {
+        return isValidDate() ? toString(this).toString() : INVALID_DATE;
+    }
+
+    /**
+     * ECMA 15.9.4.2 Date.parse (string)
+     *
+     * @param self self reference
+     * @param string string to parse as date
+     * @return Date interpreted from the string, or NaN for illegal values
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object parse(final Object self, final Object string) {
+        return parseDateString(JSType.toString(string));
+    }
+
+    /**
+     * ECMA 15.9.4.3 Date.UTC (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )
+     *
+     * @param self self reference
+     * @param args mandatory args are year, month. Optional are date, hours, minutes, seconds and milliseconds
+     * @return a time clip according to the ECMA specification
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 7, where = Where.CONSTRUCTOR)
+    public static Object UTC(final Object self, final Object... args) {
+        final NativeDate nd = new NativeDate(0);
+        final double[] d = convertCtorArgs(args);
+        final double time = d == null ? Double.NaN : timeClip(makeDate(d));
+        nd.setTime(time);
+        return time;
+    }
+
+    /**
+     * ECMA 15.9.4.4 Date.now ( )
+     *
+     * @param self self reference
+     * @return a Date that points to the current moment in time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object now(final Object self) {
+        return (double)System.currentTimeMillis();
+    }
+
+    /**
+     * ECMA 15.9.5.2 Date.prototype.toString ( )
+     *
+     * @param self self reference
+     * @return string value that represents the Date in the current time zone
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toString(final Object self) {
+        return toStringImpl(self, FORMAT_DATE_TIME);
+    }
+
+    /**
+     * ECMA 15.9.5.3 Date.prototype.toDateString ( )
+     *
+     * @param self self reference
+     * @return string value with the "date" part of the Date in the current time zone
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toDateString(final Object self) {
+        return toStringImpl(self, FORMAT_DATE);
+    }
+
+    /**
+     * ECMA 15.9.5.4 Date.prototype.toTimeString ( )
+     *
+     * @param self self reference
+     * @return string value with "time" part of Date in the current time zone
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toTimeString(final Object self) {
+        return toStringImpl(self, FORMAT_TIME);
+    }
+
+    /**
+     * ECMA 15.9.5.5 Date.prototype.toLocaleString ( )
+     *
+     * @param self self reference
+     * @return string value that represents the Data in the current time zone and locale
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toLocaleString(final Object self) {
+        return toStringImpl(self, FORMAT_LOCAL_DATE_TIME);
+    }
+
+    /**
+     * ECMA 15.9.5.6 Date.prototype.toLocaleDateString ( )
+     *
+     * @param self self reference
+     * @return string value with the "date" part of the Date in the current time zone and locale
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toLocaleDateString(final Object self) {
+        return toStringImpl(self, FORMAT_LOCAL_DATE);
+    }
+
+    /**
+     * ECMA 15.9.5.7 Date.prototype.toLocaleTimeString ( )
+     *
+     * @param self self reference
+     * @return string value with the "time" part of Date in the current time zone and locale
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toLocaleTimeString(final Object self) {
+        return toStringImpl(self, FORMAT_LOCAL_TIME);
+    }
+
+    /**
+     * ECMA 15.9.5.8 Date.prototype.valueOf ( )
+     *
+     * @param self self reference
+     * @return valueOf - a number which is this time value
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object valueOf(final Object self) {
+        final NativeDate nd = getNativeDate(self);
+        return (nd != null) ? nd.getTime() : Double.NaN;
+    }
+
+    /**
+     * ECMA 15.9.5.9 Date.prototype.getTime ( )
+     *
+     * @param self self reference
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getTime(final Object self) {
+        final NativeDate nd = getNativeDate(self);
+        return (nd != null) ? nd.getTime() : Double.NaN;
+    }
+
+    /**
+     * ECMA 15.9.5.10 Date.prototype.getFullYear ( )
+     *
+     * @param self self reference
+     * @return full year
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getFullYear(final Object self) {
+        return getField(self, YEAR);
+    }
+
+    /**
+     * ECMA 15.9.5.11 Date.prototype.getUTCFullYear( )
+     *
+     * @param self self reference
+     * @return UTC full year
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getUTCFullYear(final Object self) {
+        return getUTCField(self, YEAR);
+    }
+
+    /**
+     * B.2.4 Date.prototype.getYear ( )
+     *
+     * @param self self reference
+     * @return year
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getYear(final Object self) {
+        final NativeDate nd = getNativeDate(self);
+        return (nd != null && nd.isValidDate()) ? (yearFromTime(nd.getLocalTime()) - 1900) : Double.NaN;
+    }
+
+    /**
+     * ECMA 15.9.5.12 Date.prototype.getMonth ( )
+     *
+     * @param self self reference
+     * @return month
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getMonth(final Object self) {
+        return getField(self, MONTH);
+    }
+
+    /**
+     * ECMA 15.9.5.13 Date.prototype.getUTCMonth ( )
+     *
+     * @param self self reference
+     * @return UTC month
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getUTCMonth(final Object self) {
+        return getUTCField(self, MONTH);
+    }
+
+    /**
+     * ECMA 15.9.5.14 Date.prototype.getDate ( )
+     *
+     * @param self self reference
+     * @return date
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getDate(final Object self) {
+        return getField(self, DAY);
+    }
+
+    /**
+     * ECMA 15.9.5.15 Date.prototype.getUTCDate ( )
+     *
+     * @param self self reference
+     * @return UTC Date
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getUTCDate(final Object self) {
+        return getUTCField(self, DAY);
+    }
+
+    /**
+     * ECMA 15.9.5.16 Date.prototype.getDay ( )
+     *
+     * @param self self reference
+     * @return day
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getDay(final Object self) {
+        final NativeDate nd = getNativeDate(self);
+        return (nd != null && nd.isValidDate()) ? weekDay(nd.getLocalTime()) : Double.NaN;
+    }
+
+    /**
+     * ECMA 15.9.5.17 Date.prototype.getUTCDay ( )
+     *
+     * @param self self reference
+     * @return UTC day
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getUTCDay(final Object self) {
+        final NativeDate nd = getNativeDate(self);
+        return (nd != null && nd.isValidDate()) ? weekDay(nd.getTime()) : Double.NaN;
+    }
+
+    /**
+     * ECMA 15.9.5.18 Date.prototype.getHours ( )
+     *
+     * @param self self reference
+     * @return hours
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getHours(final Object self) {
+        return getField(self, HOUR);
+    }
+
+    /**
+     * ECMA 15.9.5.19 Date.prototype.getUTCHours ( )
+     *
+     * @param self self reference
+     * @return UTC hours
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getUTCHours(final Object self) {
+        return getUTCField(self, HOUR);
+    }
+
+    /**
+     * ECMA 15.9.5.20 Date.prototype.getMinutes ( )
+     *
+     * @param self self reference
+     * @return minutes
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getMinutes(final Object self) {
+        return getField(self, MINUTE);
+    }
+
+    /**
+     * ECMA 15.9.5.21 Date.prototype.getUTCMinutes ( )
+     *
+     * @param self self reference
+     * @return UTC minutes
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getUTCMinutes(final Object self) {
+        return getUTCField(self, MINUTE);
+    }
+
+    /**
+     * ECMA 15.9.5.22 Date.prototype.getSeconds ( )
+     *
+     * @param self self reference
+     * @return seconds
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getSeconds(final Object self) {
+        return getField(self, SECOND);
+    }
+
+    /**
+     * ECMA 15.9.5.23 Date.prototype.getUTCSeconds ( )
+     *
+     * @param self self reference
+     * @return UTC seconds
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getUTCSeconds(final Object self) {
+        return getUTCField(self, SECOND);
+    }
+
+    /**
+     * ECMA 15.9.5.24 Date.prototype.getMilliseconds ( )
+     *
+     * @param self self reference
+     * @return milliseconds
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getMilliseconds(final Object self) {
+        return getField(self, MILLISECOND);
+    }
+
+    /**
+     * ECMA 15.9.5.25 Date.prototype.getUTCMilliseconds ( )
+     *
+     * @param self self reference
+     * @return UTC milliseconds
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getUTCMilliseconds(final Object self) {
+        return getUTCField(self, MILLISECOND);
+    }
+
+    /**
+     * ECMA 15.9.5.26 Date.prototype.getTimezoneOffset ( )
+     *
+     * @param self self reference
+     * @return time zone offset or NaN if N/A
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object getTimezoneOffset(final Object self) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd != null) {
+            final long msec = (long) nd.getTime();
+            return - nd.getTimeZone().getOffset(msec) / msPerMinute;
+        }
+        return Double.NaN;
+    }
+
+    /**
+     * ECMA 15.9.5.27 Date.prototype.setTime (time)
+     *
+     * @param self self reference
+     * @param time time
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object setTime(final Object self, final Object time) {
+        final double     num = timeClip(JSType.toNumber(time));
+        final NativeDate nd  = getNativeDate(self);
+        nd.setTime(num);
+        return num;
+    }
+
+    /**
+     * ECMA 15.9.5.28 Date.prototype.setMilliseconds (ms)
+     *
+     * @param self self reference
+     * @param args milliseconds
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object setMilliseconds(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, MILLISECOND, args, true);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.29 Date.prototype.setUTCMilliseconds (ms)
+     *
+     * @param self self reference
+     * @param args utc milliseconds
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object setUTCMilliseconds(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, MILLISECOND, args, false);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.30 Date.prototype.setSeconds (sec [, ms ] )
+     *
+     * @param self self reference
+     * @param args seconds (milliseconds optional second argument)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setSeconds(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, SECOND, args, true);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.31 Date.prototype.setUTCSeconds (sec [, ms ] )
+     *
+     * @param self self reference
+     * @param args UTC seconds (milliseconds optional second argument)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setUTCSeconds(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, SECOND, args, false);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.32 Date.prototype.setMinutes (min [, sec [, ms ] ] )
+     *
+     * @param self self reference
+     * @param args minutes (seconds and milliseconds are optional second and third arguments)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
+    public static Object setMinutes(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, MINUTE, args, true);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.33 Date.prototype.setUTCMinutes (min [, sec [, ms ] ] )
+     *
+     * @param self self reference
+     * @param args minutes (seconds and milliseconds are optional second and third arguments)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
+    public static Object setUTCMinutes(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, MINUTE, args, false);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.34 Date.prototype.setHours (hour [, min [, sec [, ms ] ] ] )
+     *
+     * @param self self reference
+     * @param args hour (optional arguments after are minutes, seconds, milliseconds)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 4)
+    public static Object setHours(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, HOUR, args, true);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.35 Date.prototype.setUTCHours (hour [, min [, sec [, ms ] ] ] )
+     *
+     * @param self self reference
+     * @param args hour (optional arguments after are minutes, seconds, milliseconds)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 4)
+    public static Object setUTCHours(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, HOUR, args, false);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.36 Date.prototype.setDate (date)
+     *
+     * @param self self reference
+     * @param args date
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object setDate(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, DAY, args, true);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.37 Date.prototype.setUTCDate (date)
+     *
+     * @param self self reference
+     * @param args UTC date
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object setUTCDate(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, DAY, args, false);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.38 Date.prototype.setMonth (month [, date ] )
+     *
+     * @param self self reference
+     * @param args month (optional second argument is date)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setMonth(final Object self, final Object... args) {
+        final NativeDate nd = getNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, MONTH, args, true);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.39 Date.prototype.setUTCMonth (month [, date ] )
+     *
+     * @param self self reference
+     * @param args UTC month (optional second argument is date)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setUTCMonth(final Object self, final Object... args) {
+        final NativeDate nd = ensureNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, MONTH, args, false);
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.40 Date.prototype.setFullYear (year [, month [, date ] ] )
+     *
+     * @param self self reference
+     * @param args year (optional second and third arguments are month and date)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
+    public static Object setFullYear(final Object self, final Object... args) {
+        final NativeDate nd   = ensureNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, YEAR, args, true);
+        } else {
+            final double[] d = convertArgs(args, 0, YEAR, YEAR, 3);
+            nd.setTime(timeClip(utc(makeDate(makeDay(d[0], d[1], d[2]), 0), nd.getTimeZone())));
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA 15.9.5.41 Date.prototype.setUTCFullYear (year [, month [, date ] ] )
+     *
+     * @param self self reference
+     * @param args UTC full year (optional second and third arguments are month and date)
+     * @return time
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
+    public static Object setUTCFullYear(final Object self, final Object... args) {
+        final NativeDate nd   = ensureNativeDate(self);
+        if (nd.isValidDate()) {
+            setFields(nd, YEAR, args, false);
+        } else {
+            final double[] d = convertArgs(args, 0, YEAR, YEAR, 3);
+            nd.setTime(timeClip(makeDate(makeDay(d[0], d[1], d[2]), 0)));
+        }
+        return nd.getTime();
+    }
+
+    /**
+     * ECMA B.2.5 Date.prototype.setYear (year)
+     *
+     * @param self self reference
+     * @param year year
+     * @return NativeDate
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object setYear(final Object self, final Object year) {
+        final NativeDate nd = getNativeDate(self);
+        if (isNaN(nd.getTime())) {
+            return null;
+        }
+
+        final double yearNum = JSType.toNumber(year);
+        if (isNaN(yearNum)) {
+            nd.setTime(NaN);
+            return nd;
+        }
+        int yearInt = JSType.toInteger(yearNum);
+        if (0 <= yearInt && yearInt <= 99) {
+            yearInt += 1900;
+        }
+        setFields(nd, YEAR, new Object[] {yearInt}, true);
+
+        return nd;
+    }
+
+    /**
+     * ECMA 15.9.5.42 Date.prototype.toUTCString ( )
+     *
+     * @param self self reference
+     * @return string representation of date
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toUTCString(final Object self) {
+        return toGMTStringImpl(self);
+    }
+
+    /**
+     * ECMA B.2.6 Date.prototype.toGMTString ( )
+     *
+     * See {@link NativeDate#toUTCString(Object)}
+     *
+     * @param self self reference
+     * @return string representation of date
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toGMTString(final Object self) {
+        return toGMTStringImpl(self);
+    }
+
+    /**
+     * ECMA 15.9.5.43 Date.prototype.toISOString ( )
+     *
+     * @param self self reference
+     * @return string representation of date
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toISOString(final Object self) {
+        return toISOStringImpl(self);
+    }
+
+    /**
+     * ECMA 15.9.5.44 Date.prototype.toJSON ( key )
+     *
+     * Provides a string representation of this Date for use by {@link NativeJSON#stringify(Object, Object, Object, Object)}
+     *
+     * @param self self reference
+     * @param key ignored
+     * @return JSON representation of this date
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toJSON(final Object self, final Object key) {
+        if (self instanceof NativeDate) {
+            final NativeDate nd = (NativeDate)self;
+            return (isNaN(nd.getTime())) ? null : toISOStringImpl(nd);
+        }
+        // NOTE: Date.prototype.toJSON is generic. Accepts other objects as well.
+        final Object selfObj = Global.toObject(self);
+        if (!(selfObj instanceof ScriptObject)) {
+            return null;
+        }
+        final ScriptObject sobj  = (ScriptObject)selfObj;
+        final Object       value = sobj.getDefaultValue(Number.class);
+
+        final double num = (value instanceof Number) ? ((Number)value).doubleValue() : NaN;
+
+        if (isInfinite(num) || isNaN(num)) {
+            return null;
+        }
+
+        try {
+            final Object func = TO_ISO_STRING.getGetter().invokeExact(sobj);
+            if (func instanceof ScriptFunction) {
+                return TO_ISO_STRING.getInvoker().invokeExact(func, sobj, key);
+            }
+            throw typeError("not.a.function", ScriptRuntime.safeToString(func));
+        } catch (final RuntimeException | Error e) {
+            throw e;
+        } catch (final Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    // -- Internals below this point
+
+    private static double parseDateString(final String str) {
+
+        final DateParser parser = new DateParser(str);
+        if (parser.parse()) {
+            final Integer[] fields = parser.getDateFields();
+            double d = makeDate(fields);
+            if (fields[DateParser.TIMEZONE] != null) {
+                d -= fields[DateParser.TIMEZONE] * 60000;
+            } else {
+                d = utc(d, Global.getEnv()._timezone);
+            }
+            d = timeClip(d);
+            return d;
+        }
+
+        return Double.NaN;
+    }
+
+    private static void zeroPad(final StringBuilder sb, final int n, final int length) {
+        for (int l = 1, d = 10; l < length; l++, d *= 10) {
+            if (n < d) {
+                sb.append('0');
+            }
+        }
+        sb.append(n);
+    }
+
+    private static String toStringImpl(final Object self, final int format) {
+        final NativeDate nd = getNativeDate(self);
+
+        if (nd != null && nd.isValidDate()) {
+            final StringBuilder sb = new StringBuilder(40);
+            final double t = nd.getLocalTime();
+
+            switch (format) {
+
+                case FORMAT_DATE_TIME:
+                case FORMAT_DATE :
+                case FORMAT_LOCAL_DATE_TIME:
+                    // EEE MMM dd yyyy
+                    sb.append(weekDays[(int) weekDay(t)])
+                            .append(' ')
+                            .append(months[(int) monthFromTime(t)])
+                            .append(' ');
+                    zeroPad(sb, (int) dayFromTime(t), 2);
+                    sb.append(' ');
+                    zeroPad(sb, (int) yearFromTime(t), 4);
+                    if (format == FORMAT_DATE) {
+                        break;
+                    }
+                    sb.append(' ');
+
+                    //$FALL-THROUGH$
+                case FORMAT_TIME:
+                    final TimeZone tz = nd.getTimeZone();
+                    final double utcTime = nd.getTime();
+                    int offset = tz.getOffset((long) utcTime) / 60000;
+                    final boolean inDaylightTime = offset != tz.getRawOffset() / 60000;
+                    // Convert minutes to HHmm timezone offset
+                    offset = (offset / 60) * 100 + offset % 60;
+
+                    // HH:mm:ss GMT+HHmm
+                    zeroPad(sb, (int) hourFromTime(t), 2);
+                    sb.append(':');
+                    zeroPad(sb, (int) minFromTime(t), 2);
+                    sb.append(':');
+                    zeroPad(sb, (int) secFromTime(t), 2);
+                    sb.append(" GMT")
+                            .append(offset < 0 ? '-' : '+');
+                    zeroPad(sb, Math.abs(offset), 4);
+                    sb.append(" (")
+                            .append(tz.getDisplayName(inDaylightTime, TimeZone.SHORT, Locale.US))
+                            .append(')');
+                    break;
+
+                case FORMAT_LOCAL_DATE:
+                    // yyyy-MM-dd
+                    zeroPad(sb, (int) yearFromTime(t), 4);
+                    sb.append('-');
+                    zeroPad(sb, (int) monthFromTime(t) + 1, 2);
+                    sb.append('-');
+                    zeroPad(sb, (int) dayFromTime(t), 2);
+                    break;
+
+                case FORMAT_LOCAL_TIME:
+                    // HH:mm:ss
+                    zeroPad(sb, (int) hourFromTime(t), 2);
+                    sb.append(':');
+                    zeroPad(sb, (int) minFromTime(t), 2);
+                    sb.append(':');
+                    zeroPad(sb, (int) secFromTime(t), 2);
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("format: " + format);
+            }
+
+            return sb.toString();
+        }
+
+        return INVALID_DATE;
+    }
+
+    private static String toGMTStringImpl(final Object self) {
+        final NativeDate nd = getNativeDate(self);
+
+        if (nd != null && nd.isValidDate()) {
+            final StringBuilder sb = new StringBuilder(29);
+            final double t = nd.getTime();
+            // EEE, dd MMM yyyy HH:mm:ss z
+            sb.append(weekDays[(int) weekDay(t)])
+                    .append(", ");
+            zeroPad(sb, (int) dayFromTime(t), 2);
+            sb.append(' ')
+                    .append(months[(int) monthFromTime(t)])
+                    .append(' ');
+            zeroPad(sb, (int) yearFromTime(t), 4);
+            sb.append(' ');
+            zeroPad(sb, (int) hourFromTime(t), 2);
+            sb.append(':');
+            zeroPad(sb, (int) minFromTime(t), 2);
+            sb.append(':');
+            zeroPad(sb, (int) secFromTime(t), 2);
+            sb.append(" GMT");
+            return sb.toString();
+        }
+
+        throw rangeError("invalid.date");
+    }
+
+    private static String toISOStringImpl(final Object self) {
+        final NativeDate nd = getNativeDate(self);
+
+        if (nd != null && nd.isValidDate()) {
+            final StringBuilder sb = new StringBuilder(24);
+            final double t = nd.getTime();
+            // yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
+            zeroPad(sb, (int) yearFromTime(t), 4);
+            sb.append('-');
+            zeroPad(sb, (int) monthFromTime(t) + 1, 2);
+            sb.append('-');
+            zeroPad(sb, (int) dayFromTime(t), 2);
+            sb.append('T');
+            zeroPad(sb, (int) hourFromTime(t), 2);
+            sb.append(':');
+            zeroPad(sb, (int) minFromTime(t), 2);
+            sb.append(':');
+            zeroPad(sb, (int) secFromTime(t), 2);
+            sb.append('.');
+            zeroPad(sb, (int) msFromTime(t), 3);
+            sb.append("Z");
+            return sb.toString();
+        }
+
+        throw rangeError("invalid.date");
+    }
+
+    // ECMA 15.9.1.2 Day (t)
+    private static double day(final double t) {
+        return Math.floor(t / msPerDay);
+    }
+
+    // ECMA 15.9.1.2 TimeWithinDay (t)
+    private static double timeWithinDay(final double t) {
+        return t % msPerDay;
+    }
+
+    // ECMA 15.9.1.3 InLeapYear (t)
+    private static boolean isLeapYear(final int y) {
+        return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
+    }
+
+    // ECMA 15.9.1.3 DaysInYear (y)
+    private static int daysInYear(final int y) {
+        return isLeapYear(y) ? 366 : 365;
+    }
+
+    // ECMA 15.9.1.3 DayFromYear (y)
+    private static double dayFromYear(final double y) {
+        return 365 * (y - 1970)
+                + Math.floor((y -1969) / 4.0)
+                - Math.floor((y - 1901) / 100.0)
+                + Math.floor((y - 1601) / 400.0);
+    }
+
+    // ECMA 15.9.1.3 Year Number
+    private static double timeFromYear(final double y) {
+        return dayFromYear(y) * msPerDay;
+    }
+
+    private static double yearFromTime(final double t) {
+        double y = Math.floor(t / (msPerDay * 365.2425)) + 1970;
+        final double t2 = timeFromYear(y);
+        if (t2 > t) {
+            y--;
+        } else if (t2 + msPerDay * daysInYear((int) y) <= t) {
+            y++;
+        }
+        return y;
+    }
+
+    private static double dayWithinYear(final double t, final double year) {
+        return day(t) - dayFromYear(year);
+    }
+
+    private static double monthFromTime(final double t) {
+        final double year = yearFromTime(t);
+        final double day = dayWithinYear(t, year);
+        final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0];
+        int month = 0;
+
+        while (month < 11 && firstDay[month + 1] <= day) {
+            month++;
+        }
+        return month;
+    }
+
+    private static double dayFromTime(final double t)  {
+        final double year = yearFromTime(t);
+        final double day = dayWithinYear(t, year);
+        final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0];
+        int month = 0;
+
+        while (month < 11 && firstDay[month + 1] <= day) {
+            month++;
+        }
+        return 1 + day - firstDay[month];
+    }
+
+    private static int dayFromMonth(final int month, final int year) {
+        assert(month >= 0 && month <= 11);
+        final int[] firstDay = firstDayInMonth[isLeapYear(year) ? 1 : 0];
+        return firstDay[month];
+    }
+
+    private static double weekDay(final double time) {
+        if (isNaN(time)) {
+            return NaN;
+        }
+        final double day = (day(time) + 4) % 7;
+        return day < 0 ? day + 7 : day;
+    }
+
+    // ECMA 15.9.1.9 LocalTime
+    private static double localTime(final double time, final TimeZone tz) {
+        return time + tz.getOffset((long) time);
+    }
+
+    // ECMA 15.9.1.9 UTC
+    private static double utc(final double time, final TimeZone tz) {
+        return time - tz.getOffset((long) (time - tz.getRawOffset()));
+    }
+
+    // ECMA 15.9.1.10 Hours, Minutes, Second, and Milliseconds
+    private static double hourFromTime(final double t) {
+        final double h = Math.floor(t / msPerHour) % hoursPerDay;
+        return h < 0 ? h + hoursPerDay: h;
+    }
+    private static double minFromTime(final double t) {
+        final double m = Math.floor(t / msPerMinute) % minutesPerHour;
+        return m < 0 ? m + minutesPerHour : m;
+    }
+
+    private static double secFromTime(final double t) {
+        final double s = Math.floor(t / msPerSecond) % secondsPerMinute;
+        return s < 0 ? s + secondsPerMinute : s;
+    }
+
+    private static double msFromTime(final double t) {
+        final double m = t % msPerSecond;
+        return m < 0 ? m + msPerSecond : m;
+    }
+
+    private static double valueFromTime(final int unit, final double t) {
+        switch (unit) {
+            case YEAR: return yearFromTime(t);
+            case MONTH: return monthFromTime(t);
+            case DAY: return dayFromTime(t);
+            case HOUR: return hourFromTime(t);
+            case MINUTE: return minFromTime(t);
+            case SECOND: return secFromTime(t);
+            case MILLISECOND: return msFromTime(t);
+            default: throw new IllegalArgumentException(Integer.toString(unit));
+        }
+    }
+
+    // ECMA 15.9.1.11 MakeTime (hour, min, sec, ms)
+    private static double makeTime(final double hour, final double min, final double sec, final double ms) {
+        return hour * 3600000 + min * 60000 + sec * 1000 + ms;
+    }
+
+    // ECMA 15.9.1.12 MakeDay (year, month, date)
+    private static double makeDay(final double year, final double month, final double date) {
+        final double y = year + Math.floor(month / 12);
+        double m = month % 12;
+        if (m < 0) {
+            m += 12;
+        }
+        double d = Math.floor(dayFromYear(y));
+        d += dayFromMonth((int) m, (int) y);
+
+        return d + date - 1;
+    }
+
+    // ECMA 15.9.1.13 MakeDate (day, time)
+    private static double makeDate(final double day, final double time) {
+        return day * msPerDay + time;
+    }
+
+
+    private static double makeDate(final Integer[] d) {
+        final double time = makeDay(d[0], d[1], d[2]) * msPerDay;
+        return time + makeTime(d[3], d[4], d[5], d[6]);
+    }
+
+    private static double makeDate(final double[] d) {
+        final double time = makeDay(d[0], d[1], d[2]) * msPerDay;
+        return time + makeTime(d[3], d[4], d[5], d[6]);
+    }
+
+    // Convert Date constructor args, checking for NaN, filling in defaults etc.
+    private static double[] convertCtorArgs(final Object[] args) {
+        final double[] d = new double[7];
+
+        for (int i = 0; i < d.length; i++) {
+            if (i < args.length) {
+                final double darg = JSType.toNumber(args[i]);
+                if (isNaN(darg) || isInfinite(darg)) {
+                    return null;
+                }
+                d[i] = (long)darg;
+            } else {
+                d[i] = i == 2 ? 1 : 0; // day in month defaults to 1
+            }
+        }
+
+        if (0 <= d[0] && d[0] <= 99) {
+            d[0] += 1900;
+        }
+
+        return d;
+    }
+
+    // This method does the hard work for all setter methods: If a value is provided
+    // as argument it is used, otherwise the value is calculated from the existing time value.
+    private static double[] convertArgs(final Object[] args, final double time, final int fieldId, final int start, final int length) {
+        final double[] d = new double[length];
+
+        for (int i = start; i < start + length; i++) {
+            if (fieldId <= i && i < fieldId + args.length) {
+                final double darg = JSType.toNumber(args[i - fieldId]);
+                if (isNaN(darg) || isInfinite(darg)) {
+                    return null;
+                }
+                d[i - start] = (long) darg;
+            } else {
+                // Date.prototype.set* methods require first argument to be defined
+                if (i == fieldId) {
+                    return null;
+                }
+                d[i - start] = valueFromTime(i, time);
+            }
+        }
+        return d;
+
+    }
+
+    // ECMA 15.9.1.14 TimeClip (time)
+    private static double timeClip(final double time) {
+        if (isInfinite(time) || isNaN(time) || Math.abs(time) > 8.64e15) {
+            return Double.NaN;
+        }
+        return (long)time;
+    }
+
+    private static NativeDate ensureNativeDate(final Object self) {
+        return getNativeDate(self);
+    }
+
+    private static NativeDate getNativeDate(final Object self) {
+        if (self instanceof NativeDate) {
+            return (NativeDate)self;
+        } else if (self != null && self == Global.instance().getDatePrototype()) {
+            return Global.instance().DEFAULT_DATE;
+        } else {
+            throw typeError("not.a.date", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    private static Object getField(final Object self, final int field) {
+        final NativeDate nd = getNativeDate(self);
+        return (nd != null && nd.isValidDate()) ? valueFromTime(field, nd.getLocalTime()) : Double.NaN;
+    }
+
+    private static Object getUTCField(final Object self, final int field) {
+        final NativeDate nd = getNativeDate(self);
+        return (nd != null && nd.isValidDate()) ? valueFromTime(field, nd.getTime()) : Double.NaN;
+    }
+
+    private static void setFields(final NativeDate nd, final int fieldId, final Object[] args, final boolean local) {
+        int start, length;
+        if (fieldId < HOUR) {
+            start = YEAR;
+            length = 3;
+        } else {
+            start = HOUR;
+            length = 4;
+        }
+        final double time = local ? nd.getLocalTime() : nd.getTime();
+        final double d[] = convertArgs(args, time, fieldId, start, length);
+
+        double newTime;
+        if (d == null) {
+            newTime = NaN;
+        } else {
+            if (start == YEAR) {
+                newTime = makeDate(makeDay(d[0], d[1], d[2]), timeWithinDay(time));
+            } else {
+                newTime = makeDate(day(time), makeTime(d[0], d[1], d[2], d[3]));
+            }
+            if (local) {
+                newTime = utc(newTime, nd.getTimeZone());
+            }
+            newTime = timeClip(newTime);
+        }
+        nd.setTime(newTime);
+    }
+
+    private boolean isValidDate() {
+        return !isNaN(time);
+    }
+
+    private double getLocalTime() {
+        return localTime(time, timezone);
+    }
+
+    private double getTime() {
+        return time;
+    }
+
+    private void setTime(final double time) {
+        this.time = time;
+    }
+
+    private TimeZone getTimeZone() {
+        return timezone;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
new file mode 100644
index 0000000..3d6fcbc
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
@@ -0,0 +1,283 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.io.PrintWriter;
+import java.util.Objects;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.PropertyListenerManager;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
+
+/**
+ * Nashorn specific debug utils. This is meant for Nashorn developers.
+ * The interface is subject to change without notice!!
+ *
+ */
+@ScriptClass("Debug")
+public final class NativeDebug extends ScriptObject {
+    NativeDebug() {
+        this.setProto(Global.objectPrototype());
+    }
+
+    @Override
+    public String getClassName() {
+        return "Debug";
+    }
+
+    /**
+     * Nashorn extension: get context, context utility
+     *
+     * @param self self reference
+     * @return context
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object getContext(final Object self) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("getNashornContext"));
+        }
+        return Global.getThisContext();
+    }
+
+    /**
+     * Nashorn extension: get map from {@link ScriptObject}
+     *
+     * @param self self reference
+     * @param obj script object
+     * @return the map for the current ScriptObject
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object map(final Object self, final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).getMap();
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Nashorn extension: get embed0 from {@link ScriptObject}
+     *
+     * @param self self reference
+     * @param obj script object
+     * @return the embed0 property value for the given ScriptObject
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object embed0(final Object self, final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).embed0;
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Nashorn extension: get embed1 from {@link ScriptObject}
+     *
+     * @param self self reference
+     * @param obj script object
+     * @return the embed1 property value for the given ScriptObject
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object embed1(final Object self, final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).embed1;
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Nashorn extension: get embed2 from {@link ScriptObject}
+     *
+     * @param self self reference
+     * @param obj script object
+     * @return the embed2 property value for the given ScriptObject
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object embed2(final Object self, final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).embed2;
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Nashorn extension: get embed3 from {@link ScriptObject}
+     *
+     * @param self self reference
+     * @param obj script object
+     * @return the embed3 property value for the given ScriptObject
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object embed3(final Object self, final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).embed3;
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Nashorn extension: get spill vector from {@link ScriptObject}
+     *
+     * @param self self reference
+     * @param obj script object
+     * @return the spill vector for the given ScriptObject
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object spill(final Object self, final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).spill;
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Nashorn extension: get invocation handle from {@link ScriptFunction}
+     *
+     * @param self self reference
+     * @param obj script function
+     * @return the invocation handle for the given ScriptFunction
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object methodHandle(final Object self, final Object obj) {
+        if (obj instanceof ScriptFunction) {
+            return ((ScriptFunction)obj).getInvokeHandle();
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Check object identity comparison regardless of type
+     *
+     * @param self self reference
+     * @param obj1 first object in comparison
+     * @param obj2 second object in comparison
+     * @return true if reference identity
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object identical(final Object self, final Object obj1, final Object obj2) {
+        return obj1 == obj2;
+    }
+
+    /**
+     * Object util - getClass
+     *
+     * @param self self reference
+     * @param obj  object
+     * @return class of {@code obj}
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object getClass(final Object self, final Object obj) {
+        if (obj != null) {
+            return obj.getClass();
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Object util - equals
+     *
+     * @param self self reference
+     * @param obj1 first object in comparison
+     * @param obj2 second object in comparison
+     * @return return {@link Object#equals(Object)} for objects.
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object equals(final Object self, final Object obj1, final Object obj2) {
+        return (obj1 != null) ? obj1.equals(obj2) : false;
+    }
+
+    /**
+     * Object util - toJavaString
+     *
+     * @param self self reference
+     * @param obj  object to represent as a string
+     * @return Java string representation of {@code obj}
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object toJavaString(final Object self, final Object obj) {
+        return Objects.toString(obj);
+    }
+
+    /**
+     * Do not call overridden toString -- use default toString impl
+     *
+     * @param self self reference
+     * @param obj  object to represent as a string
+     * @return string representation
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object toIdentString(final Object self, final Object obj) {
+        if (obj == null) {
+            return "null";
+        }
+
+        final int hash = System.identityHashCode(obj);
+        return obj.getClass() + "@" + Integer.toHexString(hash);
+    }
+
+    /**
+     * Dump all Nashorn debug mode counters. Calling this may be better if
+     * you want to print all counters. This way you can avoid too many callsites
+     * due to counter access itself!!
+     * @param self self reference
+     * @return undefined
+     */
+    @SuppressWarnings("resource")
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object dumpCounters(final Object self) {
+        final PrintWriter out = Context.getCurrentErr();
+
+        out.println("ScriptObject count " + ScriptObject.getCount());
+        out.println("Scope count " + ScriptObject.getScopeCount());
+        out.println("ScriptObject listeners added " + PropertyListenerManager.getListenersAdded());
+        out.println("ScriptObject listeners removed " + PropertyListenerManager.getListenersRemoved());
+        out.println("ScriptObject listeners dead " + PropertyListenerManager.getListenersDead());
+        out.println("ScriptFunction count " + ScriptObject.getCount());
+        out.println("ScriptFunction invokes " + ScriptFunction.getInvokes());
+        out.println("ScriptFunction allocations " + ScriptFunction.getAllocations());
+        out.println("PropertyMap count " + PropertyMap.getCount());
+        out.println("PropertyMap cloned " + PropertyMap.getClonedCount());
+        out.println("PropertyMap history hit " + PropertyMap.getHistoryHit());
+        out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations());
+        out.println("PropertyMap proto history hit " + PropertyMap.getProtoHistoryHit());
+        out.println("PropertyMap setProtoNewMapCount " + PropertyMap.getSetProtoNewMapCount());
+        out.println("Callsite count " + LinkerCallSite.getCount());
+        out.println("Callsite misses " + LinkerCallSite.getMissCount());
+        out.println("Callsite misses by site at " + LinkerCallSite.getMissSamplingPercentage() + "%");
+
+        LinkerCallSite.getMissCounts(out);
+
+        return UNDEFINED;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
new file mode 100644
index 0000000..8cea0c7
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
@@ -0,0 +1,326 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ECMAException;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * ECMA 15.11 Error Objects
+ */
+@ScriptClass("Error")
+public final class NativeError extends ScriptObject {
+
+    static final MethodHandle GET_COLUMNNUMBER = findOwnMH("getColumnNumber", Object.class, Object.class);
+    static final MethodHandle SET_COLUMNNUMBER = findOwnMH("setColumnNumber", Object.class, Object.class, Object.class);
+    static final MethodHandle GET_LINENUMBER   = findOwnMH("getLineNumber", Object.class, Object.class);
+    static final MethodHandle SET_LINENUMBER   = findOwnMH("setLineNumber", Object.class, Object.class, Object.class);
+    static final MethodHandle GET_FILENAME     = findOwnMH("getFileName", Object.class, Object.class);
+    static final MethodHandle SET_FILENAME     = findOwnMH("setFileName", Object.class, Object.class, Object.class);
+    static final MethodHandle GET_STACK        = findOwnMH("getStack", Object.class, Object.class);
+    static final MethodHandle SET_STACK        = findOwnMH("setStack", Object.class, Object.class, Object.class);
+
+    // message property name
+    static final String MESSAGE = "message";
+    // name property name
+    static final String NAME = "name";
+    // stack property name
+    static final String STACK = "__stack__";
+    // lineNumber property name
+    static final String LINENUMBER = "__lineNumber__";
+    // columnNumber property name
+    static final String COLUMNNUMBER = "__columnNumber__";
+    // fileName property name
+    static final String FILENAME = "__fileName__";
+
+    /** Message property name */
+    @Property(name = NativeError.MESSAGE)
+    public Object instMessage;
+
+    /** ECMA 15.11.4.2 Error.prototype.name */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object name;
+
+    /** ECMA 15.11.4.3 Error.prototype.message */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object message;
+
+    NativeError(final Object msg) {
+        this.setProto(Global.instance().getErrorPrototype());
+        if (msg != UNDEFINED) {
+            this.instMessage = JSType.toString(msg);
+        } else {
+            this.delete(NativeError.MESSAGE, Global.isStrict());
+        }
+    }
+
+    @Override
+    public String getClassName() {
+        return "Error";
+    }
+
+    /**
+     * ECMA 15.11.2 The Error Constructor
+     *
+     * @param newObj true if this is being instantiated with a new
+     * @param self   self reference
+     * @param msg    error message
+     *
+     * @return NativeError instance
+     */
+    @Constructor
+    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+        return new NativeError(msg);
+    }
+
+    /**
+     * Nashorn extension: Error.dumpStack
+     * dumps the stack of the current thread.
+     *
+     * @param self self reference
+     *
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object dumpStack(final Object self) {
+        Thread.dumpStack();
+        return UNDEFINED;
+    }
+
+    /**
+     * Nashorn extension: Error.prototype.printStackTrace
+     * prints stack trace associated with the exception (if available).
+     * to the standard error stream.
+     *
+     * @param self self reference
+     *
+     * @return result of {@link ECMAException#printStackTrace(ScriptObject)}, which is typically undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object printStackTrace(final Object self) {
+        Global.checkObject(self);
+        return ECMAException.printStackTrace((ScriptObject)self);
+    }
+
+    /**
+     * Nashorn extension: Error.prototype.lineNumber
+     *
+     * @param self self reference
+     *
+     * @return line number from which error was thrown
+     */
+    public static Object getLineNumber(final Object self) {
+        Global.checkObject(self);
+        final ScriptObject sobj = (ScriptObject)self;
+        return sobj.has(LINENUMBER) ? sobj.get(LINENUMBER) : ECMAException.getLineNumber(sobj);
+    }
+
+    /**
+     * Nashorn extension: Error.prototype.lineNumber
+     *
+     * @param self  self reference
+     * @param value value of line number
+     *
+     * @return value that was set
+     */
+    public static Object setLineNumber(final Object self, final Object value) {
+        Global.checkObject(self);
+        final ScriptObject sobj = (ScriptObject)self;
+        sobj.set(LINENUMBER, value, Global.isStrict());
+        return value;
+    }
+
+    /**
+     * Nashorn extension: Error.prototype.columnNumber
+     *
+     * @param self self reference
+     *
+     * @return column number from which error was thrown
+     */
+    public static Object getColumnNumber(final Object self) {
+        Global.checkObject(self);
+        final ScriptObject sobj = (ScriptObject)self;
+        return sobj.has(COLUMNNUMBER) ? sobj.get(COLUMNNUMBER) : ECMAException.getColumnNumber((ScriptObject)self);
+    }
+
+    /**
+     * Nashorn extension: Error.prototype.columnNumber
+     *
+     * @param self  self reference
+     * @param value value of column number
+     *
+     * @return value that was set
+     */
+    public static Object setColumnNumber(final Object self, final Object value) {
+        Global.checkObject(self);
+        final ScriptObject sobj = (ScriptObject)self;
+        sobj.set(COLUMNNUMBER, value, Global.isStrict());
+        return value;
+    }
+
+    /**
+     * Nashorn extension: Error.prototype.fileName
+     *
+     * @param self self reference
+     *
+     * @return file name from which error was thrown
+     */
+    public static Object getFileName(final Object self) {
+        Global.checkObject(self);
+        final ScriptObject sobj = (ScriptObject)self;
+        return sobj.has(FILENAME) ? sobj.get(FILENAME) : ECMAException.getFileName((ScriptObject)self);
+    }
+
+    /**
+     * Nashorn extension: Error.prototype.fileName
+     *
+     * @param self  self reference
+     * @param value value of file name
+     *
+     * @return value that was set
+     */
+    public static Object setFileName(final Object self, final Object value) {
+        Global.checkObject(self);
+        final ScriptObject sobj = (ScriptObject)self;
+        sobj.set(FILENAME, value, Global.isStrict());
+        return value;
+    }
+
+    /**
+     * Nashorn extension: Error.prototype.stack
+     * "stack" property is an array typed value containing {@link StackTraceElement}
+     * objects of JavaScript stack frames.
+     *
+     * @param self  self reference
+     *
+     * @return      value of "stack" property
+     */
+    public static Object getStack(final Object self) {
+        Global.checkObject(self);
+        final ScriptObject sobj = (ScriptObject)self;
+        if (sobj.has(STACK)) {
+            return sobj.get(STACK);
+        }
+
+        final Object exception = ECMAException.getException(sobj);
+        Object[] res;
+        if (exception instanceof Throwable) {
+            final StackTraceElement[] frames = ((Throwable)exception).getStackTrace();
+            final List<StackTraceElement> filtered = new ArrayList<>();
+            for (final StackTraceElement st : frames) {
+                if (ECMAErrors.isScriptFrame(st)) {
+                    filtered.add(st);
+                }
+            }
+            res = filtered.toArray();
+        } else {
+            res = ScriptRuntime.EMPTY_ARRAY;
+        }
+
+        return new NativeArray(res);
+    }
+
+    /**
+     * Nashorn extension
+     * Accessed from {@link Global} while setting up the Error.prototype
+     *
+     * @param self   self reference
+     * @param value  value to set "stack" property to, must be {@code ScriptObject}
+     *
+     * @return value that was set
+     */
+    public static Object setStack(final Object self, final Object value) {
+        Global.checkObject(self);
+        final ScriptObject sobj = (ScriptObject)self;
+        sobj.set(STACK, value, Global.isStrict());
+        return value;
+    }
+
+    /**
+     * ECMA 15.11.4.4 Error.prototype.toString ( )
+     *
+     * @param self  self reference
+     *
+     * @return this NativeError as a string
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toString(final Object self) {
+        // Step 1 and 2 : check if 'self' is object it not throw TypeError
+        Global.checkObject(self);
+
+        final ScriptObject sobj = (ScriptObject)self;
+
+        // Step 3 & 4 : get "name" and convert to String.
+        // But if message is undefined make it "Error".
+        Object name = sobj.get("name");
+        if (name == UNDEFINED) {
+            name = "Error";
+        } else {
+            name = JSType.toString(name);
+        }
+
+        // Steps 5, 6, & 7 : get "message" and convert to String.
+        // if 'message' is undefined make it "" (empty String).
+        Object msg = sobj.get("message");
+        if (msg == UNDEFINED) {
+            msg = "";
+        } else {
+            msg = JSType.toString(msg);
+        }
+
+        // Step 8 : if name is empty, return msg
+        if (((String)name).isEmpty()) {
+            return msg;
+        }
+
+        // Step 9 : if message is empty, return name
+        if (((String)msg).isEmpty()) {
+            return name;
+        }
+        // Step 10 : return name + ": " + msg
+        return (String)name + ": " + (String)msg;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.publicLookup(), NativeError.class, name, MH.type(rtype, types));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java
new file mode 100644
index 0000000..a33fb0d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java
@@ -0,0 +1,87 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * ECMA 15.11.6.1 EvalError
+ *
+ */
+@ScriptClass("Error")
+public final class NativeEvalError extends ScriptObject {
+
+    /** message property in instance */
+    @Property(name = NativeError.MESSAGE)
+    public Object instMessage;
+
+    /** error name property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object name;
+
+    /** ECMA 15.1.1.1 message property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+
+    public Object message;
+    NativeEvalError(final Object msg) {
+        this.setProto(Global.instance().getEvalErrorPrototype());
+        if (msg != UNDEFINED) {
+            this.instMessage = JSType.toString(msg);
+        } else {
+            this.delete(NativeError.MESSAGE, Global.isStrict());
+        }
+    }
+
+    @Override
+    public String getClassName() {
+        return "Error";
+    }
+
+
+    /**
+     * ECMA 15.11.6.1 EvalError
+     *
+     * Constructor
+     *
+     * @param newObj was this error instantiated with the new operator
+     * @param self   self reference
+     * @param msg    error message
+     *
+     * @return new EvalError
+     */
+    @Constructor(name = "EvalError")
+    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+        return new NativeEvalError(msg);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
new file mode 100644
index 0000000..98db34b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
@@ -0,0 +1,186 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Float32 array for the TypedArray extension
+ */
+@ScriptClass("Float32Array")
+public final class NativeFloat32Array extends ArrayBufferView {
+    private static final int BYTES_PER_ELEMENT = 4;
+    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
+        @Override
+        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new NativeFloat32Array(buffer, byteOffset, length);
+        }
+        @Override
+        public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new Float32ArrayData(buffer, byteOffset, length);
+        }
+    };
+
+    private static final class Float32ArrayData extends ArrayDataImpl {
+        private Float32ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+            super(buffer, byteOffset, elementLength);
+        }
+
+        @Override
+        protected int byteIndex(final int index) {
+            return index * BYTES_PER_ELEMENT + byteOffset;
+        }
+
+        @Override
+        protected double getDoubleImpl(final int index) {
+            final int byteIndex = byteIndex(index);
+            final byte[] byteArray = buffer.getByteArray();
+            final int bits = byteArray[byteIndex  ]       & 0x0000_00ff |
+                             byteArray[byteIndex+1] <<  8 & 0x0000_ff00 |
+                             byteArray[byteIndex+2] << 16 & 0x00ff_0000 |
+                             byteArray[byteIndex+3] << 24 & 0xff00_0000 ;
+            return Float.intBitsToFloat(bits);
+        }
+
+        @Override
+        protected int getIntImpl(final int index) {
+            return (int)getDoubleImpl(index);
+        }
+
+        @Override
+        protected long getLongImpl(final int key) {
+            return (long)getDoubleImpl(key);
+        }
+
+        @Override
+        protected Object getObjectImpl(final int key) {
+            return getDoubleImpl(key);
+        }
+
+        @Override
+        protected void setImpl(final int index, final double value) {
+            final int bits = Float.floatToRawIntBits((float)value);
+            final int byteIndex = byteIndex(index);
+            @SuppressWarnings("MismatchedReadAndWriteOfArray")
+            final byte[] byteArray = buffer.getByteArray();
+            byteArray[byteIndex  ] = (byte)(bits        & 0xff);
+            byteArray[byteIndex+1] = (byte)(bits >>>  8 & 0xff);
+            byteArray[byteIndex+2] = (byte)(bits >>> 16 & 0xff);
+            byteArray[byteIndex+3] = (byte)(bits >>> 24 & 0xff);
+        }
+
+        @Override
+        protected void setImpl(final int key, final int value) {
+            setImpl(key, (double)value);
+        }
+
+        @Override
+        protected void setImpl(final int key, final long value) {
+            setImpl(key, (double)value);
+        }
+
+        @Override
+        protected void setImpl(final int key, final Object value) {
+            setImpl(key, JSType.toNumber(value));
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param newObj is this typed array instantiated with the new operator
+     * @param self   self reference
+     * @param args   args
+     *
+     * @return new typed array
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        return constructorImpl(args, FACTORY);
+    }
+
+    NativeFloat32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+        super(buffer, byteOffset, length);
+    }
+
+    @Override
+    protected Factory factory() {
+        return FACTORY;
+    }
+
+    @Override
+    protected boolean isFloatArray() {
+        return true;
+    }
+
+    /**
+     * Set values
+     * @param self   self reference
+     * @param array  multiple values of array's type to set
+     * @param offset optional start index, interpreted  0 if undefined
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object set(final Object self, final Object array, final Object offset) {
+        return ArrayBufferView.setImpl(self, array, offset);
+    }
+
+    /**
+     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
+     * referencing the elements at begin, inclusive, up to end, exclusive. If either
+     * begin or end is negative, it refers to an index from the end of the array,
+     * as opposed to from the beginning.
+     * <p>
+     * If end is unspecified, the subarray contains all elements from begin to the end
+     * of the TypedArray. The range specified by the begin and end values is clamped to
+     * the valid index range for the current array. If the computed length of the new
+     * TypedArray would be negative, it is clamped to zero.
+     * <p>
+     * The returned TypedArray will be of the same type as the array on which this
+     * method is invoked.
+     *
+     * @param self self reference
+     * @param begin begin position
+     * @param end end position
+     *
+     * @return sub array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object subarray(final Object self, final Object begin, final Object end) {
+        return ArrayBufferView.subarrayImpl(self, begin, end);
+    }
+
+    @Override
+    protected ScriptObject getPrototype() {
+        return Global.instance().getFloat32ArrayPrototype();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
new file mode 100644
index 0000000..e2ce624
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
@@ -0,0 +1,196 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Float64 array for the TypedArray extension
+ */
+@ScriptClass("Float64Array")
+public final class NativeFloat64Array extends ArrayBufferView {
+    private static final int BYTES_PER_ELEMENT = 8;
+    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
+        @Override
+        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new NativeFloat64Array(buffer, byteOffset, length);
+        }
+        @Override
+        public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new Float64ArrayData(buffer, byteOffset, length);
+        }
+    };
+
+    private static final class Float64ArrayData extends ArrayDataImpl {
+        private Float64ArrayData(final NativeArrayBuffer buffer,
+                final int byteOffset, final int elementLength) {
+            super(buffer, byteOffset, elementLength);
+        }
+
+        @Override
+        protected int byteIndex(final int index) {
+            return index * BYTES_PER_ELEMENT + byteOffset;
+        }
+
+        @Override
+        protected double getDoubleImpl(final int index) {
+            final int byteIndex = byteIndex(index);
+            final byte[] byteArray = buffer.getByteArray();
+            final long bits;
+            bits =       byteArray[byteIndex  ]       & 0x0000_0000_0000_00ffL |
+                   (long)byteArray[byteIndex+1] <<  8 & 0x0000_0000_0000_ff00L |
+                   (long)byteArray[byteIndex+2] << 16 & 0x0000_0000_00ff_0000L |
+                   (long)byteArray[byteIndex+3] << 24 & 0x0000_0000_ff00_0000L |
+                   (long)byteArray[byteIndex+4] << 32 & 0x0000_00ff_0000_0000L |
+                   (long)byteArray[byteIndex+5] << 40 & 0x0000_ff00_0000_0000L |
+                   (long)byteArray[byteIndex+6] << 48 & 0x00ff_0000_0000_0000L |
+                   (long)byteArray[byteIndex+7] << 56 & 0xff00_0000_0000_0000L ;
+            return Double.longBitsToDouble(bits);
+        }
+
+        @Override
+        protected int getIntImpl(final int index) {
+            return (int)getDoubleImpl(index);
+        }
+
+        @Override
+        protected long getLongImpl(final int key) {
+            return (long)getDoubleImpl(key);
+        }
+
+        @Override
+        protected Object getObjectImpl(final int key) {
+            return getDoubleImpl(key);
+        }
+
+        @Override
+        protected void setImpl(final int index, final double value) {
+            final long bits = Double.doubleToRawLongBits(value);
+            final int byteIndex = byteIndex(index);
+            @SuppressWarnings("MismatchedReadAndWriteOfArray")
+            final byte[] byteArray = buffer.getByteArray();
+            byteArray[byteIndex  ] = (byte)(bits        & 0xff);
+            byteArray[byteIndex+1] = (byte)(bits >>>  8 & 0xff);
+            byteArray[byteIndex+2] = (byte)(bits >>> 16 & 0xff);
+            byteArray[byteIndex+3] = (byte)(bits >>> 24 & 0xff);
+            byteArray[byteIndex+4] = (byte)(bits >>> 32 & 0xff);
+            byteArray[byteIndex+5] = (byte)(bits >>> 40 & 0xff);
+            byteArray[byteIndex+6] = (byte)(bits >>> 48 & 0xff);
+            byteArray[byteIndex+7] = (byte)(bits >>> 56 & 0xff);
+        }
+
+        @Override
+        protected void setImpl(final int key, final int value) {
+            setImpl(key, (double)value);
+        }
+
+        @Override
+        protected void setImpl(final int key, final long value) {
+            setImpl(key, (double)value);
+        }
+
+        @Override
+        protected void setImpl(final int key, final Object value) {
+            setImpl(key, JSType.toNumber(value));
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param newObj is this typed array instantiated with the new operator
+     * @param self   self reference
+     * @param args   args
+     *
+     * @return new typed array
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        return constructorImpl(args, FACTORY);
+    }
+
+    NativeFloat64Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+        super(buffer, byteOffset, length);
+    }
+
+    @Override
+    protected Factory factory() {
+        return FACTORY;
+    }
+
+    @Override
+    protected boolean isFloatArray() {
+        return true;
+    }
+
+    /**
+     * Set values
+     * @param self   self reference
+     * @param array  multiple values of array's type to set
+     * @param offset optional start index, interpreted  0 if undefined
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object set(final Object self, final Object array, final Object offset) {
+        return ArrayBufferView.setImpl(self, array, offset);
+    }
+
+    /**
+     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
+     * referencing the elements at begin, inclusive, up to end, exclusive. If either
+     * begin or end is negative, it refers to an index from the end of the array,
+     * as opposed to from the beginning.
+     * <p>
+     * If end is unspecified, the subarray contains all elements from begin to the end
+     * of the TypedArray. The range specified by the begin and end values is clamped to
+     * the valid index range for the current array. If the computed length of the new
+     * TypedArray would be negative, it is clamped to zero.
+     * <p>
+     * The returned TypedArray will be of the same type as the array on which this
+     * method is invoked.
+     *
+     * @param self self reference
+     * @param begin begin position
+     * @param end end position
+     *
+     * @return sub array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object subarray(final Object self, final Object begin, final Object end) {
+        return ArrayBufferView.subarrayImpl(self, begin, end);
+    }
+
+    @Override
+    protected ScriptObject getPrototype() {
+        return Global.instance().getFloat64ArrayPrototype();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
new file mode 100644
index 0000000..f5c0c29
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
@@ -0,0 +1,218 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.util.List;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * ECMA 15.3 Function Objects
+ *
+ * Note: instances of this class are never created. This class is not even a
+ * subclass of ScriptObject. But, we use this class to generate prototype and
+ * constructor for "Function".
+ */
+@ScriptClass("Function")
+public final class NativeFunction {
+    // do *not* create me!
+    private NativeFunction() {
+    }
+
+    /**
+     * ECMA 15.3.4.2 Function.prototype.toString ( )
+     *
+     * @param self self reference
+     * @return string representation of Function
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toString(final Object self) {
+        if (!(self instanceof ScriptFunction)) {
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+        }
+        return ((ScriptFunction)self).toSource();
+    }
+
+    /**
+     * ECMA 15.3.4.3 Function.prototype.apply (thisArg, argArray)
+     *
+     * @param self   self reference
+     * @param thiz   {@code this} arg for apply
+     * @param array  array of argument for apply
+     * @return result of apply
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object apply(final Object self, final Object thiz, final Object array) {
+        if (!(self instanceof ScriptFunction)) {
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+        }
+
+        Object[] args = null;
+
+        if (ScriptObject.isArray(array)) {
+            args = ((NativeArray)array).asObjectArray();
+        } else if (array instanceof ScriptObject) {
+            // look for array-like object
+            final ScriptObject sobj = (ScriptObject)array;
+            final Object       len  = sobj.getLength();
+
+            if (len == UNDEFINED || len == null) {
+                throw typeError("function.apply.expects.array");
+            }
+
+            final int n = (int)JSType.toUint32(len);
+            if (n != JSType.toNumber(len)) {
+                throw typeError("function.apply.expects.array");
+            }
+
+            args = new Object[(int)JSType.toUint32(len)];
+            for (int i = 0; i < args.length; i++) {
+                args[i] = sobj.get(i);
+            }
+        } else if (array instanceof Object[]) {
+            args = (Object[])array;
+        } else if (array instanceof List) {
+            final List<?> list = (List<?>)array;
+            list.toArray(args = new Object[list.size()]);
+        } else if (array == null || array == UNDEFINED) {
+            args = ScriptRuntime.EMPTY_ARRAY;
+        } else {
+            throw typeError("function.apply.expects.array");
+        }
+
+        return ScriptRuntime.apply((ScriptFunction)self, thiz, args);
+    }
+
+    /**
+     * ECMA 15.3.4.4 Function.prototype.call (thisArg [ , arg1 [ , arg2, ... ] ] )
+     *
+     * @param self self reference
+     * @param args arguments for call
+     * @return result of call
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object call(final Object self, final Object... args) {
+        if (!(self instanceof ScriptFunction)) {
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+        }
+
+        Object thiz = (args.length == 0) ? UNDEFINED : args[0];
+        Object[] arguments;
+
+        if (args.length > 1) {
+            arguments = new Object[args.length - 1];
+            System.arraycopy(args, 1, arguments, 0, arguments.length);
+        } else {
+            arguments = ScriptRuntime.EMPTY_ARRAY;
+        }
+
+        return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments);
+    }
+
+    /**
+     * ECMA 15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]])
+     *
+     * @param self self reference
+     * @param args arguments for bind
+     * @return function with bound arguments
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object bind(final Object self, final Object... args) {
+        if (!(self instanceof ScriptFunction)) {
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+        }
+
+        final Object thiz = (args.length == 0) ? UNDEFINED : args[0];
+
+        Object[] arguments;
+        if (args.length > 1) {
+            arguments = new Object[args.length - 1];
+            System.arraycopy(args, 1, arguments, 0, arguments.length);
+        } else {
+            arguments = ScriptRuntime.EMPTY_ARRAY;
+        }
+
+        return ((ScriptFunctionImpl)self).makeBoundFunction(thiz, arguments);
+    }
+
+    /**
+     * Nashorn extension: Function.prototype.toSource
+     *
+     * @param self self reference
+     * @return source for function
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toSource(final Object self) {
+        if (!(self instanceof ScriptFunction)) {
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+        }
+        return ((ScriptFunction)self).toSource();
+    }
+
+    /**
+     * ECMA 15.3.2.1 new Function (p1, p2, ... , pn, body)
+     *
+     * Constructor
+     *
+     * @param newObj is the new operator used for constructing this function
+     * @param self   self reference
+     * @param args   arguments
+     * @return new NativeFunction
+     */
+    @Constructor(arity = 1)
+    public static Object function(final boolean newObj, final Object self, final Object... args) {
+        final StringBuilder sb = new StringBuilder();
+
+        sb.append("(function (");
+        if (args.length > 0) {
+            for (int i = 0; i < args.length - 1; i++) {
+                sb.append(JSType.toString(args[i]));
+                if (i < args.length - 2) {
+                    sb.append(",");
+                }
+            }
+        }
+        sb.append(") {\n");
+        if (args.length > 0) {
+            sb.append(JSType.toString(args[args.length - 1]));
+            sb.append('\n');
+        }
+        sb.append("})");
+
+        final Global global = Global.instance();
+
+        return Global.directEval(global, sb.toString(), global, "<function>", Global.isStrict());
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
new file mode 100644
index 0000000..c5951d9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
@@ -0,0 +1,144 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Int16 array for the TypedArray extension
+ */
+@ScriptClass("Int16Array")
+public final class NativeInt16Array extends ArrayBufferView {
+    private static final int BYTES_PER_ELEMENT = 2;
+    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
+        @Override
+        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new NativeInt16Array(buffer, byteOffset, length);
+        }
+        @Override
+        public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new Int16ArrayData(buffer, byteOffset, length);
+        }
+    };
+
+    private static final class Int16ArrayData extends ArrayDataImpl {
+        private Int16ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+            super(buffer, byteOffset, elementLength);
+        }
+
+        @Override
+        protected int byteIndex(final int index) {
+            return index * BYTES_PER_ELEMENT + byteOffset;
+        }
+
+        @Override
+        protected int getIntImpl(final int index) {
+            final int byteIndex = byteIndex(index);
+            final byte[] byteArray = buffer.getByteArray();
+            return byteArray[byteIndex  ]       & (short)0x00ff |
+                   byteArray[byteIndex+1] <<  8 & (short)0xff00 ;
+        }
+
+        @Override
+        protected void setImpl(final int index, final int value) {
+            final int byteIndex = byteIndex(index);
+            @SuppressWarnings("MismatchedReadAndWriteOfArray")
+            final byte[] byteArray = buffer.getByteArray();
+            byteArray[byteIndex  ] = (byte)(value       & 0xff);
+            byteArray[byteIndex+1] = (byte)(value >>> 8 & 0xff);
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param newObj is this typed array instantiated with the new operator
+     * @param self   self reference
+     * @param args   args
+     *
+     * @return new typed array
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        return constructorImpl(args, FACTORY);
+    }
+
+    NativeInt16Array(final NativeArrayBuffer buffer, final int byteOffset, final int byteLength) {
+        super(buffer, byteOffset, byteLength);
+    }
+
+    @Override
+    protected Factory factory() {
+        return FACTORY;
+    }
+
+    /**
+     * Set values
+     * @param self   self reference
+     * @param array  multiple values of array's type to set
+     * @param offset optional start index, interpreted  0 if undefined
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object set(final Object self, final Object array, final Object offset) {
+        return ArrayBufferView.setImpl(self, array, offset);
+    }
+
+    /**
+     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
+     * referencing the elements at begin, inclusive, up to end, exclusive. If either
+     * begin or end is negative, it refers to an index from the end of the array,
+     * as opposed to from the beginning.
+     * <p>
+     * If end is unspecified, the subarray contains all elements from begin to the end
+     * of the TypedArray. The range specified by the begin and end values is clamped to
+     * the valid index range for the current array. If the computed length of the new
+     * TypedArray would be negative, it is clamped to zero.
+     * <p>
+     * The returned TypedArray will be of the same type as the array on which this
+     * method is invoked.
+     *
+     * @param self self reference
+     * @param begin begin position
+     * @param end end position
+     *
+     * @return sub array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object subarray(final Object self, final Object begin, final Object end) {
+        return ArrayBufferView.subarrayImpl(self, begin, end);
+    }
+
+    @Override
+    protected ScriptObject getPrototype() {
+        return Global.instance().getInt16ArrayPrototype();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
new file mode 100644
index 0000000..486e7a6
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
@@ -0,0 +1,148 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Int32 array for the TypedArray extension
+ */
+@ScriptClass("Int32Array")
+public final class NativeInt32Array extends ArrayBufferView {
+    private static final int BYTES_PER_ELEMENT = 4;
+    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
+        @Override
+        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new NativeInt32Array(buffer, byteOffset, length);
+        }
+        @Override
+        public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new Int32ArrayData(buffer, byteOffset, length);
+        }
+    };
+
+    private static final class Int32ArrayData extends ArrayDataImpl {
+        private Int32ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+            super(buffer, byteOffset, elementLength);
+        }
+
+        @Override
+        protected int byteIndex(final int index) {
+            return index * BYTES_PER_ELEMENT + byteOffset;
+        }
+
+        @Override
+        protected int getIntImpl(final int index) {
+            final int byteIndex = byteIndex(index);
+            final byte[] byteArray = buffer.getByteArray();
+            return byteArray[byteIndex  ]       & 0x0000_00ff |
+                   byteArray[byteIndex+1] <<  8 & 0x0000_ff00 |
+                   byteArray[byteIndex+2] << 16 & 0x00ff_0000 |
+                   byteArray[byteIndex+3] << 24 & 0xff00_0000 ;
+        }
+
+        @Override
+        protected void setImpl(final int index, final int value) {
+            final int byteIndex = byteIndex(index);
+            @SuppressWarnings("MismatchedReadAndWriteOfArray")
+            final byte[] byteArray = buffer.getByteArray();
+            byteArray[byteIndex  ] = (byte)(value        & 0xff);
+            byteArray[byteIndex+1] = (byte)(value >>>  8 & 0xff);
+            byteArray[byteIndex+2] = (byte)(value >>> 16 & 0xff);
+            byteArray[byteIndex+3] = (byte)(value >>> 24 & 0xff);
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param newObj is this typed array instantiated with the new operator
+     * @param self   self reference
+     * @param args   args
+     *
+     * @return new typed array
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        return constructorImpl(args, FACTORY);
+    }
+
+    NativeInt32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+        super(buffer, byteOffset, length);
+    }
+
+    @Override
+    protected Factory factory() {
+        return FACTORY;
+    }
+
+    /**
+     * Set values
+     * @param self   self reference
+     * @param array  multiple values of array's type to set
+     * @param offset optional start index, interpreted  0 if undefined
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object set(final Object self, final Object array, final Object offset) {
+        return ArrayBufferView.setImpl(self, array, offset);
+    }
+
+    /**
+     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
+     * referencing the elements at begin, inclusive, up to end, exclusive. If either
+     * begin or end is negative, it refers to an index from the end of the array,
+     * as opposed to from the beginning.
+     * <p>
+     * If end is unspecified, the subarray contains all elements from begin to the end
+     * of the TypedArray. The range specified by the begin and end values is clamped to
+     * the valid index range for the current array. If the computed length of the new
+     * TypedArray would be negative, it is clamped to zero.
+     * <p>
+     * The returned TypedArray will be of the same type as the array on which this
+     * method is invoked.
+     *
+     * @param self self reference
+     * @param begin begin position
+     * @param end end position
+     *
+     * @return sub array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object subarray(final Object self, final Object begin, final Object end) {
+        return ArrayBufferView.subarrayImpl(self, begin, end);
+    }
+
+    @Override
+    protected ScriptObject getPrototype() {
+        return Global.instance().getInt32ArrayPrototype();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
new file mode 100644
index 0000000..9ad7d24
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
@@ -0,0 +1,138 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Int8Array for the TypedArray extension
+ */
+@ScriptClass("Int8Array")
+public final class NativeInt8Array extends ArrayBufferView {
+    private static final int BYTES_PER_ELEMENT = 1;
+    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
+        @Override
+        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new NativeInt8Array(buffer, byteOffset, length);
+        }
+
+        @Override
+        public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new Int8ArrayData(buffer, byteOffset, length);
+        }
+    };
+
+    private static final class Int8ArrayData extends ArrayDataImpl {
+        private Int8ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+            super(buffer, byteOffset, elementLength);
+        }
+
+        @Override
+        protected int byteIndex(final int index) {
+            return index * BYTES_PER_ELEMENT + byteOffset;
+        }
+
+        @Override
+        protected int getIntImpl(final int index) {
+            return buffer.getByteArray()[byteIndex(index)];
+        }
+
+        @Override
+        protected void setImpl(final int index, final int value) {
+            buffer.getByteArray()[byteIndex(index)] = (byte)value;
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param newObj is this typed array instantiated with the new operator
+     * @param self   self reference
+     * @param args   args
+     *
+     * @return new typed array
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        return constructorImpl(args, FACTORY);
+    }
+
+    NativeInt8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+        super(buffer, byteOffset, length);
+    }
+
+    @Override
+    protected Factory factory() {
+        return FACTORY;
+    }
+
+    /**
+     * Set values
+     * @param self   self reference
+     * @param array  multiple values of array's type to set
+     * @param offset optional start index, interpreted  0 if undefined
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object set(final Object self, final Object array, final Object offset) {
+        return ArrayBufferView.setImpl(self, array, offset);
+    }
+
+    /**
+     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
+     * referencing the elements at begin, inclusive, up to end, exclusive. If either
+     * begin or end is negative, it refers to an index from the end of the array,
+     * as opposed to from the beginning.
+     * <p>
+     * If end is unspecified, the subarray contains all elements from begin to the end
+     * of the TypedArray. The range specified by the begin and end values is clamped to
+     * the valid index range for the current array. If the computed length of the new
+     * TypedArray would be negative, it is clamped to zero.
+     * <p>
+     * The returned TypedArray will be of the same type as the array on which this
+     * method is invoked.
+     *
+     * @param self self reference
+     * @param begin begin position
+     * @param end end position
+     *
+     * @return sub array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object subarray(final Object self, final Object begin, final Object end) {
+        return ArrayBufferView.subarrayImpl(self, begin, end);
+    }
+
+    @Override
+    protected ScriptObject getPrototype() {
+        return Global.instance().getInt8ArrayPrototype();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
new file mode 100644
index 0000000..409b9fa
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
@@ -0,0 +1,745 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.FindProperty;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
+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
+ * thought of as the {@link java.lang.reflect.Proxy} equivalent for JavaScript. NativeJSAdapter calls specially named
+ * JavaScript methods on an adaptee object when property access/update/call/new/delete is attempted on it. Example:
+ *<pre>
+ *    var y = {
+ *                __get__    : function (name) { ... }
+ *                __has__    : function (name) { ... }
+ *                __put__    : function (name, value) {...}
+ *                __call__   : function (name, arg1, arg2) {...}
+ *                __new__    : function (arg1, arg2) {...}
+ *                __delete__ : function (name) { ... }
+ *                __getIds__ : function () { ... }
+ *            };
+ *
+ *    var x = new JSAdapter(y);
+ *
+ *    x.i;                        // calls y.__get__
+ *    x.foo();                    // calls y.__call__
+ *    new x();                    // calls y.__new__
+ *    i in x;                     // calls y.__has__
+ *    x.p = 10;                   // calls y.__put__
+ *    delete x.p;                 // calls y.__delete__
+ *    for (i in x) { print(i); }  // calls y.__getIds__
+ * </pre>
+ * <p>
+ * JavaScript caller of adapter object is isolated from the fact that the property access/mutation/deletion are really
+ * calls to JavaScript methods on adaptee.
+ * </p>
+ * <p>
+ * JSAdapter constructor can optionally receive an "overrides" object. Properties of overrides object is copied to
+ * JSAdapter instance. When user accessed property is one of these, then adaptee's methods like {@code __get__},
+ * {@code __put__} etc. are not called for those. This can be used to make certain "preferred" properties that can be
+ * accessed in the usual/faster way avoiding proxy mechanism. Example:
+ * </p>
+ * <pre>
+ *     var x = new JSAdapter({ foo: 444, bar: 6546 }) {
+ *          __get__: function(name) { return name; }
+ *      };
+ *
+ *     x.foo;           // 444 directly retrieved without __get__ call
+ *     x.bar = 'hello'; // "bar" directly set without __put__ call
+ *     x.prop           // calls __get__("prop") as 'prop' is not overridden
+ * </pre>
+ * It is possible to pass a specific prototype for JSAdapter instance by passing three arguments to JSAdapter
+ * constructor. So exact signature of JSAdapter constructor is as follows:
+ * <pre>
+ *     JSAdapter([proto], [overrides], adaptee);
+ * </pre>
+ * Both proto and overrides are optional - but adaptee is not. When proto is not passed {@code JSAdapter.prototype} is
+ * used.
+ */
+@ScriptClass("JSAdapter")
+public final class NativeJSAdapter extends ScriptObject {
+    /** object get operation */
+    public static final String __get__       = "__get__";
+    /** object out operation */
+    public static final String __put__       = "__put__";
+    /** object call operation */
+    public static final String __call__      = "__call__";
+    /** object new operation */
+    public static final String __new__       = "__new__";
+    /** object getIds operation */
+    public static final String __getIds__    = "__getIds__";
+    /** object getKeys operation */
+    public static final String __getKeys__   = "__getKeys__";
+    /** object getValues operation */
+    public static final String __getValues__ = "__getValues__";
+    /** object has operation */
+    public static final String __has__       = "__has__";
+    /** object delete operation */
+    public static final String __delete__    = "__delete__";
+
+    // the new extensibility, sealing and freezing operations
+
+    /** prevent extensions operation */
+    public static final String __preventExtensions__ = "__preventExtensions__";
+    /** isExtensible extensions operation */
+    public static final String __isExtensible__      = "__isExtensible__";
+    /** seal operation */
+    public static final String __seal__              = "__seal__";
+    /** isSealed extensions operation */
+    public static final String __isSealed__          = "__isSealed__";
+    /** freeze operation */
+    public static final String __freeze__            = "__freeze__";
+    /** isFrozen extensions operation */
+    public static final String __isFrozen__          = "__isFrozen__";
+
+    private final ScriptObject adaptee;
+    private final boolean overrides;
+
+    private static final MethodHandle IS_JSADAPTOR = findOwnMH("isJSAdaptor", boolean.class, Object.class, Object.class, MethodHandle.class, Object.class, ScriptFunction.class);
+
+    NativeJSAdapter(final ScriptObject proto, final Object overrides, final ScriptObject adaptee) {
+        this.adaptee = wrapAdaptee(adaptee);
+        this.setProto(proto);
+        if (overrides instanceof ScriptObject) {
+            this.overrides = true;
+            final ScriptObject sobj = (ScriptObject)overrides;
+            final Iterator<String> iter = sobj.propertyIterator();
+            while (iter.hasNext()) {
+                final String prop = iter.next();
+                super.set(prop, sobj.get(prop), false);
+            }
+        } else {
+            this.overrides = false;
+        }
+    }
+
+    private static ScriptObject wrapAdaptee(final ScriptObject adaptee) {
+        final ScriptObject sobj = new jdk.nashorn.internal.scripts.JO();
+        sobj.setProto(adaptee);
+        return sobj;
+    }
+
+    @Override
+    public String getClassName() {
+        return "JSAdapter";
+    }
+
+    @Override
+    public int getInt(final Object key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getInt(key) : callAdapteeInt(__get__, key);
+    }
+
+    @Override
+    public int getInt(final double key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getInt(key) : callAdapteeInt(__get__, key);
+    }
+
+    @Override
+    public int getInt(final long key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getInt(key) : callAdapteeInt(__get__, key);
+    }
+
+    @Override
+    public int getInt(final int key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getInt(key) : callAdapteeInt(__get__, key);
+    }
+
+    @Override
+    public long getLong(final Object key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key) : callAdapteeLong(__get__, key);
+    }
+
+    @Override
+    public long getLong(final double key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key) : callAdapteeLong(__get__, key);
+    }
+
+    @Override
+    public long getLong(final long key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key) : callAdapteeLong(__get__, key);
+    }
+
+    @Override
+    public long getLong(final int key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key) : callAdapteeLong(__get__, key);
+    }
+
+    @Override
+    public double getDouble(final Object key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key) : callAdapteeDouble(__get__, key);
+    }
+
+    @Override
+    public double getDouble(final double key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key) : callAdapteeDouble(__get__, key);
+    }
+
+    @Override
+    public double getDouble(final long key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key) : callAdapteeDouble(__get__, key);
+    }
+
+    @Override
+    public double getDouble(final int key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key) : callAdapteeDouble(__get__, key);
+    }
+
+    @Override
+    public Object get(final Object key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
+    }
+
+    @Override
+    public Object get(final double key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
+    }
+
+    @Override
+    public Object get(final long key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
+    }
+
+    @Override
+    public Object get(final int key) {
+        return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
+    }
+
+    @Override
+    public void set(final Object key, final int value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final Object key, final long value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final Object key, final double value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final Object key, final Object value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final double key, final int value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final double key, final long value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final double key, final double value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final double key, final Object value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final long key, final int value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final long key, final long value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final long key, final double value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final long key, final Object value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final int key, final int value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final int key, final long value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final int key, final double value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public void set(final int key, final Object value, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            super.set(key, value, strict);
+        } else {
+            callAdaptee(__put__, key, value, strict);
+        }
+    }
+
+    @Override
+    public boolean has(final Object key) {
+        if (overrides && super.hasOwnProperty(key)) {
+            return true;
+        }
+
+        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
+    }
+
+    @Override
+    public boolean has(final int key) {
+        if (overrides && super.hasOwnProperty(key)) {
+            return true;
+        }
+
+        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
+    }
+
+    @Override
+    public boolean has(final long key) {
+        if (overrides && super.hasOwnProperty(key)) {
+            return true;
+        }
+
+        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
+    }
+
+    @Override
+    public boolean has(final double key) {
+        if (overrides && super.hasOwnProperty(key)) {
+            return true;
+        }
+
+        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
+    }
+
+    @Override
+    public boolean delete(final int key, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            return super.delete(key, strict);
+        }
+
+        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
+    }
+
+    @Override
+    public boolean delete(final long key, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            return super.delete(key, strict);
+        }
+
+        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
+    }
+
+    @Override
+    public boolean delete(final double key, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            return super.delete(key, strict);
+        }
+
+        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
+    }
+
+    @Override
+    public boolean delete(final Object key, final boolean strict) {
+        if (overrides && super.hasOwnProperty(key)) {
+            return super.delete(key, strict);
+        }
+
+        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
+    }
+
+    @Override
+    public Iterator<String> propertyIterator() {
+        // Try __getIds__ first, if not found then try __getKeys__
+        // In jdk6, we had added "__getIds__" so this is just for compatibility.
+        Object func = adaptee.get(__getIds__);
+        if (!(func instanceof ScriptFunction)) {
+            func = adaptee.get(__getKeys__);
+        }
+
+        Object obj;
+        if (func instanceof ScriptFunction) {
+            obj = ScriptRuntime.apply((ScriptFunction)func, adaptee);
+        } else {
+            obj = new NativeArray(0);
+        }
+
+        final List<String> array = new ArrayList<>();
+        for (final Iterator<Object> iter = ArrayLikeIterator.arrayLikeIterator(obj); iter.hasNext(); ) {
+            array.add((String)iter.next());
+        }
+
+        return array.iterator();
+    }
+
+
+    @Override
+    public Iterator<Object> valueIterator() {
+        final Object obj = callAdaptee(new NativeArray(0), __getValues__);
+        return ArrayLikeIterator.arrayLikeIterator(obj);
+    }
+
+    @Override
+    public ScriptObject preventExtensions() {
+        callAdaptee(__preventExtensions__);
+        return this;
+    }
+
+    @Override
+    public boolean isExtensible() {
+        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __isExtensible__));
+    }
+
+    @Override
+    public ScriptObject seal() {
+        callAdaptee(__seal__);
+        return this;
+    }
+
+    @Override
+    public boolean isSealed() {
+        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __isSealed__));
+    }
+
+    @Override
+    public ScriptObject freeze() {
+        callAdaptee(__freeze__);
+        return this;
+    }
+
+    @Override
+    public boolean isFrozen() {
+        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __isFrozen__));
+    }
+
+    /**
+     * Constructor
+     *
+     * @param isNew is this NativeJSAdapter instantiated with the new operator
+     * @param self  self reference
+     * @param args  arguments ([adaptee], [overrides, adaptee] or [proto, overrides, adaptee]
+     * @return new NativeJSAdapter
+     */
+    @Constructor
+    public static Object construct(final boolean isNew, final Object self, final Object... args) {
+        Object proto     = UNDEFINED;
+        Object overrides = UNDEFINED;
+        Object adaptee;
+
+        if (args == null || args.length == 0) {
+            throw typeError("not.an.object", "null");
+        }
+
+        switch (args.length) {
+        case 1:
+            adaptee = args[0];
+            break;
+
+        case 2:
+            overrides = args[0];
+            adaptee   = args[1];
+            break;
+
+        default:
+            //fallthru
+        case 3:
+            proto = args[0];
+            overrides = args[1];
+            adaptee = args[2];
+            break;
+        }
+
+        if (!(adaptee instanceof ScriptObject)) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(adaptee));
+        }
+
+        if (proto != null && !(proto instanceof ScriptObject)) {
+            proto = Global.instance().getJSAdapterPrototype();
+        }
+
+        return new NativeJSAdapter((ScriptObject)proto, overrides, (ScriptObject)adaptee);
+    }
+
+    @Override
+    protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
+        return findHook(desc, __new__, false);
+    }
+
+    @Override
+    protected GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        if (overrides && super.hasOwnProperty(desc.getNameToken(2))) {
+            try {
+                final GuardedInvocation inv = super.findCallMethodMethod(desc, request);
+                if (inv != null) {
+                    return inv;
+                }
+            } catch (final Exception e) {
+                //ignored
+            }
+        }
+
+        return findHook(desc, __call__);
+    }
+
+    @Override
+    protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operation) {
+        final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+        if (overrides && super.hasOwnProperty(name)) {
+            try {
+                final GuardedInvocation inv = super.findGetMethod(desc, request, operation);
+                if (inv != null) {
+                    return inv;
+                }
+            } catch (final Exception e) {
+                //ignored
+            }
+        }
+
+        switch(operation) {
+        case "getProp":
+        case "getElem":
+            return findHook(desc, __get__);
+        case "getMethod":
+            final FindProperty find = adaptee.findProperty(__call__, true);
+            if (find != null) {
+                final ScriptFunctionImpl func = (ScriptFunctionImpl)getObjectValue(find);
+                // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
+                // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
+                return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
+                        func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
+                        adaptee.getMap().getProtoGetSwitchPoint(__call__), testJSAdaptor(adaptee, null, null, null));
+            }
+            throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
+        default:
+            break;
+        }
+
+        throw new AssertionError("should not reach here");
+    }
+
+    @Override
+    protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        if (overrides && super.hasOwnProperty(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND))) {
+            try {
+                final GuardedInvocation inv = super.findSetMethod(desc, request);
+                if (inv != null) {
+                    return inv;
+                }
+            } catch (final Exception e) {
+                //ignored
+            }
+        }
+
+        return findHook(desc, __put__);
+    }
+
+    // -- Internals only below this point
+    private Object callAdaptee(final String name, final Object... args) {
+        return callAdaptee(UNDEFINED, name, args);
+    }
+
+    private double callAdapteeDouble(final String name, final Object... args) {
+        return JSType.toNumber(callAdaptee(name, args));
+    }
+
+    private long callAdapteeLong(final String name, final Object... args) {
+        return JSType.toLong(callAdaptee(name, args));
+    }
+
+    private int callAdapteeInt(final String name, final Object... args) {
+        return JSType.toInt32(callAdaptee(name, args));
+    }
+
+    private Object callAdaptee(final Object retValue, final String name, final Object... args) {
+        final Object func = adaptee.get(name);
+        if (func instanceof ScriptFunction) {
+            return ScriptRuntime.apply((ScriptFunction)func, adaptee, args);
+        }
+        return retValue;
+    }
+
+    private GuardedInvocation findHook(final CallSiteDescriptor desc, final String hook) {
+        return findHook(desc, hook, true);
+    }
+
+    private GuardedInvocation findHook(final CallSiteDescriptor desc, final String hook, final boolean useName) {
+        final FindProperty findData = adaptee.findProperty(hook, true);
+        final MethodType type = desc.getMethodType();
+        if (findData != null) {
+            final String name = desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null;
+            final ScriptFunction func = (ScriptFunction)getObjectValue(findData);
+
+            final MethodHandle methodHandle = getCallMethodHandle(findData, type,
+                    useName ? name : null);
+            if (methodHandle != null) {
+                return new GuardedInvocation(
+                        methodHandle,
+                        adaptee.getMap().getProtoGetSwitchPoint(hook),
+                        testJSAdaptor(adaptee, findData.getGetter(Object.class), findData.getOwner(), func));
+            }
+        }
+
+        switch (hook) {
+        case __call__:
+            throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
+        default:
+            final MethodHandle methodHandle = hook.equals(__put__) ?
+            MH.asType(Lookup.EMPTY_SETTER, type) :
+            Lookup.emptyGetter(type.returnType());
+            return new GuardedInvocation(methodHandle, adaptee.getMap().getProtoGetSwitchPoint(hook), testJSAdaptor(adaptee, null, null, null));
+        }
+    }
+
+    private static MethodHandle testJSAdaptor(final Object adaptee, final MethodHandle getter, final Object where, final ScriptFunction func) {
+        return MH.insertArguments(IS_JSADAPTOR, 1, adaptee, getter, where, func);
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isJSAdaptor(final Object self, final Object adaptee, final MethodHandle getter, final Object where, final ScriptFunction func) {
+        final boolean res = self instanceof NativeJSAdapter && ((NativeJSAdapter)self).getAdaptee() == adaptee;
+        if (res && getter != null) {
+            try {
+                return getter.invokeExact(where) == func;
+            } catch (final RuntimeException | Error e) {
+                throw e;
+            } catch (final Throwable t) {
+                throw new RuntimeException(t);
+            }
+        }
+
+        return res;
+    }
+
+    /**
+     * Get the adaptee
+     * @return adaptee ScriptObject
+     */
+    public ScriptObject getAdaptee() {
+        return adaptee;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        try {
+            return MethodHandles.lookup().findStatic(NativeJSAdapter.class, name, MH.type(rtype, types));
+        } catch (final NoSuchMethodException | IllegalAccessException e) {
+            throw new MethodHandleFactory.LookupException(e);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
new file mode 100644
index 0000000..faeebc1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
@@ -0,0 +1,382 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.lang.invoke.MethodHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.JSONFunctions;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+import jdk.nashorn.internal.runtime.linker.InvokeByName;
+
+/**
+ * ECMAScript 262 Edition 5, Section 15.12 The NativeJSON Object
+ *
+ */
+@ScriptClass("JSON")
+public final class NativeJSON extends ScriptObject {
+    private static final InvokeByName TO_JSON = new InvokeByName("toJSON", ScriptObject.class, Object.class, Object.class);
+    private static final MethodHandle REPLACER_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
+            ScriptFunction.class, ScriptObject.class, Object.class, Object.class);
+
+
+    NativeJSON() {
+        this.setProto(Global.objectPrototype());
+    }
+
+    /**
+     * ECMA 15.12.2 parse ( text [ , reviver ] )
+     *
+     * @param self     self reference
+     * @param text     a JSON formatted string
+     * @param reviver  optional value: function that takes two parameters (key, value)
+     *
+     * @return an ECMA script value
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object parse(final Object self, final Object text, final Object reviver) {
+        return JSONFunctions.parse(text, reviver);
+    }
+
+    /**
+     * ECMA 15.12.3 stringify ( value [ , replacer [ , space ] ] )
+     *
+     * @param self     self reference
+     * @param value    ECMA script value (usually object or array)
+     * @param replacer either a function or an array of strings and numbers
+     * @param space    optional parameter - allows result to have whitespace injection
+     *
+     * @return a string in JSON format
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object stringify(final Object self, final Object value, final Object replacer, final Object space) {
+        // The stringify method takes a value and an optional replacer, and an optional
+        // space parameter, and returns a JSON text. The replacer can be a function
+        // that can replace values, or an array of strings that will select the keys.
+
+        // A default replacer method can be provided. Use of the space parameter can
+        // produce text that is more easily readable.
+
+        final StringifyState state = new StringifyState();
+
+        // If there is a replacer, it must be a function or an array.
+        if (replacer instanceof ScriptFunction) {
+            state.replacerFunction = (ScriptFunction) replacer;
+        } else if (isArray(replacer) ||
+                replacer instanceof Iterable ||
+                (replacer != null && replacer.getClass().isArray())) {
+
+            state.propertyList = new ArrayList<>();
+
+            final Iterator<Object> iter = ArrayLikeIterator.arrayLikeIterator(replacer);
+
+            while (iter.hasNext()) {
+                String item = null;
+                final Object v = iter.next();
+
+                if (v instanceof String) {
+                    item = (String) v;
+                } else if (v instanceof ConsString) {
+                    item = v.toString();
+                } else if (v instanceof Number ||
+                        v instanceof NativeNumber ||
+                        v instanceof NativeString) {
+                    item = JSType.toString(v);
+                }
+
+                if (item != null) {
+                    state.propertyList.add(item);
+                }
+            }
+        }
+
+        // If the space parameter is a number, make an indent
+        // string containing that many spaces.
+
+        String gap;
+
+        if (space instanceof Number || space instanceof NativeNumber) {
+            int indent;
+            if (space instanceof NativeNumber) {
+                indent = ((NativeNumber)space).intValue();
+            } else {
+                indent = ((Number)space).intValue();
+            }
+
+            final StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < Math.min(10, indent); i++) {
+                sb.append(' ');
+            }
+            gap = sb.toString();
+
+        } else if (space instanceof String || space instanceof ConsString || space instanceof NativeString) {
+            final String str = (space instanceof String) ? (String)space : space.toString();
+            gap = str.substring(0, Math.min(10, str.length()));
+        } else {
+            gap = "";
+        }
+
+        state.gap = gap;
+
+        final ScriptObject wrapper = Global.newEmptyInstance();
+        wrapper.set("", value, Global.isStrict());
+
+        return str("", wrapper, state);
+    }
+
+    // -- Internals only below this point
+
+    // stringify helpers.
+
+    private static class StringifyState {
+        final Map<ScriptObject, ScriptObject> stack = new IdentityHashMap<>();
+
+        StringBuilder  indent = new StringBuilder();
+        String         gap = "";
+        List<String>   propertyList = null;
+        ScriptFunction replacerFunction = null;
+    }
+
+    // Spec: The abstract operation Str(key, holder).
+    private static Object str(final Object key, final ScriptObject holder, final StringifyState state) {
+        Object value = holder.get(key);
+
+        try {
+            if (value instanceof ScriptObject) {
+                final ScriptObject svalue = (ScriptObject)value;
+                final Object toJSON = TO_JSON.getGetter().invokeExact(svalue);
+                if (toJSON instanceof ScriptFunction) {
+                    value = TO_JSON.getInvoker().invokeExact(toJSON, svalue, key);
+                }
+            }
+
+            if (state.replacerFunction != null) {
+                value = REPLACER_INVOKER.invokeExact(state.replacerFunction, holder, key, value);
+            }
+        } catch(Error|RuntimeException t) {
+            throw t;
+        } catch(final Throwable t) {
+            throw new RuntimeException(t);
+        }
+        final boolean isObj = (value instanceof ScriptObject);
+        if (isObj) {
+            if (value instanceof NativeNumber) {
+                value = JSType.toNumber(value);
+            } else if (value instanceof NativeString) {
+                value = JSType.toString(value);
+            } else if (value instanceof NativeBoolean) {
+                value = ((NativeBoolean)value).booleanValue();
+            }
+        }
+
+        if (value == null) {
+            return "null";
+        } else if (Boolean.TRUE.equals(value)) {
+            return "true";
+        } else if (Boolean.FALSE.equals(value)) {
+            return "false";
+        }
+
+        if (value instanceof String) {
+            return JSONFunctions.quote((String)value);
+        } else if (value instanceof ConsString) {
+            return JSONFunctions.quote(value.toString());
+        }
+
+        if (value instanceof Number) {
+            return JSType.isFinite(((Number)value).doubleValue()) ? JSType.toString(value) : "null";
+        }
+
+        final JSType type = JSType.of(value);
+        if (type == JSType.OBJECT) {
+            if (isArray(value)) {
+                return JA((NativeArray)value, state);
+            } else if (value instanceof ScriptObject) {
+                return JO((ScriptObject)value, state);
+            }
+        }
+
+        return UNDEFINED;
+    }
+
+    // Spec: The abstract operation JO(value) serializes an object.
+    private static String JO(final ScriptObject value, final StringifyState state) {
+        if (state.stack.containsKey(value)) {
+            throw typeError("JSON.stringify.cyclic");
+        }
+
+        state.stack.put(value, value);
+        final StringBuilder stepback = new StringBuilder(state.indent.toString());
+        state.indent.append(state.gap);
+
+        final StringBuilder finalStr = new StringBuilder();
+        final List<Object>  partial  = new ArrayList<>();
+        final List<String>  k        = state.propertyList == null ? Arrays.asList(value.getOwnKeys(false)) : state.propertyList;
+
+        for (final Object p : k) {
+            final Object strP = str(p, value, state);
+
+            if (strP != UNDEFINED) {
+                final StringBuilder member = new StringBuilder();
+
+                member.append(JSONFunctions.quote(p.toString())).append(':');
+                if (!state.gap.isEmpty()) {
+                    member.append(' ');
+                }
+
+                member.append(strP);
+                partial.add(member);
+            }
+        }
+
+        if (partial.isEmpty()) {
+            finalStr.append("{}");
+        } else {
+            if (state.gap.isEmpty()) {
+                final int size = partial.size();
+                int       index = 0;
+
+                finalStr.append('{');
+
+                for (final Object str : partial) {
+                    finalStr.append(str);
+                    if (index < size - 1) {
+                        finalStr.append(',');
+                    }
+                    index++;
+                }
+
+                finalStr.append('}');
+            } else {
+                final int size  = partial.size();
+                int       index = 0;
+
+                finalStr.append("{\n");
+                finalStr.append(state.indent);
+
+                for (final Object str : partial) {
+                    finalStr.append(str);
+                    if (index < size - 1) {
+                        finalStr.append(",\n");
+                        finalStr.append(state.indent);
+                    }
+                    index++;
+                }
+
+                finalStr.append('\n');
+                finalStr.append(stepback);
+                finalStr.append('}');
+            }
+        }
+
+        state.stack.remove(value);
+        state.indent = stepback;
+
+        return finalStr.toString();
+    }
+
+    // Spec: The abstract operation JA(value) serializes an array.
+    private static Object JA(final NativeArray value, final StringifyState state) {
+        if (state.stack.containsKey(value)) {
+            throw typeError("JSON.stringify.cyclic");
+        }
+
+        state.stack.put(value, value);
+        final StringBuilder stepback = new StringBuilder(state.indent.toString());
+        state.indent.append(state.gap);
+        final List<Object> partial = new ArrayList<>();
+
+        final int length = JSType.toInteger(value.getLength());
+        int index = 0;
+
+        while (index < length) {
+            Object strP = str(index, value, state);
+            if (strP == UNDEFINED) {
+                strP = "null";
+            }
+            partial.add(strP);
+            index++;
+        }
+
+        final StringBuilder finalStr = new StringBuilder();
+        if (partial.isEmpty()) {
+            finalStr.append("[]");
+        } else {
+            if (state.gap.isEmpty()) {
+                final int size = partial.size();
+                index = 0;
+                finalStr.append('[');
+                for (final Object str : partial) {
+                    finalStr.append(str);
+                    if (index < size - 1) {
+                        finalStr.append(',');
+                    }
+                    index++;
+                }
+
+                finalStr.append(']');
+            } else {
+                final int size = partial.size();
+                index = 0;
+                finalStr.append("[\n");
+                finalStr.append(state.indent);
+                for (final Object str : partial) {
+                    finalStr.append(str);
+                    if (index < size - 1) {
+                        finalStr.append(",\n");
+                        finalStr.append(state.indent);
+                    }
+                    index++;
+                }
+
+                finalStr.append('\n');
+                finalStr.append(stepback);
+                finalStr.append(']');
+            }
+        }
+
+        state.stack.remove(value);
+        state.indent = stepback;
+
+        return finalStr.toString();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
new file mode 100644
index 0000000..fc16962
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
@@ -0,0 +1,413 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import jdk.internal.dynalink.beans.StaticClass;
+import jdk.internal.dynalink.support.TypeUtilities;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
+
+/**
+ * This class is the implementation for the {@code Java} global object exposed to programs running under Nashorn. This
+ * object acts as the API entry point to Java platform specific functionality, dealing with creating new instances of
+ * Java classes, subclassing Java classes, implementing Java interfaces, converting between Java arrays and ECMAScript
+ * arrays, and so forth.
+ */
+@ScriptClass("Java")
+public final class NativeJava {
+
+    private NativeJava() {
+    }
+
+    /**
+     * Returns true if the specified object is a Java type object, that is an instance of {@link StaticClass}.
+     * @param self not used
+     * @param type the object that is checked if it is a type object or not
+     * @return tells whether given object is a Java type object or not.
+     * @see #type(Object, Object)
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object isType(final Object self, final Object type) {
+        return type instanceof StaticClass;
+    }
+
+    /**
+     * <p>
+     * Given a name of a Java type, returns an object representing that type in Nashorn. The Java class of the objects
+     * used to represent Java types in Nashorn is not {@link java.lang.Class} but rather {@link StaticClass}. They are
+     * the objects that you can use with the {@code new} operator to create new instances of the class as well as to
+     * access static members of the class. In Nashorn, {@code Class} objects are just regular Java objects that aren't
+     * treated specially. Instead of them, {@link StaticClass} instances - which we sometimes refer to as "Java type
+     * objects" are used as constructors with the {@code new} operator, and they expose static fields, properties, and
+     * methods. While this might seem confusing at first, it actually closely matches the Java language: you use a
+     * different expression (e.g. {@code java.io.File}) as an argument in "new" and to address statics, and it is
+     * distinct from the {@code Class} object (e.g. {@code java.io.File.class}). Below we cover in details the
+     * properties of the type objects.
+     * </p>
+     * <p><b>Constructing Java objects</b></p>
+     * Examples:
+     * <pre>
+     * var arrayListType = Java.type("java.util.ArrayList")
+     * var intType = Java.type("int")
+     * var stringArrayType = Java.type("java.lang.String[]")
+     * var int2DArrayType = Java.type("int[][]")
+     * </pre>
+     * Note that the name of the type is always a string for a fully qualified name. You can use any of these types to
+     * create new instances, e.g.:
+     * <pre>
+     * var anArrayList = new Java.type("java.util.ArrayList")
+     * </pre>
+     * or
+     * <pre>
+     * var ArrayList = Java.type("java.util.ArrayList")
+     * var anArrayList = new ArrayList
+     * var anArrayListWithSize = new ArrayList(16)
+     * </pre>
+     * In the special case of inner classes, you need to use the JVM fully qualified name, meaning using {@code $} sign
+     * in the class name:
+     * <pre>
+     * var ftype = Java.type("java.awt.geom.Arc2D$Float")
+     * </pre>
+     * However, once you retrieved the outer class, you can access the inner class as a property on it:
+     * <pre>
+     * var arctype = Java.type("java.awt.geom.Arc2D")
+     * var ftype = arctype.Float
+     * </pre>
+     * <p>
+     * You can access both static and non-static inner classes. If you want to create an instance of a non-static
+     * inner class, remember to pass an instance of its outer class as the first argument to the constructor.
+     * </p>
+     * <p>
+     * If the type is abstract, you can instantiate an anonymous subclass of it using an argument list that is
+     * applicable to any of its public or protected constructors, but inserting a JavaScript object with functions
+     * properties that provide JavaScript implementations of the abstract methods. If method names are overloaded, the
+     * JavaScript function will provide implementation for all overloads. E.g.:
+     * </p>
+     * <pre>
+     * var TimerTask =  Java.type("java.util.TimerTask")
+     * var task = new TimerTask({ run: function() { print("Hello World!") } })
+     * </pre>
+     * <p>
+     * Nashorn supports a syntactic extension where a "new" expression followed by an argument is identical to
+     * invoking the constructor and passing the argument to it, so you can write the above example also as:
+     * </p>
+     * <pre>
+     * var task = new TimerTask {
+     *     run: function() {
+     *       print("Hello World!")
+     *     }
+     * }
+     * </pre>
+     * <p>
+     * which is very similar to Java anonymous inner class definition. On the other hand, if the type is an abstract
+     * type with a single abstract method (commonly referred to as a "SAM type") or all abstract methods it has share
+     * the same overloaded name), then instead of an object, you can just pass a function, so the above example can
+     * become even more simplified to:
+     * </p>
+     * <pre>
+     * var task = new TimerTask(function() { print("Hello World!") })
+     * </pre>
+     * <p>
+     * Note that in every one of these cases if you are trying to instantiate an abstract class that has constructors
+     * that take some arguments, you can invoke those simply by specifying the arguments after the initial
+     * implementation object or function.
+     * </p>
+     * <p>The use of functions can be taken even further; if you are invoking a Java method that takes a SAM type,
+     * you can just pass in a function object, and Nashorn will know what you meant:
+     * </p>
+     * <pre>
+     * var timer = new Java.type("java.util.Timer")
+     * timer.schedule(function() { print("Hello World!") })
+     * </pre>
+     * <p>
+     * Here, {@code Timer.schedule()} expects a {@code TimerTask} as its argument, so Nashorn creates an instance of a
+     * {@code TimerTask} subclass and uses the passed function to implement its only abstract method, {@code run()}. In
+     * this usage though, you can't use non-default constructors; the type must be either an interface, or must have a
+     * protected or public no-arg constructor.
+     * </p>
+     * <p>
+     * You can also subclass non-abstract classes; for that you will need to use the {@link #extend(Object, Object...)}
+     * method.
+     * </p>
+     * <p><b>Accessing static members</b></p>
+     * Examples:
+     * <pre>
+     * var File = Java.type("java.io.File")
+     * var pathSep = File.pathSeparator
+     * var tmpFile1 = File.createTempFile("abcdefg", ".tmp")
+     * var tmpFile2 = File.createTempFile("abcdefg", ".tmp", new File("/tmp"))
+     * </pre>
+     * Actually, you can even assign static methods to variables, so the above example can be rewritten as:
+     * <pre>
+     * var File = Java.type("java.io.File")
+     * var createTempFile = File.createTempFile
+     * var tmpFile1 = createTempFile("abcdefg", ".tmp")
+     * var tmpFile2 = createTempFile("abcdefg", ".tmp", new File("/tmp"))
+     * </pre>
+     * If you need to access the actual {@code java.lang.Class} object for the type, you can use the {@code class}
+     * property on the object representing the type:
+     * <pre>
+     * var File = Java.type("java.io.File")
+     * var someFile = new File("blah")
+     * print(File.class === someFile.getClass()) // prints true
+     * </pre>
+     * Of course, you can also use the {@code getClass()} method or its equivalent {@code class} property on any
+     * instance of the class. Other way round, you can use the synthetic {@code static} property on any
+     * {@code java.lang.Class} object to retrieve its type-representing object:
+     * <pre>
+     * var File = Java.type("java.io.File")
+     * print(File.class.static === File) // prints true
+     * </pre>
+     * <p><b>{@code instanceof} operator</b></p>
+     * The standard ECMAScript {@code instanceof} operator is extended to recognize Java objects and their type objects:
+     * <pre>
+     * var File = Java.type("java.io.File")
+     * var aFile = new File("foo")
+     * print(aFile instanceof File) // prints true
+     * print(aFile instanceof File.class) // prints false - Class objects aren't type objects.
+     * </pre>
+     * @param self not used
+     * @param objTypeName the object whose JS string value represents the type name. You can use names of primitive Java
+     * types to obtain representations of them, and you can use trailing square brackets to represent Java array types.
+     * @return the object representing the named type
+     * @throws ClassNotFoundException if the class is not found
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object type(final Object self, final Object objTypeName) throws ClassNotFoundException {
+        return type(objTypeName);
+    }
+
+    private static StaticClass type(final Object objTypeName) throws ClassNotFoundException {
+        return StaticClass.forClass(type(JSType.toString(objTypeName)));
+    }
+
+    private static Class<?> type(final String typeName) throws ClassNotFoundException {
+        if (typeName.endsWith("[]")) {
+            return arrayType(typeName);
+        }
+
+        return simpleType(typeName);
+    }
+
+    /**
+     * Given a JavaScript array and a Java type, returns a Java array with the same initial contents, and with the
+     * specified component type. Example:
+     * <pre>
+     * var anArray = [1, "13", false]
+     * var javaIntArray = Java.toJavaArray(anArray, "int")
+     * print(javaIntArray[0]) // prints 1
+     * print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
+     * print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
+     * </pre>
+     * @param self not used
+     * @param objArray the JavaScript array. Can be null.
+     * @param objType either a {@link #type(Object, Object) type object} or a String describing the component type of
+     * the Java array to create. Can not be null. If undefined, Object is assumed (allowing the argument to be omitted).
+     * @return a Java array with the copy of JavaScript array's contents, converted to the appropriate Java component
+     * type. Returns null if objArray is null.
+     * @throws ClassNotFoundException if the class described by objType is not found
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object toJavaArray(final Object self, final Object objArray, final Object objType) throws ClassNotFoundException {
+        final StaticClass componentType =
+            objType instanceof StaticClass ?
+                (StaticClass)objType :
+                objType == UNDEFINED ?
+                    StaticClass.forClass(Object.class) :
+                    type(objType);
+
+        if (objArray == null) {
+            return null;
+        }
+
+        Global.checkObject(objArray);
+
+        return ((ScriptObject)objArray).getArray().asArrayOfType(componentType.getRepresentedClass());
+    }
+
+    /**
+     * Given a Java array or {@link Collection}, returns a JavaScript array with a shallow copy of its contents. Note
+     * that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you
+     * need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will
+     * want to use this method. Example:
+     * <pre>
+     * var File = Java.type("java.io.File")
+     * var listHomeDir = new File("~").listFiles()
+     * var jsListHome = Java.toJavaScriptArray(listHomeDir)
+     * var jpegModifiedDates = jsListHome
+     *     .filter(function(val) { return val.getName().endsWith(".jpg") })
+     *     .map(function(val) { return val.lastModified() })
+     * </pre>
+     * @param self not used
+     * @param objArray the java array or collection. Can be null.
+     * @return a JavaScript array with the copy of Java array's or collection's contents. Returns null if objArray is
+     * null.
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object toJavaScriptArray(final Object self, final Object objArray) {
+        if (objArray == null) {
+            return null;
+        } else if (objArray instanceof Collection) {
+            return new NativeArray(((Collection<?>)objArray).toArray());
+        } else if (objArray instanceof Object[]) {
+            return new NativeArray(((Object[])objArray).clone());
+        } else if (objArray instanceof int[]) {
+            return new NativeArray(((int[])objArray).clone());
+        } else if (objArray instanceof double[]) {
+            return new NativeArray(((double[])objArray).clone());
+        } else if (objArray instanceof long[]) {
+            return new NativeArray(((long[])objArray).clone());
+        } else if (objArray instanceof byte[]) {
+            return new NativeArray(copyArray((byte[])objArray));
+        } else if (objArray instanceof short[]) {
+            return new NativeArray(copyArray((short[])objArray));
+        } else if (objArray instanceof char[]) {
+            return new NativeArray(copyArray((char[])objArray));
+        } else if (objArray instanceof float[]) {
+            return new NativeArray(copyArray((float[])objArray));
+        } else if (objArray instanceof boolean[]) {
+            return new NativeArray(copyArray((boolean[])objArray));
+        }
+
+        throw typeError("cant.convert.to.javascript.array", objArray.getClass().getName());
+    }
+
+    private static int[] copyArray(final byte[] in) {
+        final int[] out = new int[in.length];
+        for(int i = 0; i < in.length; ++i) {
+            out[i] = in[i];
+        }
+        return out;
+    }
+
+    private static int[] copyArray(final short[] in) {
+        final int[] out = new int[in.length];
+        for(int i = 0; i < in.length; ++i) {
+            out[i] = in[i];
+        }
+        return out;
+    }
+
+    private static int[] copyArray(final char[] in) {
+        final int[] out = new int[in.length];
+        for(int i = 0; i < in.length; ++i) {
+            out[i] = in[i];
+        }
+        return out;
+    }
+
+    private static double[] copyArray(final float[] in) {
+        final double[] out = new double[in.length];
+        for(int i = 0; i < in.length; ++i) {
+            out[i] = in[i];
+        }
+        return out;
+    }
+
+    private static Object[] copyArray(final boolean[] in) {
+        final Object[] out = new Object[in.length];
+        for(int i = 0; i < in.length; ++i) {
+            out[i] = in[i];
+        }
+        return out;
+    }
+
+    private static Class<?> simpleType(final String typeName) throws ClassNotFoundException {
+        final Class<?> primClass = TypeUtilities.getPrimitiveTypeByName(typeName);
+        return primClass != null ? primClass : Global.getThisContext().findClass(typeName);
+    }
+
+    private static Class<?> arrayType(final String typeName) throws ClassNotFoundException {
+        return Array.newInstance(type(typeName.substring(0, typeName.length() - 2)), 0).getClass();
+    }
+
+    /**
+     * Returns a type object for a subclass of the specified Java class (or implementation of the specified interface)
+     * that acts as a script-to-Java adapter for it. See {@link #type(Object, Object)} for a discussion of type objects,
+     * and see {@link JavaAdapterFactory} for details on script-to-Java adapters. Note that you can also implement
+     * interfaces and subclass abstract classes using {@code new} operator on a type object for an interface or abstract
+     * class. However, to extend a non-abstract class, you will have to use this method. Example:
+     * <pre>
+     * var ArrayList = Java.type("java.util.ArrayList")
+     * var ArrayListExtender = Java.extend(ArrayList)
+     * var printSizeInvokedArrayList = new ArrayListExtender() {
+     *     size: function() { print("size invoked!"); }
+     * }
+     * var printAddInvokedArrayList = new ArrayListExtender() {
+     *     add: function(x, y) {
+     *       if(typeof(y) === "undefined") {
+     *           print("add(e) invoked!");
+     *       } else {
+     *           print("add(i, e) invoked!");
+     *       }
+     * }
+     * </pre>
+     * We can see several important concepts in the above example:
+     * <ul>
+     * <li>Every Java class will have exactly one extender subclass in Nashorn - repeated invocations of {@code extend}
+     * for the same type will yield the same extender type. It's a generic adapter that delegates to whatever JavaScript
+     * functions its implementation object has on a per-instance basis.</li>
+     * <li>If the Java method is overloaded (as in the above example {@code List.add()}), then your JavaScript adapter
+     * must be prepared to deal with all overloads.</li>
+     * <li>You can't invoke {@code super.*()} from adapters for now.</li>
+     * </ul>
+     * @param self not used
+     * @param types the original types. The caller must pass at least one Java type object of class {@link StaticClass}
+     * representing either a public interface or a non-final public class with at least one public or protected
+     * constructor. If more than one type is specified, at most one can be a class and the rest have to be interfaces.
+     * Invoking the method twice with exactly the same types in the same order will return the same adapter
+     * class, any reordering of types or even addition or removal of redundant types (i.e. interfaces that other types
+     * in the list already implement/extend, or {@code java.lang.Object} in a list of types consisting purely of
+     * interfaces) will result in a different adapter class, even though those adapter classes are functionally
+     * identical; we deliberately don't want to incur the additional processing cost of canonicalizing type lists.
+     * @return a new {@link StaticClass} that represents the adapter for the original types.
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object extend(final Object self, final Object... types) {
+        if(types == null || types.length == 0) {
+            throw typeError("extend.expects.at.least.one.argument");
+        }
+        final Class<?>[] stypes = new Class<?>[types.length];
+        try {
+            for(int i = 0; i < types.length; ++i) {
+                stypes[i] = ((StaticClass)types[i]).getRepresentedClass();
+            }
+        } catch(final ClassCastException e) {
+            throw typeError("extend.expects.java.types");
+        }
+        return JavaAdapterFactory.getAdapterClassFor(stypes);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
new file mode 100644
index 0000000..88d0e6a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
@@ -0,0 +1,152 @@
+/*
+ * 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.objects;
+
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.beans.StaticClass;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.NativeJavaPackage;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * This is "JavaImporter" constructor. This constructor allows you to use Java types omitting explicit package names.
+ * Objects of this constructor are used along with {@code "with"} statements and as such are not usable in ECMAScript
+ * strict mode. Example:
+ * <pre>
+ *     var imports = new JavaImporter(java.util, java.io);
+ *     with (imports) {
+ *         var m = new HashMap(); // java.util.HashMap
+ *         var f = new File("."); // java.io.File
+ *         ...
+ *     }
+ * </pre>
+ * Note however that the preferred way for accessing Java types in Nashorn is through the use of
+ * {@link NativeJava#type(Object, Object) Java.type()} method.
+ */
+@ScriptClass("JavaImporter")
+public final class NativeJavaImporter extends ScriptObject {
+    private final Object[] args;
+
+    NativeJavaImporter(final Object[] args) {
+        this.args = args;
+        this.setProto(Global.instance().getJavaImporterPrototype());
+    }
+
+    @Override
+    public String getClassName() {
+        return "JavaImporter";
+    }
+
+    /**
+     * Constructor
+     * @param isNew is the new operator used for instantiating this NativeJavaImporter
+     * @param self self reference
+     * @param args arguments
+     * @return NativeJavaImporter instance
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean isNew, final Object self, final Object... args) {
+        return new NativeJavaImporter(args);
+    }
+
+    /**
+     * "No such property" call placeholder.
+     *
+     * This can never be called as we override {@link ScriptObject#noSuchProperty}. We do declare it here as it's a signal
+     * to {@link jdk.nashorn.internal.runtime.WithObject} that it's worth trying doing a {@code noSuchProperty} on this object.
+     *
+     * @param self self reference
+     * @param name property name
+     * @return never returns
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object __noSuchProperty__(final Object self, final Object name) {
+        throw new AssertionError("__noSuchProperty__ placeholder called");
+    }
+
+    /**
+     * "No such method call" placeholder
+     *
+     * This can never be called as we override {@link ScriptObject#noSuchMethod}. We do declare it here as it's a signal
+     * to {@link jdk.nashorn.internal.runtime.WithObject} that it's worth trying doing a noSuchProperty on this object.
+     *
+     * @param self self reference
+     * @param args arguments to method
+     * @return never returns
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object __noSuchMethod__(final Object self, final Object... args) {
+        throw new AssertionError("__noSuchMethod__ placeholder called");
+    }
+
+    @Override
+    public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) {
+        return createAndSetProperty(desc) ? super.lookup(desc, request) : super.noSuchProperty(desc, request);
+    }
+
+    @Override
+    public GuardedInvocation noSuchMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        return createAndSetProperty(desc) ? super.lookup(desc, request) : super.noSuchMethod(desc, request);
+    }
+
+    private boolean createAndSetProperty(final CallSiteDescriptor desc) {
+        final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+        final Object value = createProperty(name);
+        if(value != null) {
+            set(name, value, isStrictContext());
+            return true;
+        }
+        return false;
+    }
+
+    private Object createProperty(final String name) {
+        final int len = args.length;
+
+        for (int i = len - 1; i > -1; i--) {
+            final Object obj = args[i];
+
+            if (obj instanceof StaticClass) {
+                if (((StaticClass)obj).getRepresentedClass().getSimpleName().equals(name)) {
+                    return obj;
+                }
+            } else if (obj instanceof NativeJavaPackage) {
+                final String pkgName  = ((NativeJavaPackage)obj).getName();
+                final String fullName = pkgName.isEmpty() ? name : (pkgName + "." + name);
+                try {
+                    return StaticClass.forClass(Class.forName(fullName));
+                } catch (final ClassNotFoundException e) {
+                    // IGNORE
+                }
+            }
+        }
+        return null;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
new file mode 100644
index 0000000..7f330ef
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
@@ -0,0 +1,700 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.GlobalFunctions;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * ECMA 15.8 The Math Object
+ *
+ */
+@ScriptClass("Math")
+public final class NativeMath extends ScriptObject {
+
+    NativeMath() {
+        this.setProto(Global.objectPrototype());
+    }
+
+    /** ECMA 15.8.1.1 - E, always a double constant. Not writable or configurable */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double E = Math.E;
+
+    /** ECMA 15.8.1.2 - LN10, always a double constant. Not writable or configurable */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double LN10 = 2.302585092994046;
+
+    /** ECMA 15.8.1.3 - LN2, always a double constant. Not writable or configurable */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double LN2 = 0.6931471805599453;
+
+    /** ECMA 15.8.1.4 - LOG2E, always a double constant. Not writable or configurable */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double LOG2E = 1.4426950408889634;
+
+    /** ECMA 15.8.1.5 - LOG10E, always a double constant. Not writable or configurable */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double LOG10E = 0.4342944819032518;
+
+    /** ECMA 15.8.1.6 - PI, always a double constant. Not writable or configurable */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double PI = Math.PI;
+
+    /** ECMA 15.8.1.7 - SQRT1_2, always a double constant. Not writable or configurable */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double SQRT1_2 = 0.7071067811865476;
+
+    /** ECMA 15.8.1.8 - SQRT2, always a double constant. Not writable or configurable */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double SQRT2 = 1.4142135623730951;
+
+    /**
+     * ECMA 15.8.2.1 abs(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return abs of value
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object abs(final Object self, final Object x) {
+        return Math.abs(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.1 abs(x) - specialization for int values
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return abs of argument
+     */
+    @SpecializedFunction
+    public static int abs(final Object self, final int x) {
+        return Math.abs(x);
+    }
+
+    /**
+     * ECMA 15.8.2.1 abs(x) - specialization for long values
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return abs of argument
+     */
+    @SpecializedFunction
+    public static long abs(final Object self, final long x) {
+        return Math.abs(x);
+    }
+
+    /**
+     * ECMA 15.8.2.1 abs(x) - specialization for double values
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return abs of argument
+     */
+    @SpecializedFunction
+    public static double abs(final Object self, final double x) {
+        return Math.abs(x);
+    }
+
+    /**
+     * ECMA 15.8.2.2 acos(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return acos of argument
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object acos(final Object self, final Object x) {
+        return Math.acos(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.2 acos(x) - specialization for double values
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return acos of argument
+     */
+    @SpecializedFunction
+    public static double acos(final Object self, final double x) {
+        return Math.acos(x);
+    }
+
+    /**
+     * ECMA 15.8.2.3 asin(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return asin of argument
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object asin(final Object self, final Object x) {
+        return Math.asin(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.3 asin(x) - specialization for double values
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return asin of argument
+     */
+    @SpecializedFunction
+    public static double asin(final Object self, final double x) {
+        return Math.asin(x);
+    }
+
+    /**
+     * ECMA 15.8.2.4 atan(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return atan of argument
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object atan(final Object self, final Object x) {
+        return Math.atan(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.4 atan(x) - specialization for double values
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return atan of argument
+     */
+    @SpecializedFunction
+    public static double atan(final Object self, final double x) {
+        return Math.atan(x);
+    }
+
+    /**
+     * ECMA 15.8.2.5 atan2(x,y)
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return atan2 of x and y
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object atan2(final Object self, final Object y, final Object x) {
+        return Math.atan2(JSType.toNumber(y), JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.5 atan2(x,y) - specialization for double values
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return atan2 of x and y
+     */
+    @SpecializedFunction
+    public static double atan2(final Object self, final double y, final double x) {
+        return Math.atan2(y,x);
+    }
+
+    /**
+     * ECMA 15.8.2.6 ceil(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return ceil of argument
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object ceil(final Object self, final Object x) {
+        return Math.ceil(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.6 ceil(x) - specialized version for ints
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return ceil of argument
+     */
+    @SpecializedFunction
+    public static int ceil(final Object self, final int x) {
+        return x;
+    }
+
+    /**
+     * ECMA 15.8.2.6 ceil(x) - specialized version for longs
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return ceil of argument
+     */
+    @SpecializedFunction
+    public static long ceil(final Object self, final long x) {
+        return x;
+    }
+
+    /**
+     * ECMA 15.8.2.6 ceil(x) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return ceil of argument
+     */
+    @SpecializedFunction
+    public static double ceil(final Object self, final double x) {
+        return Math.ceil(x);
+    }
+
+    /**
+     * ECMA 15.8.2.7 cos(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return cos of argument
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object cos(final Object self, final Object x) {
+        return Math.cos(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.7 cos(x) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return cos of argument
+     */
+    @SpecializedFunction
+    public static double cos(final Object self, final double x) {
+        return Math.cos(x);
+    }
+
+    /**
+     * ECMA 15.8.2.8 exp(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return exp of argument
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object exp(final Object self, final Object x) {
+        return Math.exp(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.9 floor(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return floor of argument
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object floor(final Object self, final Object x) {
+        return Math.floor(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.9 floor(x) - specialized version for ints
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return floor of argument
+     */
+    @SpecializedFunction
+    public static int floor(final Object self, final int x) {
+        return x;
+    }
+
+    /**
+     * ECMA 15.8.2.9 floor(x) - specialized version for longs
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return floor of argument
+     */
+    @SpecializedFunction
+    public static long floor(final Object self, final long x) {
+        return x;
+    }
+
+    /**
+     * ECMA 15.8.2.9 floor(x) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return floor of argument
+     */
+    @SpecializedFunction
+    public static double floor(final Object self, final double x) {
+        return Math.floor(x);
+    }
+
+    /**
+     * ECMA 15.8.2.10 log(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return log of argument
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object log(final Object self, final Object x) {
+        return Math.log(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.10 log(x) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return log of argument
+     */
+    @SpecializedFunction
+    public static double log(final Object self, final double x) {
+        return Math.log(x);
+    }
+
+    /**
+     * ECMA 15.8.2.11 max(x)
+     *
+     * @param self  self reference
+     * @param args  arguments
+     *
+     * @return the largest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given
+     */
+    @Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object max(final Object self, final Object... args) {
+        switch (args.length) {
+        case 0:
+            return Double.NEGATIVE_INFINITY;
+        case 1:
+            return JSType.toNumber(args[0]);
+        default:
+            double res = JSType.toNumber(args[0]);
+            for (int i = 1; i < args.length; i++) {
+                res = Math.max(res, JSType.toNumber(args[i]));
+            }
+            return res;
+        }
+    }
+
+    /**
+     * ECMA 15.8.2.11 max(x) - specialized no args version
+     *
+     * @param self  self reference
+     *
+     * @return {@link Double#NEGATIVE_INFINITY}
+     */
+    @SpecializedFunction
+    public static double max(final Object self) {
+        return Double.NEGATIVE_INFINITY;
+    }
+
+    /**
+     * ECMA 15.8.2.11 max(x) - specialized version for ints
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return largest value of x and y
+     */
+    @SpecializedFunction
+    public static int max(final Object self, final int x, final int y) {
+        return Math.max(x, y);
+    }
+
+    /**
+     * ECMA 15.8.2.11 max(x) - specialized version for longs
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return largest value of x and y
+     */
+    @SpecializedFunction
+    public static long max(final Object self, final long x, final long y) {
+        return Math.max(x, y);
+    }
+
+    /**
+     * ECMA 15.8.2.11 max(x) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return largest value of x and y
+     */
+    @SpecializedFunction
+    public static double max(final Object self, final double x, final double y) {
+        return Math.max(x, y);
+    }
+
+    /**
+     * ECMA 15.8.2.12 min(x)
+     *
+     * @param self  self reference
+     * @param args  arguments
+     *
+     * @return the smallest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given
+     */
+    @Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object min(final Object self, final Object... args) {
+        switch (args.length) {
+        case 0:
+            return Double.POSITIVE_INFINITY;
+        case 1:
+            return JSType.toNumber(args[0]);
+        default:
+            double res = JSType.toNumber(args[0]);
+            for (int i = 1; i < args.length; i++) {
+                res = Math.min(res, JSType.toNumber(args[i]));
+            }
+            return res;
+        }
+    }
+
+    /**
+     * ECMA 15.8.2.11 min(x) - specialized no args version
+     *
+     * @param self  self reference
+     *
+     * @return {@link Double#POSITIVE_INFINITY}
+     */
+    @SpecializedFunction
+    public static double min(final Object self) {
+        return Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * ECMA 15.8.2.12 min(x) - specialized version for ints
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return smallest value of x and y
+     */
+    @SpecializedFunction
+    public static int min(final Object self, final int x, final int y) {
+        return Math.min(x, y);
+    }
+
+    /**
+     * ECMA 15.8.2.12 min(x) - specialized version for longs
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return smallest value of x and y
+     */
+    @SpecializedFunction
+    public static long min(final Object self, final long x, final long y) {
+        return Math.min(x, y);
+    }
+
+    /**
+     * ECMA 15.8.2.12 min(x) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return smallest value of x and y
+     */
+    @SpecializedFunction
+    public static double min(final Object self, final double x, final double y) {
+        return Math.min(x, y);
+    }
+
+    /**
+     * ECMA 15.8.2.13 pow(x,y)
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return x raised to the power of y
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object pow(final Object self, final Object x, final Object y) {
+        return Math.pow(JSType.toNumber(x), JSType.toNumber(y));
+    }
+
+    /**
+     * ECMA 15.8.2.13 pow(x,y) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     first argument
+     * @param y     second argument
+     *
+     * @return x raised to the power of y
+     */
+    @SpecializedFunction
+    public static double pow(final Object self, final double x, final double y) {
+        return Math.pow(x, y);
+    }
+
+    /**
+     * ECMA 15.8.2.14 random()
+     *
+     * @param self  self reference
+     *
+     * @return random number in the range [0..1)
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object random(final Object self) {
+        return Math.random();
+    }
+
+    /**
+     * ECMA 15.8.2.15 round(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return x rounded
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object round(final Object self, final Object x) {
+        if (GlobalFunctions.isNaN(self, x)) {
+            return Double.NaN;
+        } else if (!GlobalFunctions.isFinite(self, x)) {
+            return x;
+        }
+
+        return Math.round(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.16 sin(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return sin of x
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object sin(final Object self, final Object x) {
+        return Math.sin(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.16 sin(x) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return sin of x
+     */
+    @SpecializedFunction
+    public static double sin(final Object self, final double x) {
+        return Math.sin(x);
+    }
+
+    /**
+     * ECMA 15.8.2.17 sqrt(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return sqrt of x
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object sqrt(final Object self, final Object x) {
+        return Math.sqrt(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.17 sqrt(x) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return sqrt of x
+     */
+    @SpecializedFunction
+    public static double sqrt(final Object self, final double x) {
+        return Math.sqrt(x);
+    }
+
+    /**
+     * ECMA 15.8.2.18 tan(x)
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return tan of x
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where=Where.CONSTRUCTOR)
+    public static Object tan(final Object self, final Object x) {
+        return Math.tan(JSType.toNumber(x));
+    }
+
+    /**
+     * ECMA 15.8.2.18 tan(x) - specialized version for doubles
+     *
+     * @param self  self reference
+     * @param x     argument
+     *
+     * @return tan of x
+     */
+    @SpecializedFunction
+    public static double tan(final Object self, final double x) {
+        return Math.tan(x);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
new file mode 100644
index 0000000..edb83f0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
@@ -0,0 +1,385 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.text.NumberFormat;
+import java.util.Locale;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
+
+/**
+ * ECMA 15.7 Number Objects.
+ *
+ */
+@ScriptClass("Number")
+public final class NativeNumber extends ScriptObject {
+
+    static final MethodHandle WRAPFILTER = findWrapFilter();
+
+    /** ECMA 15.7.3.2 largest positive finite value */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double MAX_VALUE = Double.MAX_VALUE;
+
+    /** ECMA 15.7.3.3 smallest positive finite value */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double MIN_VALUE = Double.MIN_VALUE;
+
+    /** ECMA 15.7.3.4 NaN */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double NaN = Double.NaN;
+
+    /** ECMA 15.7.3.5 negative infinity */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double NEGATIVE_INFINITY = Double.NEGATIVE_INFINITY;
+
+    /** ECMA 15.7.3.5 positive infinity */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
+    public static final double POSITIVE_INFINITY = Double.POSITIVE_INFINITY;
+
+    private final double  value;
+    private final boolean isInt;
+    private final boolean isLong;
+
+    NativeNumber(final double value) {
+        this(value, Global.instance().getNumberPrototype());
+    }
+
+    private NativeNumber(final double value, final ScriptObject proto) {
+        this.value = value;
+        this.isInt  = isRepresentableAsInt(value);
+        this.isLong = isRepresentableAsLong(value);
+        this.setProto(proto);
+    }
+
+    @Override
+    public String safeToString() {
+        return "[Number " + toString() + "]";
+    }
+
+    @Override
+    public String toString() {
+        return Double.toString(getValue());
+    }
+
+    /**
+     * Get the value of this Number
+     * @return a {@code double} representing the Number value
+     */
+    public double getValue() {
+        return doubleValue();
+    }
+
+    /**
+     * Get the value of this Number
+     * @return a {@code double} representing the Number value
+     */
+    public double doubleValue() {
+        return value;
+    }
+
+    /**
+     * Get the value of this Number as a {@code int}
+     * @return an {@code int} representing the Number value
+     * @throws ClassCastException If number is not representable as an {@code int}
+     */
+    public int intValue() throws ClassCastException {
+        if (isInt) {
+            return (int)value;
+        }
+        throw new ClassCastException();
+    }
+
+    /**
+     * Get the value of this Number as a {@code long}
+     * @return a {@code long} representing the Number value
+     * @throws ClassCastException If number is not representable as an {@code long}
+     */
+    public long longValue() throws ClassCastException {
+        if (isLong) {
+            return (long)value;
+        }
+        throw new ClassCastException();
+    }
+
+    @Override
+    public String getClassName() {
+        return "Number";
+    }
+
+    /**
+     * ECMA 15.7.2 - The Number constructor
+     *
+     * @param newObj is this Number instantiated with the new operator
+     * @param self   self reference
+     * @param args   value of number
+     * @return the Number instance (internally represented as a {@code NativeNumber})
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        final double num = (args.length > 0) ? JSType.toNumber(args[0]) : 0.0;
+
+        if (newObj) {
+            final ScriptObject proto =
+                (self instanceof ScriptObject) ?
+                    ((ScriptObject)self).getProto() :
+                    Global.instance().getNumberPrototype();
+
+            return new NativeNumber(num, proto);
+        }
+
+        return num;
+    }
+
+    /**
+     * ECMA 15.7.4.5 Number.prototype.toFixed (fractionDigits)
+     *
+     * @param self           self reference
+     * @param fractionDigits how many digits should be after the decimal point, 0 if undefined
+     *
+     * @return number in decimal fixed point notation
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toFixed(final Object self, final Object fractionDigits) {
+        final int f = JSType.toInteger(fractionDigits);
+        if (f < 0 || f > 20) {
+            throw rangeError("invalid.fraction.digits", "toFixed");
+        }
+
+        final double x = getNumberValue(self);
+        if (Double.isNaN(x)) {
+            return "NaN";
+        }
+
+        if (Math.abs(x) >= 1e21) {
+            return JSType.toString(x);
+        }
+
+        final NumberFormat format = NumberFormat.getNumberInstance(Locale.US);
+        format.setMinimumFractionDigits(f);
+        format.setMaximumFractionDigits(f);
+        format.setGroupingUsed(false);
+
+        return format.format(x);
+    }
+
+    /**
+     * ECMA 15.7.4.6 Number.prototype.toExponential (fractionDigits)
+     *
+     * @param self           self reference
+     * @param fractionDigits how many digital should be after the significand's decimal point. If undefined, use as many as necessary to uniquely specify number.
+     *
+     * @return number in decimal exponential notation
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toExponential(final Object self, final Object fractionDigits) {
+        final double  x         = getNumberValue(self);
+        final boolean trimZeros = fractionDigits == UNDEFINED;
+        final int     f         = trimZeros ? 16 : JSType.toInteger(fractionDigits);
+
+        if (Double.isNaN(x)) {
+            return "NaN";
+        } else if (Double.isInfinite(x)) {
+            return x > 0? "Infinity" : "-Infinity";
+        }
+
+        if (fractionDigits != UNDEFINED && (f < 0 || f > 20)) {
+            throw rangeError("invalid.fraction.digits", "toExponential");
+        }
+
+        final String res = String.format(Locale.US, "%1." + f + "e", x);
+        return fixExponent(res, trimZeros);
+    }
+
+    /**
+     * ECMA 15.7.4.7 Number.prototype.toPrecision (precision)
+     *
+     * @param self      self reference
+     * @param precision use {@code precision - 1} digits after the significand's decimal point or call {@link NativeDate#toString} if undefined
+     *
+     * @return number in decimal exponentiation notation or decimal fixed notation depending on {@code precision}
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toPrecision(final Object self, final Object precision) {
+        final double x = getNumberValue(self);
+        if (precision == UNDEFINED) {
+            return JSType.toString(x);
+        }
+
+        final int p = JSType.toInteger(precision);
+        if (Double.isNaN(x)) {
+            return "NaN";
+        } else if (Double.isInfinite(x)) {
+            return x > 0? "Infinity" : "-Infinity";
+        }
+
+        if (p < 1 || p > 21) {
+            throw rangeError("invalid.precision");
+        }
+
+        // workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6469160
+        if (x == 0.0 && p <= 1) {
+            return "0";
+        }
+
+        return fixExponent(String.format(Locale.US, "%." + p + "g", x), false);
+    }
+
+    /**
+     * ECMA 15.7.4.2 Number.prototype.toString ( [ radix ] )
+     *
+     * @param self  self reference
+     * @param radix radix to use for string conversion
+     * @return string representation of this Number in the given radix
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toString(final Object self, final Object radix) {
+        if (radix != UNDEFINED) {
+            final int intRadix = JSType.toInteger(radix);
+            if (intRadix != 10) {
+                if (intRadix < 2 || intRadix > 36) {
+                    throw rangeError("invalid.radix");
+                }
+                return JSType.toString(getNumberValue(self), intRadix);
+            }
+        }
+
+        return JSType.toString(getNumberValue(self));
+    }
+
+    /**
+     * ECMA 15.7.4.3 Number.prototype.toLocaleString()
+     *
+     * @param self self reference
+     * @return localized string for this Number
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toLocaleString(final Object self) {
+        return JSType.toString(getNumberValue(self));
+    }
+
+
+    /**
+     * ECMA 15.7.4.4 Number.prototype.valueOf ( )
+     *
+     * @param self self reference
+     * @return boxed number value for this Number
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object valueOf(final Object self) {
+        return getNumberValue(self);
+    }
+
+    /**
+     * Lookup the appropriate method for an invoke dynamic call.
+     * @param request  The link request
+     * @param receiver receiver of call
+     * @return Link to be invoked at call site.
+     */
+    public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
+        return PrimitiveLookup.lookupPrimitive(request, Number.class, new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER);
+    }
+
+    @SuppressWarnings("unused")
+    private static NativeNumber wrapFilter(final Object receiver) {
+        return new NativeNumber(((Number)receiver).doubleValue());
+    }
+
+    private static double getNumberValue(final Object self) {
+        if (self instanceof Number) {
+            return ((Number)self).doubleValue();
+        } else if (self instanceof NativeNumber) {
+            return ((NativeNumber)self).getValue();
+        } else if (self != null && self == Global.instance().getNumberPrototype()) {
+            return 0.0;
+        } else {
+            throw typeError("not.a.number", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    // Exponent of Java "e" or "E" formatter is always 2 digits and zero
+    // padded if needed (e+01, e+00, e+12 etc.) JS expects exponent to contain
+    // exact number of digits e+1, e+0, e+12 etc. Fix the exponent here.
+    //
+    // Additionally, if trimZeros is true, this cuts trailing zeros in the
+    // fraction part for calls to toExponential() with undefined fractionDigits
+    // argument.
+    private static String fixExponent(final String str, final boolean trimZeros) {
+        final int index = str.indexOf('e');
+        if (index < 1) {
+            // no exponent, do nothing..
+            return str;
+        }
+
+        // check if character after e+ or e- is 0
+        final int expPadding = str.charAt(index + 2) == '0' ? 3 : 2;
+        // check if there are any trailing zeroes we should remove
+
+        int fractionOffset = index;
+        if (trimZeros) {
+            assert fractionOffset > 0;
+            char c = str.charAt(fractionOffset - 1);
+            while (fractionOffset > 1 && (c == '0' || c == '.')) {
+                c = str.charAt(--fractionOffset - 1);
+            }
+
+        }
+        // if anything needs to be done compose a new string
+        if (fractionOffset < index || expPadding == 3) {
+            return str.substring(0, fractionOffset)
+                    + str.substring(index, index + 2)
+                    + str.substring(index + expPadding);
+        }
+        return str;
+    }
+
+    private static MethodHandle findWrapFilter() {
+        try {
+            return MethodHandles.lookup().findStatic(NativeNumber.class, "wrapFilter", MH.type(NativeNumber.class, Object.class));
+        } catch (final NoSuchMethodException | IllegalAccessException e) {
+            throw new MethodHandleFactory.LookupException(e);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
new file mode 100644
index 0000000..5162d89
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
@@ -0,0 +1,411 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.linker.InvokeByName;
+
+/**
+ * ECMA 15.2 Object objects
+ *
+ * JavaScript Object constructor/prototype. Note: instances of this class are
+ * never created. This class is not even a subclass of ScriptObject. But, we use
+ * this class to generate prototype and constructor for "Object".
+ *
+ */
+@ScriptClass("Object")
+public final class NativeObject {
+    private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
+
+    private NativeObject() {
+    }
+
+    /**
+     * ECMA 15.2.3.2 Object.getPrototypeOf ( O )
+     *
+     * @param  self self reference
+     * @param  obj object to get prototype from
+     * @return the prototype of an object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object getPrototypeOf(final Object self, final Object obj) {
+        Global.checkObject(obj);
+
+        return ((ScriptObject)obj).getProto();
+    }
+
+    /**
+     * ECMA 15.2.3.3 Object.getOwnPropertyDescriptor ( O, P )
+     *
+     * @param self  self reference
+     * @param obj   object from which to get property descriptor for {@code ToString(prop)}
+     * @param prop  property descriptor
+     * @return property descriptor
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) {
+        Global.checkObject(obj);
+
+        final String       key  = JSType.toString(prop);
+        final ScriptObject sobj = (ScriptObject)obj;
+
+        return sobj.getOwnPropertyDescriptor(key);
+    }
+
+    /**
+     * ECMA 15.2.3.4 Object.getOwnPropertyNames ( O )
+     *
+     * @param self self reference
+     * @param obj  object to query for property names
+     * @return array of property names
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object getOwnPropertyNames(final Object self, final Object obj) {
+        Global.checkObject(obj);
+
+        return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
+    }
+
+    /**
+     * ECMA 15.2.3.5 Object.create ( O [, Properties] )
+     *
+     * @param self  self reference
+     * @param proto prototype object
+     * @param props properties to define
+     * @return object created
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object create(final Object self, final Object proto, final Object props) {
+        if (proto != null) {
+            Global.checkObject(proto);
+        }
+
+        // FIXME: should we create a proper object with correct number of
+        // properties?
+        final ScriptObject newObj = Global.newEmptyInstance();
+        newObj.setProtoCheck(proto);
+        if (props != UNDEFINED) {
+            NativeObject.defineProperties(self, newObj, props);
+        }
+
+        return newObj;
+    }
+
+    /**
+     * ECMA 15.2.3.6 Object.defineProperty ( O, P, Attributes )
+     *
+     * @param self self reference
+     * @param obj  object in which to define a property
+     * @param prop property to define
+     * @param attr attributes for property descriptor
+     * @return object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
+        Global.checkObject(obj);
+        ((ScriptObject)obj).defineOwnProperty(JSType.toString(prop), attr, true);
+        return obj;
+    }
+
+    /**
+     * ECMA 5.2.3.7 Object.defineProperties ( O, Properties )
+     *
+     * @param self  self reference
+     * @param obj   object in which to define properties
+     * @param props properties
+     * @return object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object defineProperties(final Object self, final Object obj, final Object props) {
+        Global.checkObject(obj);
+
+        final ScriptObject sobj     = (ScriptObject)obj;
+        final Object       propsObj = Global.toObject(props);
+
+        if (propsObj instanceof ScriptObject) {
+            final Object[] keys = ((ScriptObject)propsObj).getOwnKeys(false);
+            for (final Object key : keys) {
+                final String prop = JSType.toString(key);
+                sobj.defineOwnProperty(prop, ((ScriptObject)propsObj).get(prop), true);
+            }
+        }
+        return sobj;
+    }
+
+    /**
+     * ECMA 15.2.3.8 Object.seal ( O )
+     *
+     * @param self self reference
+     * @param obj  object to seal
+     * @return sealed object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object seal(final Object self, final Object obj) {
+        Global.checkObject(obj);
+        return ((ScriptObject)obj).seal();
+    }
+
+
+    /**
+     * ECMA 15.2.3.9 Object.freeze ( O )
+     *
+     * @param self self reference
+     * @param obj object to freeze
+     * @return frozen object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object freeze(final Object self, final Object obj) {
+        Global.checkObject(obj);
+        return ((ScriptObject)obj).freeze();
+    }
+
+    /**
+     * ECMA 15.2.3.10 Object.preventExtensions ( O )
+     *
+     * @param self self reference
+     * @param obj  object, for which to set the internal extensible property to false
+     * @return object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object preventExtensions(final Object self, final Object obj) {
+        Global.checkObject(obj);
+        return ((ScriptObject)obj).preventExtensions();
+    }
+
+    /**
+     * ECMA 15.2.3.11 Object.isSealed ( O )
+     *
+     * @param self self reference
+     * @param obj check whether an object is sealed
+     * @return true if sealed, false otherwise
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object isSealed(final Object self, final Object obj) {
+        Global.checkObject(obj);
+        return ((ScriptObject)obj).isSealed();
+    }
+
+    /**
+     * ECMA 15.2.3.12 Object.isFrozen ( O )
+     *
+     * @param self self reference
+     * @param obj check whether an object
+     * @return true if object is frozen, false otherwise
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object isFrozen(final Object self, final Object obj) {
+        Global.checkObject(obj);
+        return ((ScriptObject)obj).isFrozen();
+    }
+
+    /**
+     * ECMA 15.2.3.13 Object.isExtensible ( O )
+     *
+     * @param self self reference
+     * @param obj check whether an object is extensible
+     * @return true if object is extensible, false otherwise
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object isExtensible(final Object self, final Object obj) {
+        Global.checkObject(obj);
+        return ((ScriptObject)obj).isExtensible();
+    }
+
+    /**
+     * ECMA 15.2.3.14 Object.keys ( O )
+     *
+     * @param self self reference
+     * @param obj  object from which to extract keys
+     * @return array of keys in object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object keys(final Object self, final Object obj) {
+        Global.checkObject(obj);
+        final ScriptObject sobj = (ScriptObject)obj;
+        return new NativeArray(sobj.getOwnKeys(false));
+    }
+
+    /**
+     * ECMA 15.2.2.1 , 15.2.1.1 new Object([value]) and Object([value])
+     *
+     * Constructor
+     *
+     * @param newObj is the new object instantiated with the new operator
+     * @param self   self reference
+     * @param value  value of object to be instantiated
+     * @return the new NativeObject
+     */
+    @Constructor
+    public static Object construct(final boolean newObj, final Object self, final Object value) {
+        final JSType type = JSType.of(value);
+
+        // Object(null), Object(undefined), Object() are same as "new Object()"
+
+        if (newObj || (type == JSType.NULL || type == JSType.UNDEFINED)) {
+            switch (type) {
+            case BOOLEAN:
+            case NUMBER:
+            case STRING:
+                return Global.toObject(value);
+            case OBJECT:
+            case FUNCTION:
+                return value;
+            case NULL:
+            case UNDEFINED:
+                // fall through..
+            default:
+                break;
+            }
+
+            return Global.newEmptyInstance();
+        }
+
+        return Global.toObject(value);
+    }
+
+    /**
+     * ECMA 15.2.4.2 Object.prototype.toString ( )
+     *
+     * @param self self reference
+     * @return ToString of object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toString(final Object self) {
+        return ScriptRuntime.builtinObjectToString(self);
+    }
+
+    /**
+     * ECMA 15.2.4.3 Object.prototype.toLocaleString ( )
+     *
+     * @param self self reference
+     * @return localized ToString
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toLocaleString(final Object self) {
+        final Object obj = JSType.toScriptObject(self);
+        if (obj instanceof ScriptObject) {
+            final ScriptObject sobj = (ScriptObject)self;
+            try {
+                final Object toString = TO_STRING.getGetter().invokeExact(sobj);
+
+                if (toString instanceof ScriptFunction) {
+                    return TO_STRING.getInvoker().invokeExact(toString, sobj);
+                }
+            } catch (final RuntimeException | Error e) {
+                throw e;
+            } catch (final Throwable t) {
+                throw new RuntimeException(t);
+            }
+
+            throw typeError("not.a.function", "toString");
+        }
+
+        return ScriptRuntime.builtinObjectToString(self);
+    }
+
+    /**
+     * ECMA 15.2.4.4 Object.prototype.valueOf ( )
+     *
+     * @param self self reference
+     * @return value of object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object valueOf(final Object self) {
+        return Global.toObject(self);
+    }
+
+    /**
+     * ECMA 15.2.4.5 Object.prototype.hasOwnProperty (V)
+     *
+     * @param self self reference
+     * @param v property to check for
+     * @return true if property exists in object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object hasOwnProperty(final Object self, final Object v) {
+        final String str = JSType.toString(v);
+        final Object obj = Global.toObject(self);
+
+        return (obj instanceof ScriptObject) && ((ScriptObject)obj).hasOwnProperty(str);
+    }
+
+    /**
+     * ECMA 15.2.4.6 Object.prototype.isPrototypeOf (V)
+     *
+     * @param self self reference
+     * @param v v prototype object to check against
+     * @return true if object is prototype of v
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object isPrototypeOf(final Object self, final Object v) {
+        if (!(v instanceof ScriptObject)) {
+            return false;
+        }
+
+        final Object obj   = Global.toObject(self);
+        ScriptObject proto = (ScriptObject)v;
+
+        do {
+            proto = proto.getProto();
+            if (proto == obj) {
+                return true;
+            }
+        } while (proto != null);
+
+        return false;
+    }
+
+    /**
+     * ECMA 15.2.4.7 Object.prototype.propertyIsEnumerable (V)
+     *
+     * @param self self reference
+     * @param v property to check if enumerable
+     * @return true if property is enumerable
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object propertyIsEnumerable(final Object self, final Object v) {
+        final String str = JSType.toString(v);
+        final Object obj = Global.toObject(self);
+
+        if (obj instanceof ScriptObject) {
+            final jdk.nashorn.internal.runtime.Property property = ((ScriptObject)obj).getMap().findProperty(str);
+            return property != null && property.isEnumerable();
+        }
+
+        return false;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java
new file mode 100644
index 0000000..dcdd517
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java
@@ -0,0 +1,86 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * ECMA 15.11.6.2 RangeError
+ *
+ */
+@ScriptClass("Error")
+public final class NativeRangeError extends ScriptObject {
+
+    /** message property in instance */
+    @Property(name = NativeError.MESSAGE)
+    public Object instMessage;
+
+    /** error name property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object name;
+
+    /** ECMA 15.1.1.1 message property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object message;
+
+    NativeRangeError(final Object msg) {
+        setProto(Global.instance().getRangeErrorPrototype());
+        if (msg != UNDEFINED) {
+            this.instMessage = JSType.toString(msg);
+        } else {
+            this.delete(NativeError.MESSAGE, Global.isStrict());
+        }
+    }
+
+    @Override
+    public String getClassName() {
+        return "Error";
+    }
+
+    /**
+     * ECMA 15.11.6.2 RangeError
+     *
+     * Constructor
+     *
+     * @param newObj was this error instantiated with the new operator
+     * @param self   self reference
+     * @param msg    error message
+     *
+     * @return new RangeError
+     */
+    @Constructor(name = "RangeError")
+    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+        return new NativeRangeError(msg);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java
new file mode 100644
index 0000000..a3ae89e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java
@@ -0,0 +1,86 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * ECMA 15.11.6.3 ReferenceError
+ *
+ */
+@ScriptClass("Error")
+public final class NativeReferenceError extends ScriptObject {
+
+    /** message property in instance */
+    @Property(name = NativeError.MESSAGE)
+    public Object instMessage;
+
+    /** error name property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object name;
+
+    /** ECMA 15.1.1.1 message property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object message;
+
+    NativeReferenceError(final Object msg) {
+        this.setProto(Global.instance().getReferenceErrorPrototype());
+        if (msg != UNDEFINED) {
+            this.instMessage = JSType.toString(msg);
+        } else {
+            this.delete(NativeError.MESSAGE, Global.isStrict());
+        }
+    }
+
+    @Override
+    public String getClassName() {
+        return "Error";
+    }
+
+    /**
+     * ECMA 15.11.6.3 ReferenceError
+     *
+     * Constructor
+     *
+     * @param newObj was this error instantiated with the new operator
+     * @param self   self reference
+     * @param msg    error message
+     *
+     * @return new ReferenceError
+     */
+    @Constructor(name = "ReferenceError")
+    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+        return new NativeReferenceError(msg);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
new file mode 100644
index 0000000..d386531
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
@@ -0,0 +1,896 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Getter;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.BitVector;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.regexp.RegExp;
+import jdk.nashorn.internal.runtime.regexp.RegExpFactory;
+import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+import jdk.nashorn.internal.runtime.regexp.RegExpMatcher;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * ECMA 15.10 RegExp Objects.
+ */
+@ScriptClass("RegExp")
+public final class NativeRegExp extends ScriptObject {
+    /** ECMA 15.10.7.5 lastIndex property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+    public Object lastIndex;
+
+    /** Compiled regexp */
+    private RegExp regexp;
+
+    // Reference to global object needed to support static RegExp properties
+    private Global globalObject;
+
+    NativeRegExp(final String input, final String flagString) {
+        try {
+            this.regexp = RegExpFactory.create(input, flagString);
+        } catch (final ParserException e) {
+            // translate it as SyntaxError object and throw it
+            e.throwAsEcmaException();
+            throw new AssertionError(); //guard against null warnings below
+        }
+
+        this.setLastIndex(0);
+        init();
+    }
+
+    NativeRegExp(final String string) {
+        this(string, "");
+    }
+
+    NativeRegExp(final NativeRegExp regExp) {
+        this.lastIndex  = regExp.getLastIndexObject();
+        this.regexp      = regExp.getRegExp();
+        init();
+    }
+
+    @Override
+    public String getClassName() {
+        return "RegExp";
+    }
+
+    /**
+     * ECMA 15.10.4
+     *
+     * Constructor
+     *
+     * @param isNew is the new operator used for instantiating this regexp
+     * @param self  self reference
+     * @param args  arguments (optional: pattern and flags)
+     * @return new NativeRegExp
+     */
+    @Constructor(arity = 2)
+    public static Object constructor(final boolean isNew, final Object self, final Object... args) {
+        if (args.length > 1) {
+            return newRegExp(args[0], args[1]);
+        } else if (args.length > 0) {
+            return newRegExp(args[0], UNDEFINED);
+        }
+
+        return newRegExp(UNDEFINED, UNDEFINED);
+    }
+
+    /**
+     * ECMA 15.10.4
+     *
+     * Constructor - specialized version, no args, empty regexp
+     *
+     * @param isNew is the new operator used for instantiating this regexp
+     * @param self  self reference
+     * @return new NativeRegExp
+     */
+    @SpecializedConstructor
+    public static Object constructor(final boolean isNew, final Object self) {
+        return new NativeRegExp("", "");
+    }
+
+    /**
+     * ECMA 15.10.4
+     *
+     * Constructor - specialized version, pattern, no flags
+     *
+     * @param isNew is the new operator used for instantiating this regexp
+     * @param self  self reference
+     * @param pattern pattern
+     * @return new NativeRegExp
+     */
+    @SpecializedConstructor
+    public static Object constructor(final boolean isNew, final Object self, final Object pattern) {
+        return newRegExp(pattern, UNDEFINED);
+    }
+
+    /**
+     * ECMA 15.10.4
+     *
+     * Constructor - specialized version, pattern and flags
+     *
+     * @param isNew is the new operator used for instantiating this regexp
+     * @param self  self reference
+     * @param pattern pattern
+     * @param flags  flags
+     * @return new NativeRegExp
+     */
+    @SpecializedConstructor
+    public static Object constructor(final boolean isNew, final Object self, final Object pattern, final Object flags) {
+        return newRegExp(pattern, flags);
+    }
+
+    /**
+     * External constructor used in generated code, which explains the public access
+     *
+     * @param regexp regexp
+     * @param flags  flags
+     * @return new NativeRegExp
+     */
+    public static NativeRegExp newRegExp(final Object regexp, final Object flags) {
+        String  patternString = "";
+        String  flagString    = "";
+        boolean flagsDefined  = false;
+
+        if (flags != UNDEFINED) {
+            flagsDefined = true;
+            flagString = JSType.toString(flags);
+        }
+
+        if (regexp != UNDEFINED) {
+            if (regexp instanceof NativeRegExp) {
+                if (!flagsDefined) {
+                    return (NativeRegExp)regexp; // 15.10.3.1 - undefined flags and regexp as
+                }
+                throw typeError("regex.cant.supply.flags");
+            }
+            patternString = JSType.toString(regexp);
+        }
+
+        return new NativeRegExp(patternString, flagString);
+    }
+
+    /**
+     * Build a regexp that matches {@code string} as-is. All meta-characters will be escaped.
+     *
+     * @param string pattern string
+     * @return flat regexp
+     */
+    static NativeRegExp flatRegExp(String string) {
+        // escape special characters
+        StringBuilder sb = null;
+        final int length = string.length();
+
+        for (int i = 0; i < length; i++) {
+            final char c = string.charAt(i);
+            switch (c) {
+                case '^':
+                case '$':
+                case '\\':
+                case '.':
+                case '*':
+                case '+':
+                case '?':
+                case '(':
+                case ')':
+                case '[':
+                case '{':
+                case '|':
+                    if (sb == null) {
+                        sb = new StringBuilder(length * 2);
+                        sb.append(string, 0, i);
+                    }
+                    sb.append('\\');
+                    sb.append(c);
+                    break;
+                default:
+                    if (sb != null) {
+                        sb.append(c);
+                    }
+                    break;
+            }
+        }
+        return new NativeRegExp(sb == null ? string : sb.toString(), "");
+    }
+
+    private String getFlagString() {
+        final StringBuilder sb = new StringBuilder(3);
+
+        if (regexp.isGlobal()) {
+            sb.append('g');
+        }
+        if (regexp.isIgnoreCase()) {
+            sb.append('i');
+        }
+        if (regexp.isMultiline()) {
+            sb.append('m');
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public String safeToString() {
+        return "[RegExp " + toString() + "]";
+    }
+
+    @Override
+    public String toString() {
+        return "/" + regexp.getSource() + "/" + getFlagString();
+    }
+
+    /**
+     * Nashorn extension: RegExp.prototype.compile - everybody implements this!
+     *
+     * @param self    self reference
+     * @param pattern pattern
+     * @param flags   flags
+     * @return new NativeRegExp
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object compile(final Object self, final Object pattern, final Object flags) {
+        final NativeRegExp regExp   = checkRegExp(self);
+        final NativeRegExp compiled = newRegExp(pattern, flags);
+        // copy over regexp to 'self'
+        regExp.setRegExp(compiled.getRegExp());
+
+        // Some implementations return undefined. Some return 'self'. Since return
+        // value is most likely be ignored, we can play safe and return 'self'.
+        return regExp;
+    }
+
+    /**
+     * ECMA 15.10.6.2 RegExp.prototype.exec(string)
+     *
+     * @param self   self reference
+     * @param string string to match against regexp
+     * @return array containing the matches or {@code null} if no match
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object exec(final Object self, final Object string) {
+        return checkRegExp(self).exec(JSType.toString(string));
+    }
+
+    /**
+     * ECMA 15.10.6.3 RegExp.prototype.test(string)
+     *
+     * @param self   self reference
+     * @param string string to test for matches against regexp
+     * @return true if matches found, false otherwise
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object test(final Object self, final Object string) {
+        return checkRegExp(self).test(JSType.toString(string));
+    }
+
+    /**
+     * ECMA 15.10.6.4 RegExp.prototype.toString()
+     *
+     * @param self self reference
+     * @return string version of regexp
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toString(final Object self) {
+        return checkRegExp(self).toString();
+    }
+
+    /**
+     * ECMA 15.10.7.1 source
+     *
+     * @param self self reference
+     * @return the input string for the regexp
+     */
+    @Getter(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public static Object source(final Object self) {
+        return checkRegExp(self).getRegExp().getSource();
+    }
+
+    /**
+     * ECMA 15.10.7.2 global
+     *
+     * @param self self reference
+     * @return true if this regexp is flagged global, false otherwise
+     */
+    @Getter(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public static Object global(final Object self) {
+        return checkRegExp(self).getRegExp().isGlobal();
+    }
+
+    /**
+     * ECMA 15.10.7.3 ignoreCase
+     *
+     * @param self self reference
+     * @return true if this regexp if flagged to ignore case, false otherwise
+     */
+    @Getter(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public static Object ignoreCase(final Object self) {
+        return checkRegExp(self).getRegExp().isIgnoreCase();
+    }
+
+    /**
+     * ECMA 15.10.7.4 multiline
+     *
+     * @param self self reference
+     * @return true if this regexp is flagged to be multiline, false otherwise
+     */
+    @Getter(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public static Object multiline(final Object self) {
+        return checkRegExp(self).getRegExp().isMultiline();
+    }
+
+    /**
+     * Getter for non-standard RegExp.input property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "input")
+    public static Object getLastInput(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getInput();
+    }
+
+    /**
+     * Getter for non-standard RegExp.multiline property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "multiline")
+    public static Object getLastMultiline(Object self) {
+        return false; // doesn't ever seem to become true and isn't documented anyhwere
+    }
+
+    /**
+     * Getter for non-standard RegExp.lastMatch property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "lastMatch")
+    public static Object getLastMatch(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(0);
+    }
+
+    /**
+     * Getter for non-standard RegExp.lastParen property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "lastParen")
+    public static Object getLastParen(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getLastParen();
+    }
+
+    /**
+     * Getter for non-standard RegExp.leftContext property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "leftContext")
+    public static Object getLeftContext(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getInput().substring(0, match.getIndex());
+    }
+
+    /**
+     * Getter for non-standard RegExp.rightContext property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "rightContext")
+    public static Object getRightContext(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getInput().substring(match.getIndex() + match.length());
+    }
+
+    /**
+     * Getter for non-standard RegExp.$1 property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$1")
+    public static Object getGroup1(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(1);
+    }
+
+    /**
+     * Getter for non-standard RegExp.$2 property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$2")
+    public static Object getGroup2(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(2);
+    }
+
+    /**
+     * Getter for non-standard RegExp.$3 property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$3")
+    public static Object getGroup3(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(3);
+    }
+
+    /**
+     * Getter for non-standard RegExp.$4 property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$4")
+    public static Object getGroup4(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(4);
+    }
+
+    /**
+     * Getter for non-standard RegExp.$5 property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$5")
+    public static Object getGroup5(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(5);
+    }
+
+    /**
+     * Getter for non-standard RegExp.$6 property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$6")
+    public static Object getGroup6(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(6);
+    }
+
+    /**
+     * Getter for non-standard RegExp.$7 property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$7")
+    public static Object getGroup7(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(7);
+    }
+
+    /**
+     * Getter for non-standard RegExp.$8 property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$8")
+    public static Object getGroup8(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(8);
+    }
+
+    /**
+     * Getter for non-standard RegExp.$9 property.
+     * @param self self object
+     * @return last regexp input
+     */
+    @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$9")
+    public static Object getGroup9(Object self) {
+        final RegExpResult match = Global.instance().getLastRegExpResult();
+        return match == null ? "" : match.getGroup(9);
+    }
+
+    private RegExpResult execInner(final String string) {
+
+        final int start = regexp.isGlobal() ? getLastIndex() : 0;
+        if (start < 0 || start > string.length()) {
+            setLastIndex(0);
+            return null;
+        }
+
+        final RegExpMatcher matcher = regexp.match(string);
+        if (matcher == null || !matcher.search(start)) {
+            setLastIndex(0);
+            return null;
+        }
+
+        if (regexp.isGlobal()) {
+            setLastIndex(matcher.end());
+        }
+
+        final RegExpResult match = new RegExpResult(string, matcher.start(), groups(matcher));
+        globalObject.setLastRegExpResult(match);
+        return match;
+    }
+
+    /**
+     * Convert java.util.regex.Matcher groups to JavaScript groups.
+     * That is, replace null and groups that didn't match with undefined.
+     */
+    private Object[] groups(final RegExpMatcher matcher) {
+        final int groupCount = matcher.groupCount();
+        final Object[] groups = new Object[groupCount + 1];
+        final BitVector groupsInNegativeLookahead  = regexp.getGroupsInNegativeLookahead();
+
+        for (int i = 0, lastGroupStart = matcher.start(); i <= groupCount; i++) {
+            final int groupStart = matcher.start(i);
+            if (lastGroupStart > groupStart
+                    || (groupsInNegativeLookahead != null && groupsInNegativeLookahead.isSet(i))) {
+                // (1) ECMA 15.10.2.5 NOTE 3: need to clear Atom's captures each time Atom is repeated.
+                // (2) ECMA 15.10.2.8 NOTE 3: Backreferences to captures in (?!Disjunction) from elsewhere
+                // in the pattern always return undefined because the negative lookahead must fail.
+                groups[i] = UNDEFINED;
+                continue;
+            }
+            final String group = matcher.group(i);
+            groups[i] = group == null ? UNDEFINED : group;
+            lastGroupStart = groupStart;
+        }
+        return groups;
+    }
+
+    /**
+     * Executes a search for a match within a string based on a regular
+     * expression. It returns an array of information or null if no match is
+     * found.
+     *
+     * @param string String to match.
+     * @return NativeArray of matches, string or null.
+     */
+    public Object exec(final String string) {
+        final RegExpResult match = execInner(string);
+
+        if (match == null) {
+            return null;
+        }
+
+        return new NativeRegExpExecResult(match);
+    }
+
+    /**
+     * Executes a search for a match within a string based on a regular
+     * expression.
+     *
+     * @param string String to match.
+     * @return True if a match is found.
+     */
+    public Object test(final String string) {
+        return exec(string) != null;
+    }
+
+    /**
+     * Searches and replaces the regular expression portion (match) with the
+     * replaced text instead. For the "replacement text" parameter, you can use
+     * the keywords $1 to $2 to replace the original text with values from
+     * sub-patterns defined within the main pattern.
+     *
+     * @param string String to match.
+     * @param replacement Replacement string.
+     * @return String with substitutions.
+     */
+    Object replace(final String string, final String replacement, final ScriptFunction function) {
+        final RegExpMatcher matcher = regexp.match(string);
+
+        if (matcher == null) {
+            return string;
+        }
+
+        /*
+         * $$ -> $
+         * $& -> the matched substring
+         * $` -> the portion of string that preceeds matched substring
+         * $' -> the portion of string that follows the matched substring
+         * $n -> the nth capture, where n is [1-9] and $n is NOT followed by a decimal digit
+         * $nn -> the nnth capture, where nn is a two digit decimal number [01-99].
+         */
+        String replace = replacement;
+
+        if (!regexp.isGlobal()) {
+            if (!matcher.search(0)) {
+                return string;
+            }
+
+            final StringBuilder sb = new StringBuilder();
+            if (function != null) {
+                replace = callReplaceValue(function, matcher, string);
+            }
+            appendReplacement(matcher, string, replace, sb, 0);
+            sb.append(string, matcher.end(), string.length());
+            return sb.toString();
+        }
+
+        setLastIndex(0);
+
+        if (!matcher.search(0)) {
+            return string;
+        }
+
+        int thisIndex = 0;
+        int previousLastIndex = 0;
+        final StringBuilder sb = new StringBuilder();
+
+        do {
+            if (function != null) {
+                replace = callReplaceValue(function, matcher, string);
+            }
+
+            appendReplacement(matcher, string, replace, sb, thisIndex);
+
+            // ECMA 15.5.4.10 String.prototype.match(regexp)
+            thisIndex = matcher.end();
+            if (thisIndex == previousLastIndex) {
+                setLastIndex(thisIndex + 1);
+                previousLastIndex = thisIndex + 1;
+            } else {
+                previousLastIndex = thisIndex;
+            }
+        } while (previousLastIndex <= string.length() && matcher.search(previousLastIndex));
+
+        sb.append(string, thisIndex, string.length());
+
+        return sb.toString();
+    }
+
+    private void appendReplacement(final RegExpMatcher matcher, final String text, final String replacement, final StringBuilder sb, final int lastAppendPosition) {
+        // Process substitution string to replace group references with groups
+        int cursor = 0;
+        final StringBuilder result = new StringBuilder();
+        Object[] groups = null;
+
+        while (cursor < replacement.length()) {
+            char nextChar = replacement.charAt(cursor);
+            if (nextChar == '$') {
+                // Skip past $
+                cursor++;
+                nextChar = replacement.charAt(cursor);
+                final int firstDigit = nextChar - '0';
+
+                if (firstDigit >= 0 && firstDigit <= 9 && firstDigit <= matcher.groupCount()) {
+                    // $0 is not supported, but $01 is. implementation-defined: if n>m, ignore second digit.
+                    int refNum = firstDigit;
+                    cursor++;
+                    if (cursor < replacement.length() && firstDigit < matcher.groupCount()) {
+                        final int secondDigit = replacement.charAt(cursor) - '0';
+                        if ((secondDigit >= 0) && (secondDigit <= 9)) {
+                            final int newRefNum = (firstDigit * 10) + secondDigit;
+                            if (newRefNum <= matcher.groupCount() && newRefNum > 0) {
+                                // $nn ($01-$99)
+                                refNum = newRefNum;
+                                cursor++;
+                            }
+                        }
+                    }
+                    if (refNum > 0) {
+                        if (groups == null) {
+                            groups = groups(matcher);
+                        }
+                        // Append group if matched.
+                        if (groups[refNum] != UNDEFINED) {
+                            result.append((String) groups[refNum]);
+                        }
+                    } else { // $0. ignore.
+                        assert refNum == 0;
+                        result.append("$0");
+                    }
+                } else if (nextChar == '$') {
+                    result.append('$');
+                    cursor++;
+                } else if (nextChar == '&') {
+                    result.append(matcher.group());
+                    cursor++;
+                } else if (nextChar == '`') {
+                    result.append(text.substring(0, matcher.start()));
+                    cursor++;
+                } else if (nextChar == '\'') {
+                    result.append(text.substring(matcher.end()));
+                    cursor++;
+                } else {
+                    // unknown substitution or $n with n>m. skip.
+                    result.append('$');
+                }
+            } else {
+                result.append(nextChar);
+                cursor++;
+            }
+        }
+        // Append the intervening text
+        sb.append(text, lastAppendPosition, matcher.start());
+        // Append the match substitution
+        sb.append(result);
+    }
+
+    private String callReplaceValue(final ScriptFunction function, final RegExpMatcher matcher, final String string) {
+        final Object[] groups = groups(matcher);
+        final Object[] args   = Arrays.copyOf(groups, groups.length + 2);
+
+        args[groups.length]     = matcher.start();
+        args[groups.length + 1] = string;
+
+        final Object self = function.isStrict() ? UNDEFINED : Global.instance();
+
+        return JSType.toString(ScriptRuntime.apply(function, self, args));
+    }
+
+    /**
+     * Breaks up a string into an array of substrings based on a regular
+     * expression or fixed string.
+     *
+     * @param string String to match.
+     * @param limit  Split limit.
+     * @return Array of substrings.
+     */
+    Object split(final String string, final long limit) {
+        return split(this, string, limit);
+    }
+
+    private static Object split(final NativeRegExp regexp0, final String input, final long limit) {
+        final List<Object> matches = new ArrayList<>();
+
+        final NativeRegExp regexp = new NativeRegExp(regexp0);
+        regexp.setGlobal(true);
+
+        if (limit == 0L) {
+            return new NativeArray();
+        }
+
+        RegExpResult match;
+        final int inputLength = input.length();
+        int lastLength = -1;
+        int lastLastIndex = 0;
+
+        while ((match = regexp.execInner(input)) != null) {
+            final int lastIndex = match.getIndex() + match.length();
+
+            if (lastIndex > lastLastIndex) {
+                matches.add(input.substring(lastLastIndex, match.getIndex()));
+                if (match.getGroups().length > 1 && match.getIndex() < inputLength) {
+                    matches.addAll(Arrays.asList(match.getGroups()).subList(1, match.getGroups().length));
+                }
+
+                lastLength = match.length();
+                lastLastIndex = lastIndex;
+
+                if (matches.size() >= limit) {
+                    break;
+                }
+            }
+
+            // bump the index to avoid infinite loop
+            if (regexp.getLastIndex() == match.getIndex()) {
+                regexp.setLastIndex(match.getIndex() + 1);
+            }
+        }
+
+        if (matches.size() < limit) {
+            // check special case if we need to append an empty string at the
+            // end of the match
+            // if the lastIndex was the entire string
+            if (lastLastIndex == input.length()) {
+                if (lastLength > 0 || regexp.test("") == Boolean.FALSE) {
+                    matches.add("");
+                }
+            } else {
+                matches.add(input.substring(lastLastIndex, inputLength));
+            }
+        }
+
+        return new NativeArray(matches.toArray());
+    }
+
+    /**
+     * Tests for a match in a string. It returns the index of the match, or -1
+     * if not found.
+     *
+     * @param string String to match.
+     * @return Index of match.
+     */
+    Object search(final String string) {
+        final RegExpResult match = execInner(string);
+
+        if (match == null) {
+            return -1;
+        }
+
+        return match.getIndex();
+    }
+
+    /**
+     * Fast lastIndex getter
+     * @return last index property as int
+     */
+    public int getLastIndex() {
+        return JSType.toInt32(lastIndex);
+    }
+
+    /**
+     * Fast lastIndex getter
+     * @return last index property as boxed integer
+     */
+    public Object getLastIndexObject() {
+        return lastIndex;
+    }
+
+    /**
+     * Fast lastIndex setter
+     * @param lastIndex lastIndex
+     */
+    public void setLastIndex(final int lastIndex) {
+        this.lastIndex = JSType.toObject(lastIndex);
+    }
+
+    private void init() {
+        // Keep reference to global object to support "static" properties of RegExp
+        this.globalObject = Global.instance();
+        this.setProto(globalObject.getRegExpPrototype());
+    }
+
+    private static NativeRegExp checkRegExp(final Object self) {
+        Global.checkObjectCoercible(self);
+        if (self instanceof NativeRegExp) {
+            return (NativeRegExp)self;
+        } else if (self != null && self == Global.instance().getRegExpPrototype()) {
+            return Global.instance().DEFAULT_REGEXP;
+        } else {
+            throw typeError("not.a.regexp", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    private void setGlobal(final boolean global) {
+        regexp.setGlobal(global);
+    }
+
+    boolean getGlobal() {
+        return regexp.isGlobal();
+    }
+
+    private RegExp getRegExp() {
+        return regexp;
+    }
+
+    private void setRegExp(final RegExp regexp) {
+        this.regexp = regexp;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java
new file mode 100644
index 0000000..5d4f857
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java
@@ -0,0 +1,84 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Getter;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Setter;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Objects of this class are used to represent return values from
+ * RegExp.prototype.exec method.
+ */
+@ScriptClass("RegExpExecResult")
+public final class NativeRegExpExecResult extends ScriptObject {
+    /** index property */
+    @Property
+    public Object index;
+
+    /** input property */
+    @Property
+    public Object input;
+
+    NativeRegExpExecResult(final RegExpResult result) {
+        setProto(Global.instance().getArrayPrototype());
+        this.setArray(ArrayData.allocate(result.getGroups().clone()));
+        this.index = result.getIndex();
+        this.input = result.getInput();
+    }
+
+    /**
+     * Length getter
+     * @param self self reference
+     * @return length property value
+     */
+    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+    public static Object length(final Object self) {
+        if (self instanceof ScriptObject) {
+            return ((ScriptObject)self).getArray().length() & JSType.MAX_UINT;
+        }
+
+        return 0;
+    }
+
+    /**
+     * Length setter
+     * @param self self reference
+     * @param length property value
+     */
+    @Setter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+    public static void length(final Object self, final Object length) {
+        if (self instanceof ScriptObject) {
+            ((ScriptObject)self).setLength(NativeArray.validLength(length, true));
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
new file mode 100644
index 0000000..a643c19
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
@@ -0,0 +1,147 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.Arrays;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+import jdk.nashorn.internal.lookup.Lookup;
+
+/**
+ * ECMA 10.6 Arguments Object.
+ *
+ * Arguments object for strict mode functions.
+ */
+public final class NativeStrictArguments extends ScriptObject {
+
+    private static final MethodHandle G$LENGTH = findOwnMH("G$length", Object.class, Object.class);
+
+    private static final MethodHandle S$LENGTH = findOwnMH("S$length", void.class, Object.class, Object.class);
+
+    // property map for strict mode arguments object
+    private static final PropertyMap nasgenmap$;
+
+    static {
+        PropertyMap map = PropertyMap.newMap(NativeStrictArguments.class);
+        map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH);
+        // In strict mode, the caller and callee properties should throw TypeError
+        map = ScriptFunctionImpl.newThrowerProperty(map, "caller");
+        map = ScriptFunctionImpl.newThrowerProperty(map, "callee");
+        nasgenmap$ = map;
+    }
+
+    private Object   length;
+    private final Object[] namedArgs;
+
+    NativeStrictArguments(final Object[] values, final int numParams) {
+        super(nasgenmap$);
+        setIsArguments();
+
+        final ScriptFunction func = ScriptFunctionImpl.getTypeErrorThrower();
+        // We have to fill user accessor functions late as these are stored
+        // in this object rather than in the PropertyMap of this object.
+        setUserAccessors("caller", func, func);
+        setUserAccessors("callee", func, func);
+
+        setArray(ArrayData.allocate(values));
+        this.length = values.length;
+
+        // extend/truncate named arg array as needed and copy values
+        this.namedArgs = new Object[numParams];
+        if (numParams > values.length) {
+            Arrays.fill(namedArgs, UNDEFINED);
+        }
+        System.arraycopy(values, 0, namedArgs, 0, Math.min(namedArgs.length, values.length));
+
+        this.setProto(Global.objectPrototype());
+    }
+
+    @Override
+    public String getClassName() {
+        return "Arguments";
+    }
+
+    /**
+     * getArgument is used for named argument access.
+     */
+    @Override
+    public Object getArgument(final int key) {
+        return (key >=0 && key < namedArgs.length) ? namedArgs[key] : UNDEFINED;
+    }
+
+    /**
+     * setArgument is used for named argument set.
+     */
+    @Override
+    public void setArgument(final int key, final Object value) {
+        if (key >= 0 && key < namedArgs.length) {
+            namedArgs[key] = value;
+        }
+    }
+
+    /**
+     * Length getter
+     * @param self self reference
+     * @return length property value
+     */
+    public static Object G$length(final Object self) {
+        if (self instanceof NativeStrictArguments) {
+            return ((NativeStrictArguments)self).getArgumentsLength();
+        }
+        return 0;
+    }
+
+    /**
+     * Length setter
+     * @param self self reference
+     * @param value value for length property
+     */
+    public static void S$length(final Object self, final Object value) {
+        if (self instanceof NativeStrictArguments) {
+            ((NativeStrictArguments)self).setArgumentsLength(value);
+        }
+    }
+
+    private Object getArgumentsLength() {
+        return length;
+    }
+
+    private void setArgumentsLength(final Object length) {
+        this.length = length;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.publicLookup(), NativeStrictArguments.class, name, MH.type(rtype, types));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
new file mode 100644
index 0000000..b2b1cf2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
@@ -0,0 +1,1189 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Getter;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import jdk.nashorn.internal.runtime.linker.NashornGuards;
+import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
+
+
+/**
+ * ECMA 15.5 String Objects.
+ */
+@ScriptClass("String")
+public final class NativeString extends ScriptObject {
+
+    private final CharSequence value;
+
+    static final MethodHandle WRAPFILTER = findWrapFilter();
+
+    NativeString(final CharSequence value) {
+        this(value, Global.instance().getStringPrototype());
+    }
+
+    private NativeString(final CharSequence value, final ScriptObject proto) {
+        assert value instanceof String || value instanceof ConsString;
+        this.value = value;
+        this.setProto(proto);
+    }
+
+    @Override
+    public String safeToString() {
+        return "[String " + toString() + "]";
+    }
+
+    @Override
+    public String toString() {
+        return getStringValue();
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other instanceof NativeString) {
+            return getStringValue().equals(((NativeString) other).getStringValue());
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return getStringValue().hashCode();
+    }
+
+    private String getStringValue() {
+        return value instanceof String ? (String) value : value.toString();
+    }
+
+    private CharSequence getValue() {
+        return value;
+    }
+
+    @Override
+    public String getClassName() {
+        return "String";
+    }
+
+    @Override
+    public Object getLength() {
+        return value.length();
+    }
+
+    // This is to provide array-like access to string characters without creating a NativeString wrapper.
+    @Override
+    protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        final Object self = request.getReceiver();
+        final Class<?> returnType = desc.getMethodType().returnType();
+
+        if (returnType == Object.class && (self instanceof String || self instanceof ConsString)) {
+            try {
+                MethodHandle mh = MethodHandles.lookup().findStatic(NativeString.class, "get", desc.getMethodType());
+                return new GuardedInvocation(mh, NashornGuards.getInstanceOf2Guard(String.class, ConsString.class));
+            } catch (final NoSuchMethodException | IllegalAccessException e) {
+                // Shouldn't happen. Fall back to super
+            }
+        }
+        return super.findGetIndexMethod(desc, request);
+    }
+
+    @SuppressWarnings("unused")
+    private static Object get(final Object self, final Object key) {
+        final CharSequence cs = JSType.toCharSequence(self);
+        final int index = getArrayIndexNoThrow(key);
+        if (index >= 0 && index < cs.length()) {
+            return String.valueOf(cs.charAt(index));
+        }
+        return ((ScriptObject) Global.toObject(self)).get(key);
+    }
+
+    @SuppressWarnings("unused")
+    private static Object get(final Object self, final double key) {
+        if (isRepresentableAsInt(key)) {
+            return get(self, (int)key);
+        }
+        return ((ScriptObject) Global.toObject(self)).get(key);
+    }
+
+    @SuppressWarnings("unused")
+    private static Object get(final Object self, final long key) {
+        final CharSequence cs = JSType.toCharSequence(self);
+        if (key >= 0 && key < cs.length()) {
+            return String.valueOf(cs.charAt((int)key));
+        }
+        return ((ScriptObject) Global.toObject(self)).get(key);
+    }
+
+    @SuppressWarnings("unused")
+    private static Object get(final Object self, final int key) {
+        final CharSequence cs = JSType.toCharSequence(self);
+        if (key >= 0 && key < cs.length()) {
+            return String.valueOf(cs.charAt(key));
+        }
+        return ((ScriptObject) Global.toObject(self)).get(key);
+    }
+
+    // String characters can be accessed with array-like indexing..
+    @Override
+    public Object get(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+        if (index >= 0 && index < value.length()) {
+            return String.valueOf(value.charAt(index));
+        }
+        return super.get(key);
+    }
+
+    @Override
+    public Object get(final double key) {
+        if (isRepresentableAsInt(key)) {
+            return get((int)key);
+        }
+        return super.get(key);
+    }
+
+    @Override
+    public Object get(final long key) {
+        if (key >= 0 && key < value.length()) {
+            return String.valueOf(value.charAt((int)key));
+        }
+        return super.get(key);
+    }
+
+    @Override
+    public Object get(final int key) {
+        if (key >= 0 && key < value.length()) {
+            return String.valueOf(value.charAt(key));
+        }
+        return super.get(key);
+    }
+
+    @Override
+    public int getInt(final Object key) {
+        return JSType.toInt32(get(key));
+    }
+
+    @Override
+    public int getInt(final double key) {
+        return JSType.toInt32(get(key));
+    }
+
+    @Override
+    public int getInt(final long key) {
+        return JSType.toInt32(get(key));
+    }
+
+    @Override
+    public int getInt(final int key) {
+        return JSType.toInt32(get(key));
+    }
+
+    @Override
+    public long getLong(final Object key) {
+        return JSType.toUint32(get(key));
+    }
+
+    @Override
+    public long getLong(final double key) {
+        return JSType.toUint32(get(key));
+    }
+
+    @Override
+    public long getLong(final long key) {
+        return JSType.toUint32(get(key));
+    }
+
+    @Override
+    public long getLong(final int key) {
+        return JSType.toUint32(get(key));
+    }
+
+    @Override
+    public double getDouble(final Object key) {
+        return JSType.toNumber(get(key));
+    }
+
+    @Override
+    public double getDouble(final double key) {
+        return JSType.toNumber(get(key));
+    }
+
+    @Override
+    public double getDouble(final long key) {
+        return JSType.toNumber(get(key));
+    }
+
+    @Override
+    public double getDouble(final int key) {
+        return JSType.toNumber(get(key));
+    }
+
+    @Override
+    public boolean has(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isValid(index) || super.has(key);
+    }
+
+    @Override
+    public boolean has(final int key) {
+        return isValid(key) || super.has(key);
+    }
+
+    @Override
+    public boolean has(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isValid(index) || super.has(key);
+    }
+
+    @Override
+    public boolean has(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isValid(index) || super.has(key);
+    }
+
+    @Override
+    public boolean hasOwnProperty(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isValid(index) || super.hasOwnProperty(key);
+    }
+
+    @Override
+    public boolean hasOwnProperty(final int key) {
+        return isValid(key) || super.hasOwnProperty(key);
+    }
+
+    @Override
+    public boolean hasOwnProperty(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isValid(index) || super.hasOwnProperty(key);
+    }
+
+    @Override
+    public boolean hasOwnProperty(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+        return isValid(index) || super.hasOwnProperty(key);
+    }
+
+    @Override
+    public boolean delete(final int key, final boolean strict) {
+        return checkDeleteIndex(key, strict)? false : super.delete(key, strict);
+    }
+
+    @Override
+    public boolean delete(final long key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
+    }
+
+    @Override
+    public boolean delete(final double key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
+    }
+
+    @Override
+    public boolean delete(final Object key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
+    }
+
+    private boolean checkDeleteIndex(final int index, final boolean strict) {
+        if (isValid(index)) {
+            if (strict) {
+                throw typeError("cant.delete.property", Integer.toString(index), ScriptRuntime.safeToString(this));
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public Object getOwnPropertyDescriptor(final String key) {
+        final int index = ArrayIndex.getArrayIndexNoThrow(key);
+        if (index >= 0 && index < value.length()) {
+            final Global global = Global.instance();
+            return global.newDataDescriptor(String.valueOf(value.charAt(index)), false, true, false);
+        }
+
+        return super.getOwnPropertyDescriptor(key);
+    }
+
+    /**
+     * return a List of own keys associated with the object.
+     * @param all True if to include non-enumerable keys.
+     * @return Array of keys.
+     */
+    @Override
+    public String[] getOwnKeys(final boolean all) {
+        final List<Object> keys = new ArrayList<>();
+
+        // add string index keys
+        for (int i = 0; i < value.length(); i++) {
+            keys.add(JSType.toString(i));
+        }
+
+        // add super class properties
+        keys.addAll(Arrays.asList(super.getOwnKeys(all)));
+        return keys.toArray(new String[keys.size()]);
+    }
+
+    /**
+     * ECMA 15.5.3 String.length
+     * @param self self reference
+     * @return     value of length property for string
+     */
+    @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+    public static Object length(final Object self) {
+        return getCharSequence(self).length();
+    }
+
+    /**
+     * ECMA 15.5.3.2 String.fromCharCode ( [ char0 [ , char1 [ , ... ] ] ] )
+     * @param self  self reference
+     * @param args  array of arguments to be interpreted as char
+     * @return string with arguments translated to charcodes
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1, where = Where.CONSTRUCTOR)
+    public static Object fromCharCode(final Object self, final Object... args) {
+        final char[] buf = new char[args.length];
+        int index = 0;
+        for (final Object arg : args) {
+            buf[index++] = (char)JSType.toUint16(arg);
+        }
+        return new String(buf);
+    }
+
+    /**
+     * ECMA 15.5.3.2 - specialization for one char
+     * @param self  self reference
+     * @param value one argument to be interpreted as char
+     * @return string with one charcode
+     */
+    @SpecializedFunction
+    public static Object fromCharCode(final Object self, final Object value) {
+        try {
+            return "" + (char)JSType.toUint16(((Number)value).doubleValue());
+        } catch (final ClassCastException e) {
+            return fromCharCode(self, new Object[] { value });
+        }
+    }
+
+    /**
+     * ECMA 15.5.3.2 - specialization for one char of int type
+     * @param self  self reference
+     * @param value one argument to be interpreted as char
+     * @return string with one charcode
+     */
+    @SpecializedFunction
+    public static Object fromCharCode(final Object self, final int value) {
+        return "" + (char)(value & 0xffff);
+    }
+
+    /**
+     * ECMA 15.5.3.2 - specialization for one char of long type
+     * @param self  self reference
+     * @param value one argument to be interpreted as char
+     * @return string with one charcode
+     */
+    @SpecializedFunction
+    public static Object fromCharCode(final Object self, final long value) {
+        return "" + (char)((int)value & 0xffff);
+    }
+
+    /**
+     * ECMA 15.5.3.2 - specialization for one char of double type
+     * @param self  self reference
+     * @param value one argument to be interpreted as char
+     * @return string with one charcode
+     */
+    @SpecializedFunction
+    public static Object fromCharCode(final Object self, final double value) {
+        return "" + (char)JSType.toUint16(value);
+    }
+
+    /**
+     * ECMA 15.5.4.2 String.prototype.toString ( )
+     * @param self self reference
+     * @return self as string
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toString(final Object self) {
+        return getString(self);
+    }
+
+    /**
+     * ECMA 15.5.4.3 String.prototype.valueOf ( )
+     * @param self self reference
+     * @return self as string
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object valueOf(final Object self) {
+        return getString(self);
+    }
+
+    /**
+     * ECMA 15.5.4.4 String.prototype.charAt (pos)
+     * @param self self reference
+     * @param pos  position in string
+     * @return string representing the char at the given position
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object charAt(final Object self, final Object pos) {
+        return charAt(self, JSType.toInteger(pos));
+    }
+
+    /**
+     * ECMA 15.5.4.4 String.prototype.charAt (pos) - specialized version for double position
+     * @param self self reference
+     * @param pos  position in string
+     * @return string representing the char at the given position
+     */
+    @SpecializedFunction
+    public static String charAt(final Object self, final double pos) {
+        return charAt(self, (int)pos);
+    }
+
+    /**
+     * ECMA 15.5.4.4 String.prototype.charAt (pos) - specialized version for int position
+     * @param self self reference
+     * @param pos  position in string
+     * @return string representing the char at the given position
+     */
+    @SpecializedFunction
+    public static String charAt(final Object self, final int pos) {
+        final String str = checkObjectToString(self);
+        return (pos < 0 || pos >= str.length()) ? "" : String.valueOf(str.charAt(pos));
+    }
+
+    /**
+     * ECMA 15.5.4.5 String.prototype.charCodeAt (pos)
+     * @param self self reference
+     * @param pos  position in string
+     * @return number representing charcode at position
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object charCodeAt(final Object self, final Object pos) {
+        return charCodeAt(self, JSType.toInteger(pos));
+    }
+
+    /**
+     * ECMA 15.5.4.5 String.prototype.charCodeAt (pos) - specialized version for double position
+     * @param self self reference
+     * @param pos  position in string
+     * @return number representing charcode at position
+     */
+    @SpecializedFunction
+    public static double charCodeAt(final Object self, final double pos) {
+        return charCodeAt(self, (int) pos);
+    }
+
+    /**
+     * ECMA 15.5.4.5 String.prototype.charCodeAt (pos) - specialized version for int position
+     * @param self self reference
+     * @param pos  position in string
+     * @return number representing charcode at position
+     */
+    @SpecializedFunction
+    public static double charCodeAt(final Object self, final int pos) {
+        final String str = checkObjectToString(self);
+        return (pos < 0 || pos >= str.length()) ? Double.NaN :  str.charAt(pos);
+    }
+
+    /**
+     * ECMA 15.5.4.6 String.prototype.concat ( [ string1 [ , string2 [ , ... ] ] ] )
+     * @param self self reference
+     * @param args list of string to concatenate
+     * @return concatenated string
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object concat(final Object self, final Object... args) {
+        CharSequence cs = checkObjectToString(self);
+        if (args != null) {
+            for (final Object obj : args) {
+                cs = new ConsString(cs, JSType.toCharSequence(obj));
+            }
+        }
+        return cs;
+    }
+
+    /**
+     * ECMA 15.5.4.7 String.prototype.indexOf (searchString, position)
+     * @param self   self reference
+     * @param search string to search for
+     * @param pos    position to start search
+     * @return position of first match or -1
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object indexOf(final Object self, final Object search, final Object pos) {
+        final String str = checkObjectToString(self);
+        return str.indexOf(JSType.toString(search), JSType.toInteger(pos));
+    }
+
+    /**
+     * ECMA 15.5.4.7 String.prototype.indexOf (searchString, position) specialized for no position parameter
+     * @param self   self reference
+     * @param search string to search for
+     * @return position of first match or -1
+     */
+    @SpecializedFunction
+    public static int indexOf(final Object self, final Object search) {
+        return indexOf(self, search, 0);
+    }
+
+    /**
+     * ECMA 15.5.4.7 String.prototype.indexOf (searchString, position) specialized for double position parameter
+     * @param self   self reference
+     * @param search string to search for
+     * @param pos    position to start search
+     * @return position of first match or -1
+     */
+    @SpecializedFunction
+    public static int indexOf(final Object self, final Object search, final double pos) {
+        return indexOf(self, search, (int) pos);
+    }
+
+    /**
+     * ECMA 15.5.4.7 String.prototype.indexOf (searchString, position) specialized for int position parameter
+     * @param self   self reference
+     * @param search string to search for
+     * @param pos    position to start search
+     * @return position of first match or -1
+     */
+    @SpecializedFunction
+    public static int indexOf(final Object self, final Object search, final int pos) {
+        return checkObjectToString(self).indexOf(JSType.toString(search), pos);
+    }
+
+    /**
+     * ECMA 15.5.4.8 String.prototype.lastIndexOf (searchString, position)
+     * @param self   self reference
+     * @param search string to search for
+     * @param pos    position to start search
+     * @return last position of match or -1
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static Object lastIndexOf(final Object self, final Object search, final Object pos) {
+
+        final String str       = checkObjectToString(self);
+        final String searchStr = JSType.toString(search);
+
+        int from;
+
+        if (pos == UNDEFINED) {
+            from = str.length();
+        } else {
+            final double numPos = JSType.toNumber(pos);
+            from = !Double.isNaN(numPos) ? (int)numPos : (int)Double.POSITIVE_INFINITY;
+        }
+
+        return str.lastIndexOf(searchStr, from);
+    }
+
+    /**
+     * ECMA 15.5.4.9 String.prototype.localeCompare (that)
+     * @param self self reference
+     * @param that comparison object
+     * @return result of locale sensitive comparison operation between {@code self} and {@code that}
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object localeCompare(final Object self, final Object that) {
+
+        final String   str      = checkObjectToString(self);
+        final Collator collator = Collator.getInstance(Global.getEnv()._locale);
+
+        collator.setStrength(Collator.IDENTICAL);
+        collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+
+        return (double)collator.compare(str, JSType.toString(that));
+    }
+
+    /**
+     * ECMA 15.5.4.10 String.prototype.match (regexp)
+     * @param self   self reference
+     * @param regexp regexp expression
+     * @return array of regexp matches
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object match(final Object self, final Object regexp) {
+
+        final String str = checkObjectToString(self);
+
+        NativeRegExp nativeRegExp;
+        if (regexp == UNDEFINED) {
+            nativeRegExp = new NativeRegExp("");
+        } else {
+            nativeRegExp = Global.toRegExp(regexp);
+        }
+
+        if (!nativeRegExp.getGlobal()) {
+            return nativeRegExp.exec(str);
+        }
+
+        nativeRegExp.setLastIndex(0);
+
+        int previousLastIndex = 0;
+        final List<Object> matches = new ArrayList<>();
+
+        Object result;
+        while ((result = nativeRegExp.exec(str)) != null) {
+            final int thisIndex = nativeRegExp.getLastIndex();
+            if (thisIndex == previousLastIndex) {
+                nativeRegExp.setLastIndex(thisIndex + 1);
+                previousLastIndex = thisIndex + 1;
+            } else {
+                previousLastIndex = thisIndex;
+            }
+            matches.add(((ScriptObject)result).get(0));
+        }
+
+        if (matches.isEmpty()) {
+            return null;
+        }
+
+        return new NativeArray(matches.toArray());
+    }
+
+    /**
+     * ECMA 15.5.4.11 String.prototype.replace (searchValue, replaceValue)
+     * @param self        self reference
+     * @param string      item to replace
+     * @param replacement item to replace it with
+     * @return string after replacement
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object replace(final Object self, final Object string, final Object replacement) {
+
+        final String str = checkObjectToString(self);
+
+        final NativeRegExp nativeRegExp;
+        if (string instanceof NativeRegExp) {
+            nativeRegExp = (NativeRegExp) string;
+        } else {
+            nativeRegExp = NativeRegExp.flatRegExp(JSType.toString(string));
+        }
+
+        if (replacement instanceof ScriptFunction) {
+            return nativeRegExp.replace(str, "", (ScriptFunction)replacement);
+        }
+
+        return nativeRegExp.replace(str, JSType.toString(replacement), null);
+    }
+
+    /**
+     * ECMA 15.5.4.12 String.prototype.search (regexp)
+     *
+     * @param self    self reference
+     * @param string  string to search for
+     * @return offset where match occurred
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object search(final Object self, final Object string) {
+
+        final String       str          = checkObjectToString(self);
+        final NativeRegExp nativeRegExp = Global.toRegExp(string == UNDEFINED ? "" : string);
+
+        return nativeRegExp.search(str);
+    }
+
+    /**
+     * ECMA 15.5.4.13 String.prototype.slice (start, end)
+     *
+     * @param self  self reference
+     * @param start start position for slice
+     * @param end   end position for slice
+     * @return sliced out substring
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object slice(final Object self, final Object start, final Object end) {
+
+        final String str      = checkObjectToString(self);
+        if (end == UNDEFINED) {
+            return slice(str, JSType.toInteger(start));
+        }
+        return slice(str, JSType.toInteger(start), JSType.toInteger(end));
+    }
+
+    /**
+     * ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for single int parameter
+     *
+     * @param self  self reference
+     * @param start start position for slice
+     * @return sliced out substring
+     */
+    @SpecializedFunction
+    public static Object slice(final Object self, final int start) {
+        final String str = checkObjectToString(self);
+        final int from = (start < 0) ? Math.max(str.length() + start, 0) : Math.min(start, str.length());
+
+        return str.substring(from);
+    }
+
+    /**
+     * ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for single double parameter
+     *
+     * @param self  self reference
+     * @param start start position for slice
+     * @return sliced out substring
+     */
+    @SpecializedFunction
+    public static Object slice(final Object self, final double start) {
+        return slice(self, (int)start);
+    }
+
+    /**
+     * ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for two int parameters
+     *
+     * @param self  self reference
+     * @param start start position for slice
+     * @param end   end position for slice
+     * @return sliced out substring
+     */
+    @SpecializedFunction
+    public static Object slice(final Object self, final int start, final int end) {
+
+        final String str = checkObjectToString(self);
+        final int len    = str.length();
+
+        final int from = (start < 0) ? Math.max(len + start, 0) : Math.min(start, len);
+        final int to   = (end < 0)   ? Math.max(len + end, 0)   : Math.min(end, len);
+
+        return str.substring(Math.min(from, to), to);
+    }
+
+    /**
+     * ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for two double parameters
+     *
+     * @param self  self reference
+     * @param start start position for slice
+     * @param end   end position for slice
+     * @return sliced out substring
+     */
+    @SpecializedFunction
+    public static Object slice(final Object self, final double start, final double end) {
+        return slice(self, (int)start, (int)end);
+    }
+
+    /**
+     * ECMA 15.5.4.14 String.prototype.split (separator, limit)
+     *
+     * @param self      self reference
+     * @param separator separator for split
+     * @param limit     limit for splits
+     * @return array object in which splits have been placed
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object split(final Object self, final Object separator, final Object limit) {
+
+        final String str = checkObjectToString(self);
+
+        if (separator == UNDEFINED) {
+            return new NativeArray(new Object[]{str});
+        }
+
+        final long lim = (limit == UNDEFINED) ? JSType.MAX_UINT : JSType.toUint32(limit);
+
+        if (separator instanceof NativeRegExp) {
+            return ((NativeRegExp) separator).split(str, lim);
+        }
+
+        // when separator is a string, it is treated as a literal search string to be used for splitting.
+        return splitString(str, JSType.toString(separator), lim);
+    }
+
+    private static Object splitString(String str, String separator, long limit) {
+        if (separator.isEmpty()) {
+            final Object[] array = new Object[str.length()];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = String.valueOf(str.charAt(i));
+            }
+            return new NativeArray(array);
+        }
+
+        final List<String> elements = new LinkedList<>();
+        final int strLength = str.length();
+        final int sepLength = separator.length();
+        int pos = 0;
+        int n = 0;
+
+        while (pos < strLength && n < limit) {
+            int found = str.indexOf(separator, pos);
+            if (found == -1) {
+                break;
+            }
+            elements.add(str.substring(pos, found));
+            n++;
+            pos = found + sepLength;
+        }
+        if (pos <= strLength && n < limit) {
+            elements.add(str.substring(pos));
+        }
+
+        return new NativeArray(elements.toArray());
+    }
+
+    /**
+     * ECMA B.2.3 String.prototype.substr (start, length)
+     *
+     * @param self   self reference
+     * @param start  start position
+     * @param length length of section
+     * @return substring given start and length of section
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object substr(final Object self, final Object start, final Object length) {
+        final String str       = JSType.toString(self);
+        final int    strLength = str.length();
+
+        int intStart = JSType.toInteger(start);
+        if (intStart < 0) {
+            intStart = Math.max(intStart + strLength, 0);
+        }
+
+        final int intLen = Math.min(Math.max((length == UNDEFINED) ? Integer.MAX_VALUE : JSType.toInteger(length), 0), strLength - intStart);
+
+        return intLen <= 0 ? "" : str.substring(intStart, intStart + intLen);
+    }
+
+    /**
+     * ECMA 15.5.4.15 String.prototype.substring (start, end)
+     *
+     * @param self  self reference
+     * @param start start position of substring
+     * @param end   end position of substring
+     * @return substring given start and end indexes
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object substring(final Object self, final Object start, final Object end) {
+
+        final String str = checkObjectToString(self);
+        if (end == UNDEFINED) {
+            return substring(str, JSType.toInteger(start));
+        }
+        return substring(str, JSType.toInteger(start), JSType.toInteger(end));
+    }
+
+    /**
+     * ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for int start parameter
+     *
+     * @param self  self reference
+     * @param start start position of substring
+     * @return substring given start and end indexes
+     */
+    @SpecializedFunction
+    public static String substring(final Object self, final int start) {
+        final String str = checkObjectToString(self);
+        if (start < 0) {
+            return str;
+        } else if (start >= str.length()) {
+            return "";
+        } else {
+            return str.substring(start);
+        }
+    }
+
+    /**
+     * ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for double start parameter
+     *
+     * @param self  self reference
+     * @param start start position of substring
+     * @return substring given start and end indexes
+     */
+    @SpecializedFunction
+    public static String substring(final Object self, final double start) {
+        return substring(self, (int)start);
+    }
+
+    /**
+     * ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for int start and end parameters
+     *
+     * @param self  self reference
+     * @param start start position of substring
+     * @param end   end position of substring
+     * @return substring given start and end indexes
+     */
+    @SpecializedFunction
+    public static String substring(final Object self, final int start, final int end) {
+        final String str = checkObjectToString(self);
+        final int len = str.length();
+        final int validStart = start < 0 ? 0 : (start > len ? len : start);
+        final int validEnd   = end < 0 ? 0 : (end > len ? len : end);
+
+        if (validStart < validEnd) {
+            return str.substring(validStart, validEnd);
+        }
+        return str.substring(validEnd, validStart);
+    }
+
+    /**
+     * ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for double start and end parameters
+     *
+     * @param self  self reference
+     * @param start start position of substring
+     * @param end   end position of substring
+     * @return substring given start and end indexes
+     */
+    @SpecializedFunction
+    public static String substring(final Object self, final double start, final double end) {
+        return substring(self, (int)start, (int)end);
+    }
+
+    /**
+     * ECMA 15.5.4.16 String.prototype.toLowerCase ( )
+     * @param self self reference
+     * @return string to lower case
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toLowerCase(final Object self) {
+        return checkObjectToString(self).toLowerCase();
+    }
+
+    /**
+     * ECMA 15.5.4.17 String.prototype.toLocaleLowerCase ( )
+     * @param self self reference
+     * @return string to locale sensitive lower case
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toLocaleLowerCase(final Object self) {
+        return checkObjectToString(self).toLowerCase(Global.getEnv()._locale);
+    }
+
+    /**
+     * ECMA 15.5.4.18 String.prototype.toUpperCase ( )
+     * @param self self reference
+     * @return string to upper case
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toUpperCase(final Object self) {
+        return checkObjectToString(self).toUpperCase();
+    }
+
+    /**
+     * ECMA 15.5.4.19 String.prototype.toLocaleUpperCase ( )
+     * @param self self reference
+     * @return string to locale sensitive upper case
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object toLocaleUpperCase(final Object self) {
+        return checkObjectToString(self).toUpperCase(Global.getEnv()._locale);
+    }
+
+    /**
+     * ECMA 15.5.4.20 String.prototype.trim ( )
+     * @param self self reference
+     * @return string trimmed from whitespace
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object trim(final Object self) {
+
+        final String str = checkObjectToString(self);
+        final int len = str.length();
+        int start = 0;
+        int end   = len - 1;
+
+        while (start <= end && ScriptRuntime.isJSWhitespace(str.charAt(start))) {
+            start++;
+        }
+        while (end > start && ScriptRuntime.isJSWhitespace(str.charAt(end))) {
+            end--;
+        }
+
+        return start == 0 && end + 1 == len ? str : str.substring(start, end + 1);
+    }
+
+    private static Object newObj(final Object self, final CharSequence str) {
+        if (self instanceof ScriptObject) {
+            return new NativeString(str, ((ScriptObject)self).getProto());
+        }
+        return new NativeString(str, Global.instance().getStringPrototype());
+    }
+
+    /**
+     * ECMA 15.5.2.1 new String ( [ value ] )
+     *
+     * Constructor
+     *
+     * @param newObj is this constructor invoked with the new operator
+     * @param self   self reference
+     * @param args   arguments (a value)
+     *
+     * @return new NativeString, empty string if no args, extraneous args ignored
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        final CharSequence str = (args.length > 0) ? JSType.toCharSequence(args[0]) : "";
+        return newObj ? newObj(self, str) : str.toString();
+    }
+
+    /**
+     * ECMA 15.5.2.1 new String ( [ value ] ) - special version with no args
+     *
+     * Constructor
+     *
+     * @param newObj is this constructor invoked with the new operator
+     * @param self   self reference
+     *
+     * @return new NativeString ("")
+     */
+    @SpecializedConstructor
+    public static Object constructor(final boolean newObj, final Object self) {
+        return newObj ? newObj(self, "") : "";
+    }
+
+    /**
+     * ECMA 15.5.2.1 new String ( [ value ] ) - special version with one arg
+     *
+     * Constructor
+     *
+     * @param newObj is this constructor invoked with the new operator
+     * @param self   self reference
+     * @param arg    argument
+     *
+     * @return new NativeString (arg)
+     */
+    @SpecializedConstructor
+    public static Object constructor(final boolean newObj, final Object self, final Object arg) {
+        final CharSequence str = JSType.toCharSequence(arg);
+        return newObj ? newObj(self, str) : str.toString();
+    }
+
+    /**
+     * ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code int} arg
+     *
+     * Constructor
+     *
+     * @param newObj is this constructor invoked with the new operator
+     * @param self   self reference
+     * @param arg    the arg
+     *
+     * @return new NativeString containing the string representation of the arg
+     */
+    @SpecializedConstructor
+    public static Object constructor(final boolean newObj, final Object self, final int arg) {
+        final String str = JSType.toString(arg);
+        return newObj ? newObj(self, str) : str;
+    }
+
+    /**
+     * Lookup the appropriate method for an invoke dynamic call.
+     *
+     * @param request  the link request
+     * @param receiver receiver of call
+     * @return Link to be invoked at call site.
+     */
+    public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
+        final MethodHandle guard = NashornGuards.getInstanceOf2Guard(String.class, ConsString.class);
+        return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER);
+    }
+
+    @SuppressWarnings("unused")
+    private static NativeString wrapFilter(final Object receiver) {
+        return new NativeString((CharSequence)receiver);
+    }
+
+    private static CharSequence getCharSequence(final Object self) {
+        if (self instanceof String || self instanceof ConsString) {
+            return (CharSequence)self;
+        } else if (self instanceof NativeString) {
+            return ((NativeString)self).getValue();
+        } else if (self != null && self == Global.instance().getStringPrototype()) {
+            return "";
+        } else {
+            throw typeError("not.a.string", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    private static String getString(final Object self) {
+        if (self instanceof String) {
+            return (String)self;
+        } else if (self instanceof ConsString) {
+            return self.toString();
+        } else if (self instanceof NativeString) {
+            return ((NativeString)self).getStringValue();
+        } else if (self != null && self == Global.instance().getStringPrototype()) {
+            return "";
+        } else {
+            throw typeError( "not.a.string", ScriptRuntime.safeToString(self));
+        }
+    }
+
+    /**
+     * Combines ECMA 9.10 CheckObjectCoercible and ECMA 9.8 ToString with a shortcut for strings.
+     *
+     * @param self the object
+     * @return the object as string
+     */
+    private static String checkObjectToString(final Object self) {
+        if (self instanceof String) {
+            return (String)self;
+        } else if (self instanceof ConsString) {
+            return self.toString();
+        } else {
+            Global.checkObjectCoercible(self);
+            return JSType.toString(self);
+        }
+    }
+
+    private boolean isValid(final int key) {
+        return key >= 0 && key < value.length();
+    }
+
+    private static MethodHandle findWrapFilter() {
+        try {
+            return MethodHandles.lookup().findStatic(NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
+        } catch (final NoSuchMethodException | IllegalAccessException e) {
+            throw new MethodHandleFactory.LookupException(e);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java
new file mode 100644
index 0000000..db54c48
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java
@@ -0,0 +1,88 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * ECMA 15.11.6.4 SyntaxError
+ *
+ */
+@ScriptClass("Error")
+public final class NativeSyntaxError extends ScriptObject {
+
+    /** message property in instance */
+    @Property(name = NativeError.MESSAGE)
+    public Object instMessage;
+
+    /** error name property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object name;
+
+    /** ECMA 15.1.1.1 message property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object message;
+
+    NativeSyntaxError(final Object msg) {
+        this.setProto(Global.instance().getSyntaxErrorPrototype());
+        if (msg != UNDEFINED) {
+            this.instMessage = JSType.toString(msg);
+        } else {
+            this.delete(NativeError.MESSAGE, Global.isStrict());
+        }
+    }
+
+    @Override
+    public String getClassName() {
+        return "Error";
+    }
+
+    /**
+     * ECMA 15.11.6.4 SyntaxError
+     *
+     * Constructor
+     *
+     * @param newObj was this error instantiated with the new operator
+     * @param self   self reference
+     * @param msg    error message
+     *
+     * @return new SyntaxError
+     */
+    @Constructor(name = "SyntaxError")
+    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+        return new NativeSyntaxError(msg);
+    }
+}
+
+
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java
new file mode 100644
index 0000000..5e87fbb
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java
@@ -0,0 +1,86 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * ECMA 15.11.6.5 TypeError
+ *
+ */
+@ScriptClass("Error")
+public final class NativeTypeError extends ScriptObject {
+
+    /** message property in instance */
+    @Property(name = NativeError.MESSAGE)
+    public Object instMessage;
+
+    /** error name property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object name;
+
+    /** ECMA 15.1.1.1 message property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object message;
+
+    NativeTypeError(final Object msg) {
+        this.setProto(Global.instance().getTypeErrorPrototype());
+        if (msg != UNDEFINED) {
+            this.instMessage = JSType.toString(msg);
+        } else {
+            delete(NativeError.MESSAGE, Global.isStrict());
+        }
+    }
+
+    @Override
+    public String getClassName() {
+        return "Error";
+    }
+
+    /**
+     * ECMA 15.11.6.5 TypeError
+     *
+     * Constructor
+     *
+     * @param newObj was this error instantiated with the new operator
+     * @param self   self reference
+     * @param msg    error message
+     *
+     * @return new TypeError
+     */
+    @Constructor(name = "TypeError")
+    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+        return new NativeTypeError(msg);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java
new file mode 100644
index 0000000..958c14a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java
@@ -0,0 +1,85 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * ECMA 15.11.6.6 URIError
+ */
+@ScriptClass("Error")
+public final class NativeURIError extends ScriptObject {
+
+    /** message property in instance */
+    @Property(name = NativeError.MESSAGE)
+    public Object instMessage;
+
+    /** error name property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object name;
+
+    /** ECMA 15.1.1.1 message property */
+    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
+    public Object message;
+
+    NativeURIError(final Object msg) {
+        this.setProto(Global.instance().getURIErrorPrototype());
+        if (msg != UNDEFINED) {
+            this.instMessage = JSType.toString(msg);
+        } else {
+            this.delete(NativeError.MESSAGE, Global.isStrict());
+        }
+    }
+
+    @Override
+    public String getClassName() {
+        return "Error";
+    }
+
+    /**
+     * ECMA 15.11.6.6 URIError
+     *
+     * Constructor
+     *
+     * @param newObj was this error instantiated with the new operator
+     * @param self   self reference
+     * @param msg    error message
+     *
+     * @return new URIError
+     */
+    @Constructor(name = "URIError")
+    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+        return new NativeURIError(msg);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
new file mode 100644
index 0000000..740bb39
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
@@ -0,0 +1,144 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Uint16 array for TypedArray extension
+ */
+@ScriptClass("Uint16Array")
+public final class NativeUint16Array extends ArrayBufferView {
+    private static final int BYTES_PER_ELEMENT = 2;
+    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
+        @Override
+        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new NativeUint16Array(buffer, byteOffset, length);
+        }
+        @Override
+        public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new Uint16ArrayData(buffer, byteOffset, length);
+        }
+    };
+
+    private static final class Uint16ArrayData extends ArrayDataImpl {
+        private Uint16ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+            super(buffer, byteOffset, elementLength);
+        }
+
+        @Override
+        protected int byteIndex(final int index) {
+            return index * BYTES_PER_ELEMENT + byteOffset;
+        }
+
+        @Override
+        protected int getIntImpl(final int index) {
+            final int byteIndex = byteIndex(index);
+            final byte[] byteArray = buffer.getByteArray();
+            return byteArray[byteIndex  ]       & 0x0000_00ff |
+                   byteArray[byteIndex+1] <<  8 & 0x0000_ff00 ;
+        }
+
+        @Override
+        protected void setImpl(final int index, final int value) {
+            final int byteIndex = byteIndex(index);
+            @SuppressWarnings("MismatchedReadAndWriteOfArray")
+            final byte[] byteArray = buffer.getByteArray();
+            byteArray[byteIndex  ] = (byte)(value       & 0xff);
+            byteArray[byteIndex+1] = (byte)(value >>> 8 & 0xff);
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param newObj is this typed array instantiated with the new operator
+     * @param self   self reference
+     * @param args   args
+     *
+     * @return new typed array
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        return constructorImpl(args, FACTORY);
+    }
+
+    NativeUint16Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+        super(buffer, byteOffset, length);
+    }
+
+    @Override
+    protected Factory factory() {
+        return FACTORY;
+    }
+
+    /**
+     * Set values
+     * @param self   self reference
+     * @param array  multiple values of array's type to set
+     * @param offset optional start index, interpreted  0 if undefined
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object set(final Object self, final Object array, final Object offset) {
+        return ArrayBufferView.setImpl(self, array, offset);
+    }
+
+    /**
+     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
+     * referencing the elements at begin, inclusive, up to end, exclusive. If either
+     * begin or end is negative, it refers to an index from the end of the array,
+     * as opposed to from the beginning.
+     * <p>
+     * If end is unspecified, the subarray contains all elements from begin to the end
+     * of the TypedArray. The range specified by the begin and end values is clamped to
+     * the valid index range for the current array. If the computed length of the new
+     * TypedArray would be negative, it is clamped to zero.
+     * <p>
+     * The returned TypedArray will be of the same type as the array on which this
+     * method is invoked.
+     *
+     * @param self self reference
+     * @param begin begin position
+     * @param end end position
+     *
+     * @return sub array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object subarray(final Object self, final Object begin, final Object end) {
+        return ArrayBufferView.subarrayImpl(self, begin, end);
+    }
+
+    @Override
+    protected ScriptObject getPrototype() {
+        return Global.instance().getUint16ArrayPrototype();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
new file mode 100644
index 0000000..7ad8a93
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
@@ -0,0 +1,162 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Uint32 array for TypedArray extension
+ */
+@ScriptClass("Uint32Array")
+public final class NativeUint32Array extends ArrayBufferView {
+    private static final int BYTES_PER_ELEMENT = 4;
+    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
+        @Override
+        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteBegin, final int length) {
+            return new NativeUint32Array(buffer, byteBegin, length);
+        }
+        @Override
+        public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new Uint32ArrayData(buffer, byteOffset, length);
+        }
+    };
+
+    private static final class Uint32ArrayData extends ArrayDataImpl {
+        private Uint32ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+            super(buffer, byteOffset, elementLength);
+        }
+
+        @Override
+        protected int byteIndex(final int index) {
+            return index * BYTES_PER_ELEMENT + byteOffset;
+        }
+
+        @Override
+        protected int getIntImpl(final int index) {
+            final int byteIndex = byteIndex(index);
+            final byte[] byteArray = buffer.getByteArray();
+            return byteArray[byteIndex  ]       & 0x0000_00ff |
+                   byteArray[byteIndex+1] <<  8 & 0x0000_ff00 |
+                   byteArray[byteIndex+2] << 16 & 0x00ff_0000 |
+                   byteArray[byteIndex+3] << 24 & 0xff00_0000 ;
+        }
+
+        @Override
+        protected long getLongImpl(final int key) {
+            return getIntImpl(key) & 0xffff_ffffL;
+        }
+
+        @Override
+        protected double getDoubleImpl(final int key) {
+            return getIntImpl(key) & 0xffff_ffffL;
+        }
+
+        @Override
+        protected Object getObjectImpl(final int key) {
+            return getIntImpl(key) & 0xffff_ffffL;
+        }
+
+        @Override
+        protected void setImpl(final int index, final int value) {
+            final int byteIndex = byteIndex(index);
+            final byte[] byteArray = buffer.getByteArray();
+            byteArray[byteIndex  ] = (byte)(value        & 0xff);
+            byteArray[byteIndex+1] = (byte)(value >>>  8 & 0xff);
+            byteArray[byteIndex+2] = (byte)(value >>> 16 & 0xff);
+            byteArray[byteIndex+3] = (byte)(value >>> 24 & 0xff);
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param newObj is this typed array instantiated with the new operator
+     * @param self   self reference
+     * @param args   args
+     *
+     * @return new typed array
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        return constructorImpl(args, FACTORY);
+    }
+
+    NativeUint32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+        super(buffer, byteOffset, length);
+    }
+
+    @Override
+    protected Factory factory() {
+        return FACTORY;
+    }
+
+    /**
+     * Set values
+     * @param self   self reference
+     * @param array  multiple values of array's type to set
+     * @param offset optional start index, interpreted  0 if undefined
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object set(final Object self, final Object array, final Object offset) {
+        return ArrayBufferView.setImpl(self, array, offset);
+    }
+
+    /**
+     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
+     * referencing the elements at begin, inclusive, up to end, exclusive. If either
+     * begin or end is negative, it refers to an index from the end of the array,
+     * as opposed to from the beginning.
+     * <p>
+     * If end is unspecified, the subarray contains all elements from begin to the end
+     * of the TypedArray. The range specified by the begin and end values is clamped to
+     * the valid index range for the current array. If the computed length of the new
+     * TypedArray would be negative, it is clamped to zero.
+     * <p>
+     * The returned TypedArray will be of the same type as the array on which this
+     * method is invoked.
+     *
+     * @param self self reference
+     * @param begin begin position
+     * @param end end position
+     *
+     * @return sub array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object subarray(final Object self, final Object begin, final Object end) {
+        return ArrayBufferView.subarrayImpl(self, begin, end);
+    }
+
+    @Override
+    protected ScriptObject getPrototype() {
+        return Global.instance().getUint32ArrayPrototype();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
new file mode 100644
index 0000000..7d506c1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
@@ -0,0 +1,137 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Uint8 array for TypedArray extension
+ */
+@ScriptClass("Uint8Array")
+public final class NativeUint8Array extends ArrayBufferView {
+    private static final int BYTES_PER_ELEMENT = 1;
+    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
+        @Override
+        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new NativeUint8Array(buffer, byteOffset, length);
+        }
+        @Override
+        public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new Uint8ArrayData(buffer, byteOffset, length);
+        }
+    };
+
+    private static final class Uint8ArrayData extends ArrayDataImpl {
+        private Uint8ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+            super(buffer, byteOffset, elementLength);
+        }
+
+        @Override
+        protected int byteIndex(final int index) {
+            return index * BYTES_PER_ELEMENT + byteOffset;
+        }
+
+        @Override
+        protected int getIntImpl(final int index) {
+            return buffer.getByteArray()[byteIndex(index)] & 0xff;
+        }
+
+        @Override
+        protected void setImpl(final int index, final int value) {
+            buffer.getByteArray()[byteIndex(index)] = (byte)value;
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param newObj is this typed array instantiated with the new operator
+     * @param self   self reference
+     * @param args   args
+     *
+     * @return new typed array
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        return constructorImpl(args, FACTORY);
+    }
+
+    NativeUint8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+        super(buffer, byteOffset, length);
+    }
+
+    @Override
+    protected Factory factory() {
+        return FACTORY;
+    }
+
+    /**
+     * Set values
+     * @param self   self reference
+     * @param array  multiple values of array's type to set
+     * @param offset optional start index, interpreted  0 if undefined
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object set(final Object self, final Object array, final Object offset) {
+        return ArrayBufferView.setImpl(self, array, offset);
+    }
+
+    /**
+     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
+     * referencing the elements at begin, inclusive, up to end, exclusive. If either
+     * begin or end is negative, it refers to an index from the end of the array,
+     * as opposed to from the beginning.
+     * <p>
+     * If end is unspecified, the subarray contains all elements from begin to the end
+     * of the TypedArray. The range specified by the begin and end values is clamped to
+     * the valid index range for the current array. If the computed length of the new
+     * TypedArray would be negative, it is clamped to zero.
+     * <p>
+     * The returned TypedArray will be of the same type as the array on which this
+     * method is invoked.
+     *
+     * @param self self reference
+     * @param begin begin position
+     * @param end end position
+     *
+     * @return sub array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object subarray(final Object self, final Object begin, final Object end) {
+        return ArrayBufferView.subarrayImpl(self, begin, end);
+    }
+
+    @Override
+    protected ScriptObject getPrototype() {
+        return Global.instance().getUint8ArrayPrototype();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
new file mode 100644
index 0000000..e3bacc2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
@@ -0,0 +1,154 @@
+/*
+ * 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.objects;
+
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+
+/**
+ * Uint8 clamped array for TypedArray extension
+ */
+@ScriptClass("Uint8ClampedArray")
+public final class NativeUint8ClampedArray extends ArrayBufferView {
+    private static final int BYTES_PER_ELEMENT = 1;
+    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
+        @Override
+        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new NativeUint8ClampedArray(buffer, byteOffset, length);
+        }
+        @Override
+        public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+            return new Uint8ClampedArrayData(buffer, byteOffset, length);
+        }
+    };
+
+    private static final class Uint8ClampedArrayData extends ArrayDataImpl {
+        private Uint8ClampedArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+            super(buffer, byteOffset, elementLength);
+        }
+
+        @Override
+        protected int byteIndex(final int index) {
+            return index * BYTES_PER_ELEMENT + byteOffset;
+        }
+
+        @Override
+        protected int getIntImpl(final int index) {
+            return buffer.getByteArray()[byteIndex(index)] & 0xff;
+        }
+
+        @Override
+        protected void setImpl(final int index, final int value) {
+            final byte clamped;
+            if ((value & 0xffff_ff00) == 0) {
+                clamped = (byte) value;
+            } else {
+                clamped = value < 0 ? 0 : (byte)0xff;
+            }
+            buffer.getByteArray()[byteIndex(index)] = clamped;
+        }
+
+        @Override
+        protected void setImpl(final int key, final double value) {
+            setImpl(key, (int)Math.rint(value));
+        }
+
+        @Override
+        protected void setImpl(final int key, final Object value) {
+            setImpl(key, JSType.toNumber(value));
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param newObj is this typed array instantiated with the new operator
+     * @param self   self reference
+     * @param args   args
+     *
+     * @return new typed array
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        return constructorImpl(args, FACTORY);
+    }
+
+    NativeUint8ClampedArray(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+        super(buffer, byteOffset, length);
+    }
+
+    @Override
+    protected Factory factory() {
+        return FACTORY;
+    }
+
+    /**
+     * Set values
+     * @param self   self reference
+     * @param array  multiple values of array's type to set
+     * @param offset optional start index, interpreted  0 if undefined
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object set(final Object self, final Object array, final Object offset) {
+        return ArrayBufferView.setImpl(self, array, offset);
+    }
+
+    /**
+     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
+     * referencing the elements at begin, inclusive, up to end, exclusive. If either
+     * begin or end is negative, it refers to an index from the end of the array,
+     * as opposed to from the beginning.
+     * <p>
+     * If end is unspecified, the subarray contains all elements from begin to the end
+     * of the TypedArray. The range specified by the begin and end values is clamped to
+     * the valid index range for the current array. If the computed length of the new
+     * TypedArray would be negative, it is clamped to zero.
+     * <p>
+     * The returned TypedArray will be of the same type as the array on which this
+     * method is invoked.
+     *
+     * @param self self reference
+     * @param begin begin position
+     * @param end end position
+     *
+     * @return sub array
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    protected static Object subarray(final Object self, final Object begin, final Object end) {
+        return ArrayBufferView.subarrayImpl(self, begin, end);
+    }
+
+    @Override
+    protected ScriptObject getPrototype() {
+        return Global.instance().getUint8ClampedArrayPrototype();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
new file mode 100644
index 0000000..edcc327
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
@@ -0,0 +1,111 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.lookup.Lookup;
+
+/**
+ * Instances of this class serve as "prototype" object for script functions.
+ * The purpose is to expose "constructor" property from "prototype". Also, nasgen
+ * generated prototype classes extend from this class.
+ *
+ */
+public class PrototypeObject extends ScriptObject {
+    private static final PropertyMap nasgenmap$;
+
+    private Object constructor;
+
+    private static final MethodHandle GET_CONSTRUCTOR = findOwnMH("getConstructor", Object.class, Object.class);
+    private static final MethodHandle SET_CONSTRUCTOR = findOwnMH("setConstructor", void.class, Object.class, Object.class);
+
+    static {
+        PropertyMap map = PropertyMap.newMap(PrototypeObject.class);
+        map = Lookup.newProperty(map, "constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR);
+        nasgenmap$ = map;
+    }
+
+    PrototypeObject() {
+        this(nasgenmap$);
+    }
+
+    /**
+     * PropertyObject constructor
+     *
+     * @param map property map
+     */
+    public PrototypeObject(final PropertyMap map) {
+        super(map != nasgenmap$ ? map.addAll(nasgenmap$) : nasgenmap$);
+        setProto(Global.objectPrototype());
+    }
+
+    PrototypeObject(final ScriptFunction func) {
+        this();
+        this.constructor = func;
+    }
+
+    /**
+     * Get the constructor for this {@code PrototypeObject}
+     * @param self self reference
+     * @return constructor, probably, but not necessarily, a {@link ScriptFunction}
+     */
+    public static Object getConstructor(final Object self) {
+        return (self instanceof PrototypeObject) ?
+            ((PrototypeObject)self).getConstructor() :
+            UNDEFINED;
+    }
+
+    /**
+     * Reset the constructor for this {@code PrototypeObject}
+     * @param self self reference
+     * @param constructor constructor, probably, but not necessarily, a {@link ScriptFunction}
+     */
+    public static void setConstructor(final Object self, final Object constructor) {
+        if (self instanceof PrototypeObject) {
+            ((PrototypeObject)self).setConstructor(constructor);
+        }
+    }
+
+    private Object getConstructor() {
+        return constructor;
+    }
+
+    private void setConstructor(final Object constructor) {
+        this.constructor = constructor;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.publicLookup(), PrototypeObject.class, name, MH.type(rtype, types));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
new file mode 100644
index 0000000..0514bd2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
@@ -0,0 +1,246 @@
+/*
+ * 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.lang.invoke.MethodHandle;
+import jdk.nashorn.internal.runtime.GlobalFunctions;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptFunctionData;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.lookup.Lookup;
+
+/**
+ * Concrete implementation of ScriptFunction. This sets correct map for the
+ * function objects -- to expose properties like "prototype", "length" etc.
+ */
+public class ScriptFunctionImpl extends ScriptFunction {
+    // property map for strict mode functions
+    private static final PropertyMap strictmodemap$;
+    // property map for bound functions
+    private static final PropertyMap boundfunctionmap$;
+    // property map for non-strict, non-bound functions.
+    private static final PropertyMap nasgenmap$;
+
+    /**
+     * Constructor called by Nasgen generated code, no membercount, use the default map.
+     * Creates builtin functions only.
+     *
+     * @param name name of function
+     * @param invokeHandle handle for invocation
+     * @param specs specialized versions of this method, if available, null otherwise
+     */
+    ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs) {
+        super(name, invokeHandle, nasgenmap$, null, specs, false, true, true);
+        init();
+    }
+
+    /**
+     * Constructor called by Nasgen generated code, no membercount, use the map passed as argument.
+     * Creates builtin functions only.
+     *
+     * @param name name of function
+     * @param invokeHandle handle for invocation
+     * @param map initial property map
+     * @param specs specialized versions of this method, if available, null otherwise
+     */
+    ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs) {
+        super(name, invokeHandle, map.addAll(nasgenmap$), null, specs, false, true, true);
+        init();
+    }
+
+    /**
+     * Constructor called by Global.newScriptFunction (runtime).
+     *
+     * @param name name of function
+     * @param methodHandle handle for invocation
+     * @param scope scope object
+     * @param specs specialized versions of this method, if available, null otherwise
+     * @param strict are we in strict mode
+     * @param builtin is this a built-in function
+     * @param isConstructor can the function be used as a constructor (most can; some built-ins are restricted).
+     */
+    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean strict, final boolean builtin, final boolean isConstructor) {
+        super(name, methodHandle, getMap(strict), scope, specs, strict, builtin, isConstructor);
+        init();
+    }
+
+    /**
+     * Constructor called by (compiler) generated code for {@link ScriptObject}s.
+     *
+     * @param data static function data
+     * @param methodHandle handle for invocation
+     * @param scope scope object
+     * @param allocator instance constructor for function
+     */
+    public ScriptFunctionImpl(final MethodHandle methodHandle, final ScriptFunctionData data, final ScriptObject scope, final MethodHandle allocator) {
+        super(data, getMap(data.isStrict()), scope);
+        // Set method handles in script data
+        data.setMethodHandles(methodHandle, allocator);
+        init();
+    }
+
+    /**
+     * Only invoked internally from {@link BoundScriptFunctionImpl} constructor.
+     * @param data the script function data for the bound function.
+     */
+    ScriptFunctionImpl(final ScriptFunctionData data) {
+        super(data, boundfunctionmap$, null);
+        init();
+    }
+
+    static {
+        PropertyMap map = PropertyMap.newMap(ScriptFunctionImpl.class);
+        map = Lookup.newProperty(map, "prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE);
+        map = Lookup.newProperty(map, "length",    Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null);
+        map = Lookup.newProperty(map, "name",      Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null);
+        nasgenmap$ = map;
+        strictmodemap$ = createStrictModeMap(nasgenmap$);
+        boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
+    }
+
+    // function object representing TypeErrorThrower
+    private static ScriptFunction typeErrorThrower;
+
+    static synchronized ScriptFunction getTypeErrorThrower() {
+        if (typeErrorThrower == null) {
+            //name handle
+            final ScriptFunctionImpl func = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_SETTER, null, null, false, false, false);
+            func.setPrototype(UNDEFINED);
+            typeErrorThrower = func;
+        }
+
+        return typeErrorThrower;
+    }
+
+    // add a new property that throws TypeError on get as well as set
+    static synchronized PropertyMap newThrowerProperty(final PropertyMap map, final String name) {
+        return map.newProperty(name, Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, -1,
+                Lookup.TYPE_ERROR_THROWER_GETTER, Lookup.TYPE_ERROR_THROWER_SETTER);
+    }
+
+    private static PropertyMap createStrictModeMap(final PropertyMap functionMap) {
+        return newThrowerProperty(newThrowerProperty(functionMap, "arguments"), "caller");
+    }
+
+    // Choose the map based on strict mode!
+    private static PropertyMap getMap(final boolean strict) {
+        return strict ? strictmodemap$ : nasgenmap$;
+    }
+
+    private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
+        // Bond function map is same as strict function map, but additionally lacks the "prototype" property, see
+        // ECMAScript 5.1 section 15.3.4.5
+        return strictModeMap.deleteProperty(strictModeMap.findProperty("prototype"));
+    }
+
+    // Instance of this class is used as global anonymous function which
+    // serves as Function.prototype object.
+    private static class AnonymousFunction extends ScriptFunctionImpl {
+        private static final PropertyMap nasgenmap$$ = PropertyMap.newMap(AnonymousFunction.class);
+
+        AnonymousFunction() {
+            super("", GlobalFunctions.ANONYMOUS, nasgenmap$$, null);
+        }
+    }
+
+    static ScriptFunctionImpl newAnonymousFunction() {
+        return new AnonymousFunction();
+    }
+
+    /**
+     * Factory method for non-constructor built-in functions
+     *
+     * @param name   function name
+     * @param methodHandle handle for invocation
+     * @param specs  specialized versions of function if available, null otherwise
+     * @return new ScriptFunction
+     */
+    static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) {
+        final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, false, true, false);
+        func.setPrototype(UNDEFINED);
+
+        return func;
+    }
+
+    /**
+     * Factory method for non-constructor built-in functions
+     *
+     * @param name   function name
+     * @param methodHandle handle for invocation
+     * @return new ScriptFunction
+     */
+    static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle) {
+        return makeFunction(name, methodHandle, null);
+    }
+
+    /**
+     * Same as {@link ScriptFunction#makeBoundFunction(Object, Object[])}. The only reason we override it is so that we
+     * can expose it to methods in this package.
+     * @param self the self to bind to this function. Can be null (in which case, null is bound as this).
+     * @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments.
+     * @return a function with the specified self and parameters bound.
+     */
+    @Override
+    protected ScriptFunction makeBoundFunction(Object self, Object[] args) {
+        return super.makeBoundFunction(self, args);
+    }
+
+    /**
+     * This method is used to create a bound function based on this function.
+     *
+     * @param data the {@code ScriptFunctionData} specifying the functions immutable portion.
+     * @return a function initialized from the specified data. Its parent scope will be set to null, therefore the
+     * passed in data should not expect a callee.
+     */
+    @Override
+    protected ScriptFunction makeBoundFunction(final ScriptFunctionData data) {
+        return new BoundScriptFunctionImpl(data, getTargetFunction());
+    }
+
+    // return Object.prototype - used by "allocate"
+    @Override
+    protected final ScriptObject getObjectPrototype() {
+        return Global.objectPrototype();
+    }
+
+    // Internals below..
+    private void init() {
+        this.setProto(Global.instance().getFunctionPrototype());
+        this.setPrototype(new PrototypeObject(this));
+
+        if (isStrict()) {
+            final ScriptFunction func = getTypeErrorThrower();
+            // We have to fill user accessor functions late as these are stored
+            // in this object rather than in the PropertyMap of this object.
+            setUserAccessors("arguments", func, func);
+            setUserAccessors("caller", func, func);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java
new file mode 100644
index 0000000..4d3df50
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java
@@ -0,0 +1,122 @@
+package jdk.nashorn.internal.objects;
+
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.nashorn.internal.codegen.CompilationException;
+import jdk.nashorn.internal.codegen.Compiler;
+import jdk.nashorn.internal.codegen.FunctionSignature;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.runtime.CodeInstaller;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptFunctionData;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * A trampoline is a promise to compile a {@link ScriptFunction} later. It just looks like
+ * the call to the script function, but when invoked it will compile the script function
+ * (in a new compile unit) and invoke it
+ */
+public final class ScriptFunctionTrampolineImpl extends ScriptFunctionImpl {
+
+    private CodeInstaller<ScriptEnvironment> installer;
+
+    /** Function node to lazily recompile when trampoline is hit */
+    private FunctionNode functionNode;
+
+    /**
+     * Constructor
+     *
+     * @param installer    opaque code installer from context
+     * @param functionNode function node to lazily compile when trampoline is hit
+     * @param data         {@link ScriptFunctionData} for function
+     * @param scope        scope
+     * @param allocator    allocator
+     */
+    public ScriptFunctionTrampolineImpl(final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode, final ScriptFunctionData data, final ScriptObject scope, final MethodHandle allocator) {
+        super(null, data, scope, allocator);
+
+        this.installer    = installer;
+        this.functionNode = functionNode;
+
+        data.setMethodHandles(makeTrampoline(), allocator);
+    }
+
+    private final MethodHandle makeTrampoline() {
+        final MethodType mt =
+            new FunctionSignature(
+                true,
+                functionNode.needsCallee(),
+                Type.OBJECT,
+                functionNode.getParameters().size()).
+            getMethodType();
+
+        return
+            MH.bindTo(
+                MH.asCollector(
+                    findOwnMH(
+                        "trampoline",
+                        Object.class,
+                        Object[].class),
+                    Object[].class,
+                    mt.parameterCount()),
+                this);
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findVirtual(MethodHandles.lookup(), ScriptFunctionTrampolineImpl.class, name, MH.type(rtype, types));
+    }
+
+    @Override
+    protected ScriptFunction makeBoundFunction(final ScriptFunctionData data) {
+        //prevent trampoline recompilation cycle if a function is bound before use
+        compile();
+        return super.makeBoundFunction(data);
+    }
+
+    private MethodHandle compile() throws CompilationException {
+        final Compiler compiler = new Compiler(installer, functionNode);
+
+        compiler.compile();
+
+        final Class<?> clazz = compiler.install();
+        /* compute function signature for lazy method. this can be done first after compilation, as only then do we know
+         * the final state about callees, scopes and specialized parameter types */
+        final FunctionSignature signature = new FunctionSignature(true, functionNode.needsCallee(), Type.OBJECT, functionNode.getParameters().size());
+        final MethodType        mt        = signature.getMethodType();
+
+        MethodHandle mh = MH.findStatic(MethodHandles.publicLookup(), clazz, functionNode.getName(), mt);
+        if (functionNode.needsCallee()) {
+            mh = MH.bindTo(mh, this);
+        }
+
+        // now the invoker method looks like the one our superclass is expecting
+        resetInvoker(mh);
+
+        return mh;
+    }
+
+    @SuppressWarnings("unused")
+    private Object trampoline(final Object... args) throws CompilationException {
+        Compiler.LOG.info(">>> TRAMPOLINE: Hitting trampoline for '" + functionNode.getName() + "'");
+        MethodHandle mh = compile();
+
+        Compiler.LOG.info("<<< COMPILED TO: " + mh);
+        // spread the array to invididual args of the correct type
+        mh = MH.asSpreader(mh, Object[].class, mh.type().parameterCount());
+
+        try {
+            //invoke the real method the trampoline points to. this only happens once
+            return mh.invoke(args);
+        } catch (final RuntimeException | Error e) {
+            throw e;
+        } catch (final Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/Attribute.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/Attribute.java
new file mode 100644
index 0000000..a6b6b1b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/Attribute.java
@@ -0,0 +1,51 @@
+/*
+ * 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.objects.annotations;
+
+/**
+ * Attributes for JavaScript properties. The negative logic "NOT_xxx" is because the
+ * common case is to be writable, enumerable and configurable
+ */
+
+public interface Attribute {
+    /** flag for non writable objects */
+    public static final int NOT_WRITABLE     = jdk.nashorn.internal.runtime.Property.NOT_WRITABLE;
+
+    /** flag for non enumerable objects */
+    public static final int NOT_ENUMERABLE   = jdk.nashorn.internal.runtime.Property.NOT_ENUMERABLE;
+
+    /** flag for non configurable objects */
+    public static final int NOT_CONFIGURABLE = jdk.nashorn.internal.runtime.Property.NOT_CONFIGURABLE;
+
+    /** read-only, non-configurable property */
+    public static final int CONSTANT = NOT_WRITABLE | NOT_CONFIGURABLE;
+
+    /** non-enumerable, read-only, non-configurable property */
+    public static final int NON_ENUMERABLE_CONSTANT = NOT_ENUMERABLE | CONSTANT;
+
+    /** by default properties are writable, enumerable and configurable */
+    public static final int DEFAULT_ATTRIBUTES = 0;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/Constructor.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/Constructor.java
new file mode 100644
index 0000000..297bb1e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/Constructor.java
@@ -0,0 +1,49 @@
+/*
+ * 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.objects.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Specifies a specific method to be the JavaScript "constructor" function.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Constructor {
+    /**
+     * Name of the constructor function. If empty, the name is inferred.
+     */
+    public String name() default "";
+
+    /**
+     * The arity of the function. By default computed from the method signature.
+     * Note that -1 means varargs. So, -2 is used as invalid arity.
+     */
+    public int arity() default -2;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/Function.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/Function.java
new file mode 100644
index 0000000..04c5393
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/Function.java
@@ -0,0 +1,62 @@
+/*
+ * 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.objects.annotations;
+
+import static jdk.nashorn.internal.objects.annotations.Attribute.DEFAULT_ATTRIBUTES;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to specify a JavaScript "function" property.
+ * Note that -1 means varargs. So, -2 is used as invalid arity.
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Function {
+    /**
+     * Name of the property. If empty, the name is inferred.
+     */
+    public String name() default "";
+
+    /**
+     * Attribute flags for this function.
+     */
+    public int attributes() default DEFAULT_ATTRIBUTES;
+
+    /**
+     * The arity of the function. By default computed from the method signature
+     */
+    public int arity() default -2;
+
+    /**
+     * where this function lives
+     */
+    public Where where() default Where.PROTOTYPE;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/Getter.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/Getter.java
new file mode 100644
index 0000000..d10bbf6
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/Getter.java
@@ -0,0 +1,55 @@
+/*
+ * 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.objects.annotations;
+
+import static jdk.nashorn.internal.objects.annotations.Attribute.DEFAULT_ATTRIBUTES;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to specify the getter method for a JavaScript "data" property.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Getter {
+    /**
+     * Name of the property. If empty, the name is inferred.
+     */
+    public String name() default "";
+
+    /**
+     * Attribute flags for this setter.
+     */
+    public int attributes() default DEFAULT_ATTRIBUTES;
+
+    /**
+     * Where this getter lives?
+     */
+    public Where where() default Where.INSTANCE;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/Property.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/Property.java
new file mode 100644
index 0000000..6aec205
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/Property.java
@@ -0,0 +1,60 @@
+/*
+ * 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.objects.annotations;
+
+import static jdk.nashorn.internal.objects.annotations.Attribute.DEFAULT_ATTRIBUTES;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to specify a JavaScript "data" property.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Property {
+    /**
+     * Name of the script property. If empty, the name is inferred.
+     */
+    public String name() default "";
+
+    /**
+     * Attribute flags for this function.
+     */
+    public int attributes() default DEFAULT_ATTRIBUTES;
+
+    /**
+     * Initialize this property with the object of given class.
+     */
+    public String clazz() default "";
+
+    /**
+     * Where this property lives?
+     */
+    public Where where() default Where.INSTANCE;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/ScriptClass.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/ScriptClass.java
new file mode 100644
index 0000000..23d910c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/ScriptClass.java
@@ -0,0 +1,44 @@
+/*
+ * 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.objects.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to specify that the annotated Java class is a JavaScript "class".
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ScriptClass {
+    /**
+     * Name of the script class. By default, the name is derived from
+     * the Java class name.
+     */
+    public String value() default "";
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/Setter.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/Setter.java
new file mode 100644
index 0000000..bad6f2a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/Setter.java
@@ -0,0 +1,55 @@
+/*
+ * 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.objects.annotations;
+
+import static jdk.nashorn.internal.objects.annotations.Attribute.DEFAULT_ATTRIBUTES;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to specify the setter method for a JavaScript "data" property.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Setter {
+    /**
+     * Name of the script property. If empty, the name is inferred.
+     */
+    public String name() default "";
+
+    /**
+     * Attribute flags for this setter.
+     */
+    public int attributes() default DEFAULT_ATTRIBUTES;
+
+    /**
+     * Where this setter lives?
+     */
+    public Where where() default Where.INSTANCE;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedConstructor.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedConstructor.java
new file mode 100644
index 0000000..9e6bd0a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedConstructor.java
@@ -0,0 +1,47 @@
+/*
+ * 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.objects.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The SpecializedConstructor annotation is used to flag more type specific constructors than the standard one in
+ * Native objects. For example {@link jdk.nashorn.internal.objects.NativeArray#construct} takes an arbitrary number of
+ * Object elements as an array. Call this constructor, including the varargs collector that allocates the array
+ * upon each invocation, is much more expensive than calling a specialized constructor that takes one arguments
+ * of, e.g. int type from the call site, such as
+ * {@link jdk.nashorn.internal.objects.NativeArray#construct(boolean, Object, int)}.
+ * {@link jdk.nashorn.internal.runtime.ScriptFunction} will try to look up the most specific function when
+ * linking the callsite.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface SpecializedConstructor {
+    //empty
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java
new file mode 100644
index 0000000..1e75d2a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java
@@ -0,0 +1,46 @@
+/*
+ * 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.objects.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The SpecializedFunction annotation is used to flag more type specific functions than the standard one in
+ * Native objects. For example {@link jdk.nashorn.internal.objects.NativeMath#max} takes an arbitrary number of
+ * Object elements as an array. Call this function, including the varargs collector that allocates the array
+ * upon each invocation, is much more expensive than calling a specialized function that takes two arguments
+ * of, e.g. int type from the call site, such as {@link jdk.nashorn.internal.objects.NativeMath#max(Object, int, int)}.
+ * {@link jdk.nashorn.internal.runtime.ScriptFunction} will try to look up the most specific function when
+ * linking the callsite.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface SpecializedFunction {
+    //empty
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/Where.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/Where.java
new file mode 100644
index 0000000..9153afe
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/Where.java
@@ -0,0 +1,38 @@
+/*
+ * 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.objects.annotations;
+
+/**
+ * Enum to tell where a Function or Property belongs.
+ */
+public enum Where {
+    /** this means that the item belongs in the Constructor of an object */
+    CONSTRUCTOR,
+    /** this means that the item belongs in the Prototype of an object */
+    PROTOTYPE,
+    /** this means that the item belongs in the Instance of an object */
+    INSTANCE
+}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/package-info.java b/nashorn/src/jdk/nashorn/internal/objects/package-info.java
new file mode 100644
index 0000000..6a106ec
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/objects/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * 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.objects;
+
+/**
+ * Classes from this package should never be directly referred from
+ * Nashorn runtime code. These classes can be referred by nasgen though.
+ * Runtime code should use (or extend) GlobalObject interface to access
+ * Global object.
+ */
diff --git a/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java b/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java
new file mode 100644
index 0000000..a3263b8
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java
@@ -0,0 +1,442 @@
+/*
+ * 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.parser;
+
+import static jdk.nashorn.internal.parser.TokenType.EOF;
+import static jdk.nashorn.internal.parser.TokenType.EOL;
+import static jdk.nashorn.internal.parser.TokenType.IDENT;
+
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.parser.Lexer.LexerToken;
+import jdk.nashorn.internal.parser.Lexer.RegexToken;
+import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.JSErrorType;
+import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.regexp.RegExpFactory;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * Base class for parsers.
+ */
+public abstract class AbstractParser {
+    /** Source to parse. */
+    protected final Source source;
+
+    /** Error manager to report errors. */
+    protected final ErrorManager errors;
+
+    /** Stream of lex tokens to parse. */
+    protected TokenStream stream;
+
+    /** Index of current token. */
+    protected int k;
+
+    /** Descriptor of current token. */
+    protected long token;
+
+    /** Type of current token. */
+    protected TokenType type;
+
+    /** Type of last token. */
+    protected TokenType last;
+
+    /** Start position of current token. */
+    protected int start;
+
+    /** Finish position of previous token. */
+    protected int finish;
+
+    /** Current line number. */
+    protected int line;
+
+    /** Position of last EOL + 1. */
+    protected int linePosition;
+
+    /** Lexer used to scan source content. */
+    protected Lexer lexer;
+
+    /** Is this parser running under strict mode? */
+    protected boolean isStrictMode;
+
+    /**
+     * Construct a parser.
+     *
+     * @param source  Source to parse.
+     * @param errors  Error reporting manager.
+     * @param strict  True if we are in strict mode
+     */
+    protected AbstractParser(final Source source, final ErrorManager errors, final boolean strict) {
+        this.source       = source;
+        this.errors       = errors;
+        this.k            = -1;
+        this.token        = Token.toDesc(EOL, 0, 1);
+        this.type         = EOL;
+        this.last         = EOL;
+        this.isStrictMode = strict;
+    }
+
+    /**
+     * Get the ith token.
+     *
+     * @param i Index of token.
+     *
+     * @return  the token
+     */
+    protected final long getToken(final int i) {
+        // Make sure there are enough tokens available.
+        while (i > stream.last()) {
+            // If we need to buffer more for lookahead.
+            if (stream.isFull()) {
+                stream.grow();
+            }
+
+            // Get more tokens.
+            lexer.lexify();
+        }
+
+        return stream.get(i);
+    }
+
+    /**
+     * Return the tokenType of the ith token.
+     *
+     * @param i Index of token
+     *
+     * @return the token type
+     */
+    protected final TokenType T(final int i) {
+        // Get token descriptor and extract tokenType.
+        return Token.descType(getToken(i));
+    }
+
+    /**
+     * Seek next token that is not an EOL.
+     *
+     * @return tokenType of next token.
+     */
+    protected final TokenType next() {
+        do {
+            nextOrEOL();
+        } while (type == EOL);
+
+        return type;
+    }
+
+    /**
+     * Seek next token.
+     *
+     * @return tokenType of next token.
+     */
+    protected final TokenType nextOrEOL() {
+        // Capture last token tokenType.
+        last = type;
+        if (type != EOF) {
+
+            // Set up next token.
+            k++;
+            final long lastToken = token;
+            token = getToken(k);
+            type = Token.descType(token);
+
+            // do this before the start is changed below
+            if (last != EOL) {
+                finish = start + Token.descLength(lastToken);
+            }
+
+            if (type == EOL) {
+                line = Token.descLength(token);
+                linePosition = Token.descPosition(token);
+            } else {
+                start = Token.descPosition(token);
+            }
+
+        }
+
+        return type;
+    }
+
+    /**
+     * Get the message string for a message ID and arguments
+     *
+     * @param msgId The Message ID
+     * @param args  The arguments
+     *
+     * @return The message string
+     */
+    protected static String message(final String msgId, final String... args) {
+        return ECMAErrors.getMessage("parser.error." + msgId, args);
+    }
+
+    /**
+     * Report an error.
+     *
+     * @param message    Error message.
+     * @param errorToken Offending token.
+     */
+    protected final void error(final String message, final long errorToken) {
+        error(JSErrorType.SYNTAX_ERROR, message, errorToken);
+    }
+
+    /**
+     * Report an error.
+     *
+     * @param errorType  The error type
+     * @param message    Error message.
+     * @param errorToken Offending token.
+     */
+    protected final void error(final JSErrorType errorType, final String message, final long errorToken) {
+        final int position  = Token.descPosition(errorToken);
+        final int lineNum   = source.getLine(position);
+        final int columnNum = source.getColumn(position);
+        final String formatted = ErrorManager.format(message, source, lineNum, columnNum, errorToken);
+        throw new ParserException(errorType, formatted, source, lineNum, columnNum, errorToken);
+    }
+
+    /**
+     * Report an error.
+     *
+     * @param message Error message.
+     */
+    protected final void error(final String message) {
+        error(JSErrorType.SYNTAX_ERROR, message);
+    }
+
+    /**
+     * Report an error.
+     *
+     * @param errorType  The error type
+     * @param message    Error message.
+     */
+    protected final void error(final JSErrorType errorType, final String message) {
+        // TODO - column needs to account for tabs.
+        final int position = Token.descPosition(token);
+        final int column = position - linePosition;
+        final String formatted = ErrorManager.format(message, source, line, column, token);
+        throw new ParserException(errorType, formatted, source, line, column, token);
+    }
+
+    /**
+     * Generate 'expected' message.
+     *
+     * @param expected Expected tokenType.
+     *
+     * @return the message string
+     */
+    protected final String expectMessage(final TokenType expected) {
+        final String tokenString = Token.toString(source, token);
+        String msg;
+
+        if (expected == null) {
+            msg = AbstractParser.message("expected.stmt", tokenString);
+        } else {
+            final String expectedName = expected.getNameOrType();
+            msg = AbstractParser.message("expected", expectedName, tokenString);
+        }
+
+        return msg;
+    }
+
+    /**
+     * Check next token and advance.
+     *
+     * @param expected Expected tokenType.
+     *
+     * @throws ParserException on unexpected token type
+     */
+    protected final void expect(final TokenType expected) throws ParserException {
+        if (type != expected) {
+            error(expectMessage(expected));
+        }
+
+        next();
+    }
+
+    /**
+     * Check next token, get its value and advance.
+     *
+     * @param  expected Expected tokenType.
+     * @return The JavaScript value of the token
+     * @throws ParserException on unexpected token type
+     */
+    protected final Object expectValue(final TokenType expected) throws ParserException {
+        if (type != expected) {
+            error(expectMessage(expected));
+        }
+
+        final Object value = getValue();
+
+        next();
+
+        return value;
+    }
+
+    /**
+     * Get the value of the current token.
+     *
+     * @return JavaScript value of the token.
+     */
+    protected final Object getValue() {
+        return getValue(token);
+    }
+
+    /**
+     * Get the value of a specific token
+     *
+     * @param valueToken the token
+     *
+     * @return JavaScript value of the token
+     */
+    protected final Object getValue(final long valueToken) {
+        try {
+            return lexer.getValueOf(valueToken, isStrictMode);
+        } catch (final ParserException e) {
+            errors.error(e);
+        }
+
+        return null;
+    }
+
+    /**
+     * Certain future reserved words can be used as identifiers in
+     * non-strict mode. Check if the current token is one such.
+     *
+     * @return true if non strict mode identifier
+     */
+    protected final boolean isNonStrictModeIdent() {
+        return !isStrictMode && type.getKind() == TokenKind.FUTURESTRICT;
+    }
+
+    /**
+     * Get ident.
+     *
+     * @return Ident node.
+     */
+    protected final IdentNode getIdent() {
+        // Capture IDENT token.
+        long identToken = token;
+
+        if (isNonStrictModeIdent()) {
+            // Fake out identifier.
+            identToken = Token.recast(token, IDENT);
+            // Get IDENT.
+            final String ident = (String)getValue(identToken);
+
+            next();
+
+            // Create IDENT node.
+            return new IdentNode(source, identToken, finish, ident);
+        }
+
+        // Get IDENT.
+        final String ident = (String)expectValue(IDENT);
+        if (ident == null) {
+            return null;
+        }
+        // Create IDENT node.
+        return new IdentNode(source, identToken, finish, ident);
+    }
+
+    /**
+     * Check if current token is in identifier name
+     *
+     * @return true if current token is an identifier name
+     */
+    protected final boolean isIdentifierName() {
+        final TokenKind kind = type.getKind();
+        if (kind == TokenKind.KEYWORD || kind == TokenKind.FUTURE || kind == TokenKind.FUTURESTRICT) {
+            return true;
+        }
+        // Fake out identifier.
+        final long identToken = Token.recast(token, IDENT);
+        // Get IDENT.
+        final String ident = (String)getValue(identToken);
+        return !ident.isEmpty() && Character.isJavaIdentifierStart(ident.charAt(0));
+    }
+
+    /**
+     * Create an IdentNode from the current token
+     *
+     * @return an IdentNode representing the current token
+     */
+    protected final IdentNode getIdentifierName() {
+        if (type == IDENT) {
+            return getIdent();
+        } else if (isIdentifierName()) {
+            // Fake out identifier.
+            final long identToken = Token.recast(token, IDENT);
+            // Get IDENT.
+            final String ident = (String)getValue(identToken);
+            next();
+            // Create IDENT node.
+            return new IdentNode(source, identToken, finish, ident);
+        } else {
+            expect(IDENT);
+            return null;
+        }
+    }
+
+    /**
+     * Create a LiteralNode from the current token
+     *
+     * @return LiteralNode representing the current token
+     * @throws ParserException if any literals fails to parse
+     */
+    protected final LiteralNode<?> getLiteral() throws ParserException {
+        // Capture LITERAL token.
+        final long literalToken = token;
+
+        // Create literal node.
+        final Object value = getValue();
+        // Advance to have a correct finish
+        next();
+
+        LiteralNode<?> node = null;
+
+        if (value == null) {
+            node = LiteralNode.newInstance(source, literalToken, finish);
+        } else if (value instanceof Number) {
+            node = LiteralNode.newInstance(source, literalToken, finish, (Number)value);
+        } else if (value instanceof String) {
+            node = LiteralNode.newInstance(source, literalToken, finish, (String)value);
+        } else if (value instanceof LexerToken) {
+            if (value instanceof RegexToken) {
+                final RegexToken regex = (RegexToken)value;
+                try {
+                    RegExpFactory.validate(regex.getExpression(), regex.getOptions());
+                } catch (final ParserException e) {
+                    error(e.getMessage());
+                }
+            }
+            node = LiteralNode.newInstance(source, literalToken, finish, (LexerToken)value);
+        } else {
+            assert false : "unknown type for LiteralNode: " + value.getClass();
+        }
+
+        return node;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java
new file mode 100644
index 0000000..39cf549
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java
@@ -0,0 +1,346 @@
+/*
+ * 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.parser;
+
+import static jdk.nashorn.internal.parser.TokenType.COLON;
+import static jdk.nashorn.internal.parser.TokenType.COMMARIGHT;
+import static jdk.nashorn.internal.parser.TokenType.EOF;
+import static jdk.nashorn.internal.parser.TokenType.ESCSTRING;
+import static jdk.nashorn.internal.parser.TokenType.RBRACE;
+import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
+import static jdk.nashorn.internal.parser.TokenType.STRING;
+
+import java.util.ArrayList;
+import java.util.List;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
+import jdk.nashorn.internal.ir.PropertyNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * Parses JSON text and returns the corresponding IR node. This is derived from the objectLiteral production of the main parser.
+ *
+ * See: 15.12.1.2 The JSON Syntactic Grammar
+ */
+public class JSONParser extends AbstractParser {
+
+    /**
+     * Constructor
+     * @param source  the source
+     * @param errors  the error manager
+     * @param strict  are we in strict mode
+     */
+    public JSONParser(final Source source, final ErrorManager errors, final boolean strict) {
+        super(source, errors, strict);
+    }
+
+    /**
+     * Implementation of the Quote(value) operation as defined in the ECMA script spec
+     * It wraps a String value in double quotes and escapes characters within in
+     *
+     * @param value string to quote
+     *
+     * @return quoted and escaped string
+     */
+    public static String quote(final String value) {
+
+        final StringBuilder product = new StringBuilder();
+
+        product.append("\"");
+
+        for (final char ch : value.toCharArray()) {
+            // TODO: should use a table?
+            switch (ch) {
+            case '\\':
+                product.append("\\\\");
+                break;
+            case '"':
+                product.append("\\\"");
+                break;
+            case '\b':
+                product.append("\\b");
+                break;
+            case '\f':
+                product.append("\\f");
+                break;
+            case '\n':
+                product.append("\\n");
+                break;
+            case '\r':
+                product.append("\\r");
+                break;
+            case '\t':
+                product.append("\\t");
+                break;
+            default:
+                if (ch < ' ') {
+                    product.append(Lexer.unicodeEscape(ch));
+                    break;
+                }
+
+                product.append(ch);
+                break;
+            }
+        }
+
+        product.append("\"");
+
+        return product.toString();
+    }
+
+    /**
+     * Public parsed method - start lexing a new token stream for
+     * a JSON script
+     *
+     * @return the JSON literal
+     */
+    public Node parse() {
+        stream = new TokenStream();
+
+        lexer = new Lexer(source, stream) {
+
+            @Override
+            protected boolean skipComments() {
+                return false;
+            }
+
+            @Override
+            protected boolean isStringDelimiter(final char ch) {
+                return ch == '\"';
+            }
+
+            @Override
+            protected boolean isWhitespace(final char ch) {
+                return Lexer.isJsonWhitespace(ch);
+            }
+
+            @Override
+            protected boolean isEOL(final char ch) {
+                return Lexer.isJsonEOL(ch);
+            }
+        };
+
+        k = -1;
+
+        next();
+
+        final Node resultNode = jsonLiteral();
+        expect(EOF);
+
+        return resultNode;
+    }
+
+    @SuppressWarnings("fallthrough")
+    private LiteralNode<?> getStringLiteral() {
+        final LiteralNode<?> literal = getLiteral();
+        final String         str     = (String)literal.getValue();
+
+        for (int i = 0; i < str.length(); i++) {
+            final char ch = str.charAt(i);
+            switch (ch) {
+            default:
+                if (ch > 0x001f) {
+                    break;
+                }
+            case '"':
+            case '\\':
+                error(AbstractParser.message("unexpected.token", str));
+                break;
+            }
+        }
+
+        return literal;
+    }
+
+    /**
+     * Parse a JSON literal from the token stream
+     * @return the JSON literal as a Node
+     */
+    private Node jsonLiteral() {
+        final long literalToken = token;
+
+        switch (type) {
+        case STRING:
+            return getStringLiteral();
+        case ESCSTRING:
+        case DECIMAL:
+        case FLOATING:
+            return getLiteral();
+        case FALSE:
+            next();
+            return LiteralNode.newInstance(source, literalToken, finish, false);
+        case TRUE:
+            next();
+            return LiteralNode.newInstance(source, literalToken, finish, true);
+        case NULL:
+            next();
+            return LiteralNode.newInstance(source, literalToken, finish);
+        case LBRACKET:
+            return arrayLiteral();
+        case LBRACE:
+            return objectLiteral();
+        /*
+         * A.8.1 JSON Lexical Grammar
+         *
+         * JSONNumber :: See 15.12.1.1
+         *    -opt DecimalIntegerLiteral JSONFractionopt ExponentPartopt
+         */
+        case SUB:
+            next();
+
+            final long realToken = token;
+            final Object value = getValue();
+
+            if (value instanceof Number) {
+                next();
+                return new UnaryNode(source, literalToken, LiteralNode.newInstance(source, realToken, finish, (Number)value));
+            }
+
+            error(AbstractParser.message("expected", "number", type.getNameOrType()));
+            break;
+        default:
+            break;
+        }
+
+        error(AbstractParser.message("expected", "json literal", type.getNameOrType()));
+        return null;
+    }
+
+    /**
+     * Parse an array literal from the token stream
+     * @return the array literal as a Node
+     */
+    private Node arrayLiteral() {
+        // Unlike JavaScript array literals, elison is not permitted in JSON.
+
+        // Capture LBRACKET token.
+        final long arrayToken = token;
+        // LBRACKET tested in caller.
+        next();
+
+        Node result = null;
+        // Prepare to accummulating elements.
+        final List<Node> elements = new ArrayList<>();
+
+loop:
+        while (true) {
+            switch (type) {
+            case RBRACKET:
+                next();
+                result = LiteralNode.newInstance(source, arrayToken, finish, elements);
+                break loop;
+
+            case COMMARIGHT:
+                next();
+                break;
+
+            default:
+                // Add expression element.
+                elements.add(jsonLiteral());
+                // Comma between array elements is mandatory in JSON.
+                if (type != COMMARIGHT && type != RBRACKET) {
+                    error(AbstractParser.message("expected", ", or ]", type.getNameOrType()));
+                }
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Parse an object literal from the token stream
+     * @return the object literal as a Node
+     */
+    private Node objectLiteral() {
+        // Capture LBRACE token.
+        final long objectToken = token;
+        // LBRACE tested in caller.
+        next();
+
+        // Prepare to accumulate elements.
+        final List<Node> elements = new ArrayList<>();
+
+        // Create a block for the object literal.
+loop:
+        while (true) {
+            switch (type) {
+            case RBRACE:
+                next();
+                break loop;
+
+            case COMMARIGHT:
+                next();
+                break;
+
+            default:
+                // Get and add the next property.
+                final Node property = propertyAssignment();
+                elements.add(property);
+
+                // Comma between property assigments is mandatory in JSON.
+                if (type != RBRACE && type != COMMARIGHT) {
+                    error(AbstractParser.message("expected", ", or }", type.getNameOrType()));
+                }
+                break;
+            }
+        }
+
+        // Construct new object literal.
+        return new ObjectNode(source, objectToken, finish, null, elements);
+    }
+
+    /**
+     * Parse a property assignment from the token stream
+     * @return the property assignment as a Node
+     */
+    private Node propertyAssignment() {
+        // Capture firstToken.
+        final long propertyToken = token;
+        LiteralNode<?> name = null;
+
+        if (type == STRING) {
+            name = getStringLiteral();
+        } else if (type == ESCSTRING) {
+            name = getLiteral();
+        }
+
+        if (name != null) {
+            expect(COLON);
+            final Node value = jsonLiteral();
+            return new PropertyNode(source, propertyToken, value.getFinish(), name, value);
+        }
+
+        // Raise an error.
+        error(AbstractParser.message("expected", "string", type.getNameOrType()));
+
+        return null;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/Lexer.java b/nashorn/src/jdk/nashorn/internal/parser/Lexer.java
new file mode 100644
index 0000000..0c2255d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/Lexer.java
@@ -0,0 +1,1675 @@
+/*
+ * 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.parser;
+
+import static jdk.nashorn.internal.parser.TokenType.ADD;
+import static jdk.nashorn.internal.parser.TokenType.DECIMAL;
+import static jdk.nashorn.internal.parser.TokenType.EOF;
+import static jdk.nashorn.internal.parser.TokenType.EOL;
+import static jdk.nashorn.internal.parser.TokenType.ERROR;
+import static jdk.nashorn.internal.parser.TokenType.ESCSTRING;
+import static jdk.nashorn.internal.parser.TokenType.EXECSTRING;
+import static jdk.nashorn.internal.parser.TokenType.FLOATING;
+import static jdk.nashorn.internal.parser.TokenType.HEXADECIMAL;
+import static jdk.nashorn.internal.parser.TokenType.LBRACE;
+import static jdk.nashorn.internal.parser.TokenType.LPAREN;
+import static jdk.nashorn.internal.parser.TokenType.OCTAL;
+import static jdk.nashorn.internal.parser.TokenType.RBRACE;
+import static jdk.nashorn.internal.parser.TokenType.REGEX;
+import static jdk.nashorn.internal.parser.TokenType.RPAREN;
+import static jdk.nashorn.internal.parser.TokenType.STRING;
+import static jdk.nashorn.internal.parser.TokenType.XML;
+
+import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.JSErrorType;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Responsible for converting source content into a stream of tokens.
+ *
+ */
+@SuppressWarnings("fallthrough")
+public class Lexer extends Scanner {
+    private static final boolean XML_LITERALS = Options.getBooleanProperty("nashorn.lexer.xmlliterals");
+
+    /** Content source. */
+    private final Source source;
+
+    /** Buffered stream for tokens. */
+    private final TokenStream stream;
+
+    /** True if here and edit strings are supported. */
+    private final boolean scripting;
+
+    /** True if a nested scan. (scan to completion, no EOF.) */
+    private final boolean nested;
+
+    /** Pending new line number and position. */
+    private int pendingLine;
+
+    /** Position of last EOL + 1. */
+    private int linePosition;
+
+    /** Type of last token added. */
+    private TokenType last;
+
+    private static final String JAVASCRIPT_WHITESPACE;
+    private static final String JAVASCRIPT_WHITESPACE_EOL;
+    private static final String JAVASCRIPT_WHITESPACE_IN_REGEXP;
+
+    private static final String JSON_WHITESPACE;
+    private static final String JSON_WHITESPACE_EOL;
+
+    static String unicodeEscape(final char ch) {
+        final StringBuilder sb = new StringBuilder();
+
+        sb.append("\\u");
+
+        final String hex = Integer.toHexString(ch);
+        for (int i = hex.length(); i < 4; i++) {
+            sb.append('0');
+        }
+        sb.append(hex);
+
+        return sb.toString();
+    }
+
+    static {
+        final StringBuilder ws       = new StringBuilder();
+        final StringBuilder wsEOL    = new StringBuilder();
+        final StringBuilder wsRegExp = new StringBuilder();
+        final StringBuilder jsonWs   = new StringBuilder();
+
+        jsonWs.append((char)0x000a);
+        jsonWs.append((char)0x000d);
+        JSON_WHITESPACE_EOL = jsonWs.toString();
+
+        jsonWs.append((char)0x0009);
+        jsonWs.append((char)0x0020);
+        JSON_WHITESPACE = jsonWs.toString();
+
+        for (int i = 0; i <= 0xffff; i++) {
+           switch (i) {
+            case 0x000a: // line feed
+            case 0x000d: // carriage return (ctrl-m)
+            case 0x2028: // line separator
+            case 0x2029: // paragraph separator
+                wsEOL.append((char)i);
+            case 0x0009: // tab
+            case 0x0020: // ASCII space
+            case 0x000b: // tabulation line
+            case 0x000c: // ff (ctrl-l)
+            case 0x00a0: // Latin-1 space
+            case 0x1680: // Ogham space mark
+            case 0x180e: // separator, Mongolian vowel
+            case 0x2000: // en quad
+            case 0x2001: // em quad
+            case 0x2002: // en space
+            case 0x2003: // em space
+            case 0x2004: // three-per-em space
+            case 0x2005: // four-per-em space
+            case 0x2006: // six-per-em space
+            case 0x2007: // figure space
+            case 0x2008: // punctuation space
+            case 0x2009: // thin space
+            case 0x200a: // hair space
+            case 0x202f: // narrow no-break space
+            case 0x205f: // medium mathematical space
+            case 0x3000: // ideographic space
+            case 0xfeff: // byte order mark
+                ws.append((char)i);
+
+                wsRegExp.append(Lexer.unicodeEscape((char)i));
+                break;
+
+            default:
+                break;
+            }
+        }
+
+        JAVASCRIPT_WHITESPACE = ws.toString();
+        JAVASCRIPT_WHITESPACE_EOL = wsEOL.toString();
+        JAVASCRIPT_WHITESPACE_IN_REGEXP = wsRegExp.toString();
+
+    }
+
+    /**
+     * Constructor
+     *
+     * @param source    the source
+     * @param stream    the token stream to lex
+     */
+    public Lexer(final Source source, final TokenStream stream) {
+        this(source, stream, false);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param source    the source
+     * @param stream    the token stream to lex
+     * @param scripting are we in scripting mode
+     */
+    public Lexer(final Source source, final TokenStream stream, final boolean scripting) {
+        super(source.getContent(), 1, 0, source.getLength());
+
+        this.source      = source;
+        this.stream      = stream;
+        this.scripting   = scripting;
+        this.nested      = false;
+        this.pendingLine = 1;
+        this.last        = EOL;
+    }
+
+    private Lexer(final Lexer lexer, final State state) {
+        super(lexer, state);
+
+        source = lexer.source;
+        stream = lexer.stream;
+        scripting = lexer.scripting;
+        nested = true;
+
+        pendingLine = state.pendingLine;
+        linePosition = state.linePosition;
+        last = EOL;
+    }
+
+    static class State extends Scanner.State {
+        /** Pending new line number and position. */
+        public final int pendingLine;
+
+        /** Position of last EOL + 1. */
+        public final int linePosition;
+
+        /** Type of last token added. */
+        public final TokenType last;
+
+        /*
+         * Constructor.
+         */
+
+        State(final int position, final int limit, final int line, final int pendingLine, final int linePosition, final TokenType last) {
+            super(position, limit, line);
+
+            this.pendingLine = pendingLine;
+            this.linePosition = linePosition;
+            this.last = last;
+        }
+    }
+
+    /**
+     * Save the state of the scan.
+     *
+     * @return Captured state.
+     */
+    @Override
+    State saveState() {
+        return new State(position, limit, line, pendingLine, linePosition, last);
+    }
+
+    /**
+     * Restore the state of the scan.
+     *
+     * @param state
+     *            Captured state.
+     */
+    void restoreState(final State state) {
+        super.restoreState(state);
+
+        pendingLine = state.pendingLine;
+        linePosition = state.linePosition;
+        last = state.last;
+    }
+
+    /**
+     * Add a new token to the stream.
+     *
+     * @param type
+     *            Token type.
+     * @param start
+     *            Start position.
+     * @param end
+     *            End position.
+     */
+    protected void add(final TokenType type, final int start, final int end) {
+        // Record last token.
+        last = type;
+
+        // Only emit the last EOL in a cluster.
+        if (type == EOL) {
+            pendingLine = end;
+            linePosition = start;
+        } else {
+            // Write any pending EOL to stream.
+            if (pendingLine != -1) {
+                stream.put(Token.toDesc(EOL, linePosition, pendingLine));
+                pendingLine = -1;
+            }
+
+            // Write token to stream.
+            stream.put(Token.toDesc(type, start, end - start));
+        }
+    }
+
+    /**
+     * Add a new token to the stream.
+     *
+     * @param type
+     *            Token type.
+     * @param start
+     *            Start position.
+     */
+    protected void add(final TokenType type, final int start) {
+        add(type, start, position);
+    }
+
+    /**
+     * Return the String of valid whitespace characters for regular
+     * expressions in JavaScript
+     * @return regexp whitespace string
+     */
+    public static String getWhitespaceRegExp() {
+        return JAVASCRIPT_WHITESPACE_IN_REGEXP;
+    }
+
+    /**
+     * Skip end of line.
+     *
+     * @param addEOL true if EOL token should be recorded.
+     */
+    private void skipEOL(final boolean addEOL) {
+
+        if (ch0 == '\r') { // detect \r\n pattern
+            skip(1);
+            if (ch0 == '\n') {
+                skip(1);
+            }
+        } else { // all other space, ch0 is guaranteed to be EOL or \0
+            skip(1);
+        }
+
+        // bump up line count
+        line++;
+
+        if (addEOL) {
+            // Add an EOL token.
+            add(EOL, position, line);
+        }
+    }
+
+    /**
+     * Skip over rest of line including end of line.
+     *
+     * @param addEOL true if EOL token should be recorded.
+     */
+    private void skipLine(final boolean addEOL) {
+        // Ignore characters.
+        while (!isEOL(ch0) && !atEOF()) {
+            skip(1);
+        }
+        // Skip over end of line.
+        skipEOL(addEOL);
+    }
+
+    /**
+     * Test whether a char is valid JavaScript whitespace
+     * @param ch a char
+     * @return true if valid JavaScript whitespace
+     */
+    public static boolean isJSWhitespace(final char ch) {
+        return JAVASCRIPT_WHITESPACE.indexOf(ch) != -1;
+    }
+
+    /**
+     * Test whether a char is valid JavaScript end of line
+     * @param ch a char
+     * @return true if valid JavaScript end of line
+     */
+    public static boolean isJSEOL(final char ch) {
+        return JAVASCRIPT_WHITESPACE_EOL.indexOf(ch) != -1;
+    }
+
+    /**
+     * Test whether a char is valid JSON whitespace
+     * @param ch a char
+     * @return true if valid JSON whitespace
+     */
+    public static boolean isJsonWhitespace(final char ch) {
+        return JSON_WHITESPACE.indexOf(ch) != -1;
+    }
+
+    /**
+     * Test whether a char is valid JSON end of line
+     * @param ch a char
+     * @return true if valid JSON end of line
+     */
+    public static boolean isJsonEOL(final char ch) {
+        return JSON_WHITESPACE_EOL.indexOf(ch) != -1;
+    }
+
+    /**
+     * Test if char is a string delimiter, e.g. '\' or '"'.  Also scans exec
+     * strings ('`') in scripting mode.
+     * @param ch a char
+     * @return true if string delimiter
+     */
+    protected boolean isStringDelimiter(final char ch) {
+        return ch == '\'' || ch == '"' || (scripting && ch == '`');
+    }
+
+    /**
+     * Test whether a char is valid JavaScript whitespace
+     * @param ch a char
+     * @return true if valid JavaScript whitespace
+     */
+    protected boolean isWhitespace(final char ch) {
+        return Lexer.isJSWhitespace(ch);
+    }
+
+    /**
+     * Test whether a char is valid JavaScript end of line
+     * @param ch a char
+     * @return true if valid JavaScript end of line
+     */
+    protected boolean isEOL(final char ch) {
+        return Lexer.isJSEOL(ch);
+    }
+
+    /**
+     * Skip over whitespace and detect end of line, adding EOL tokens if
+     * encountered.
+     *
+     * @param addEOL true if EOL tokens should be recorded.
+     */
+    private void skipWhitespace(final boolean addEOL) {
+        while (isWhitespace(ch0)) {
+            if (isEOL(ch0)) {
+                skipEOL(addEOL);
+            } else {
+                skip(1);
+            }
+        }
+    }
+
+    /**
+     * Skip over comments.
+     *
+     * @return True if a comment.
+     */
+    protected boolean skipComments() {
+        if (ch0 == '/') {
+            // Is it a // comment.
+            if (ch1 == '/') {
+                // Skip over //.
+                skip(2);
+                // Scan for EOL.
+                while (!atEOF() && !isEOL(ch0)) {
+                    skip(1);
+                }
+                // Did detect a comment.
+                return true;
+            } else if (ch1 == '*') {
+                // Record beginning of comment.
+                final int start = position;
+                // Skip over /*.
+                skip(2);
+                // Scan for */.
+                while (!atEOF() && !(ch0 == '*' && ch1 == '/')) {
+                    // If end of line handle else skip character.
+                    if (isEOL(ch0)) {
+                        skipEOL(true);
+                    } else {
+                        skip(1);
+                    }
+                }
+
+                if (atEOF()) {
+                    // TODO - Report closing */ missing in parser.
+                    add(ERROR, start);
+                } else {
+                    // Skip */.
+                    skip(2);
+                }
+
+                // Did detect a comment.
+                return true;
+            }
+        }
+
+        if (scripting && ch0 == '#') {
+            // shell style comment
+            // Skip over #.
+            skip(1);
+            // Scan for EOL.
+            while (!atEOF() && !isEOL(ch0)) {
+                skip(1);
+            }
+            // Did detect a comment.
+            return true;
+        }
+
+        // Not a comment.
+        return false;
+    }
+
+    /**
+     * Convert a regex token to a token object.
+     *
+     * @param start  Position in source content.
+     * @param length Length of regex token.
+     * @return Regex token object.
+     */
+    public RegexToken valueOfPattern(final int start, final int length) {
+        // Save the current position.
+        final int savePosition = position;
+        // Reset to beginning of content.
+        reset(start);
+        // Buffer for recording characters.
+        final StringBuilder sb = new StringBuilder(length);
+
+        // Skip /.
+        skip(1);
+        boolean inBrackets = false;
+        // Scan for closing /, stopping at end of line.
+        while (!atEOF() && ch0 != '/' && !isEOL(ch0) || inBrackets) {
+            // Skip over escaped character.
+            if (ch0 == '\\') {
+                sb.append(ch0);
+                sb.append(ch1);
+                skip(2);
+            } else {
+                if (ch0 == '[') {
+                    inBrackets = true;
+                } else if (ch0 == ']') {
+                    inBrackets = false;
+                }
+
+                // Skip literal character.
+                sb.append(ch0);
+                skip(1);
+            }
+        }
+
+        // Get pattern as string.
+        final String regex = sb.toString();
+
+        // Skip /.
+        skip(1);
+
+        // Options as string.
+        final String options = source.getString(position, scanIdentifier());
+
+        reset(savePosition);
+
+        // Compile the pattern.
+        return new RegexToken(regex, options);
+    }
+
+    /**
+     * Return true if the given token can be the beginning of a literal.
+     *
+     * @param token a token
+     * @return true if token can start a literal.
+     */
+    public boolean canStartLiteral(final TokenType token) {
+        return token.startsWith('/') || ((scripting || XML_LITERALS) && token.startsWith('<'));
+    }
+
+    /**
+     * Check whether the given token represents the beginning of a literal. If so scan
+     * the literal and return <tt>true</tt>, otherwise return false.
+     *
+     * @param token the token.
+     * @param startTokenType the token type.
+     * @return True if a literal beginning with startToken was found and scanned.
+     */
+    protected boolean scanLiteral(final long token, final TokenType startTokenType) {
+        // Check if it can be a literal.
+        if (!canStartLiteral(startTokenType)) {
+            return false;
+        }
+        // We break on ambiguous tokens so if we already moved on it can't be a literal.
+        if (stream.get(stream.last()) != token) {
+            return false;
+        }
+        // Rewind to token start position
+        reset(Token.descPosition(token));
+
+        if (ch0 == '/') {
+            return scanRegEx();
+        } else if (ch0 == '<') {
+            if (ch1 == '<') {
+                return scanHereString();
+            } else if (Character.isJavaIdentifierStart(ch1)) {
+                return scanXMLLiteral();
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Scan over regex literal.
+     *
+     * @return True if a regex literal.
+     */
+    private boolean scanRegEx() {
+        assert ch0 == '/';
+        // Make sure it's not a comment.
+        if (ch1 != '/' && ch1 != '*') {
+            // Record beginning of literal.
+            final int start = position;
+            // Skip /.
+            skip(1);
+            boolean inBrackets = false;
+
+            // Scan for closing /, stopping at end of line.
+            while (!atEOF() && (ch0 != '/' || inBrackets) && !isEOL(ch0)) {
+                // Skip over escaped character.
+                if (ch0 == '\\') {
+                    skip(1);
+                    if (isEOL(ch0)) {
+                        reset(start);
+                        return false;
+                    }
+                    skip(1);
+                } else {
+                    if (ch0 == '[') {
+                        inBrackets = true;
+                    } else if (ch0 == ']') {
+                        inBrackets = false;
+                    }
+
+                    // Skip literal character.
+                    skip(1);
+                }
+            }
+
+            // If regex literal.
+            if (ch0 == '/') {
+                // Skip /.
+                skip(1);
+
+                // Skip over options.
+                while (!atEOF() && Character.isJavaIdentifierPart(ch0) || ch0 == '\\' && ch1 == 'u') {
+                    skip(1);
+                }
+
+                // Add regex token.
+                add(REGEX, start);
+                // Regex literal detected.
+                return true;
+            }
+
+            // False start try again.
+            reset(start);
+        }
+
+        // Regex literal not detected.
+        return false;
+    }
+
+    /**
+     * Convert a digit to a integer.  Can't use Character.digit since we are
+     * restricted to ASCII by the spec.
+     *
+     * @param ch   Character to convert.
+     * @param base Numeric base.
+     *
+     * @return The converted digit or -1 if invalid.
+     */
+    private static int convertDigit(final char ch, final int base) {
+        int digit;
+
+        if ('0' <= ch && ch <= '9') {
+            digit = ch - '0';
+        } else if ('A' <= ch && ch <= 'Z') {
+            digit = ch - 'A' + 10;
+        } else if ('a' <= ch && ch <= 'z') {
+            digit = ch - 'a' + 10;
+        } else {
+            return -1;
+        }
+
+        return digit < base ? digit : -1;
+    }
+
+
+    /**
+     * Get the value of a numeric sequence.
+     *
+     * @param base  Numeric base.
+     * @param max   Maximum number of digits.
+     * @param skip  Skip over escape first.
+     * @param check Tells whether to throw error if a digit is invalid for the given base.
+     * @param type  Type of token to report against.
+     *
+     * @return Value of sequence or < 0 if no digits.
+     */
+    private int valueOfSequence(final int base, final int max, final boolean skip, final boolean check, final TokenType type) {
+        assert base == 16 || base == 8 : "base other than 16 or 8";
+        final boolean isHex = base == 16;
+        final int shift = isHex ? 4 : 3;
+        int value = 0;
+
+        if (skip) {
+            skip(2);
+        }
+
+        for (int i = 0; i < max; i++) {
+            final int digit = convertDigit(ch0, base);
+
+            if (digit == -1) {
+                if (check) {
+                    error(Lexer.message("invalid." + (isHex ? "hex" : "octal")), type, position, limit);
+                }
+                return i == 0 ? -1 : value;
+            }
+
+            value = value << shift | digit;
+            skip(1);
+        }
+
+        return value;
+    }
+
+    /**
+     * Convert a string to a JavaScript identifier.
+     *
+     * @param start  Position in source content.
+     * @param length Length of token.
+     * @return Ident string or null if an error.
+     */
+    private String valueOfIdent(final int start, final int length) throws RuntimeException {
+        // Save the current position.
+        final int savePosition = position;
+        // End of scan.
+        final int end = start + length;
+        // Reset to beginning of content.
+        reset(start);
+        // Buffer for recording characters.
+        final StringBuilder sb = new StringBuilder(length);
+
+        // Scan until end of line or end of file.
+        while (!atEOF() && position < end && !isEOL(ch0)) {
+            // If escape character.
+            if (ch0 == '\\' && ch1 == 'u') {
+                final int ch = valueOfSequence(16, 4, true, true, TokenType.IDENT);
+                if (isWhitespace((char)ch)) {
+                    return null;
+                }
+                if (ch < 0) {
+                    sb.append('\\');
+                    sb.append('u');
+                } else {
+                    sb.append((char)ch);
+                }
+            } else {
+                // Add regular character.
+                sb.append(ch0);
+                skip(1);
+            }
+        }
+
+        // Restore position.
+        reset(savePosition);
+
+        return sb.toString();
+    }
+
+    /**
+     * Scan over and identifier or keyword. Handles identifiers containing
+     * encoded Unicode chars.
+     *
+     * Example:
+     *
+     * var \u0042 = 44;
+     */
+    private void scanIdentifierOrKeyword() {
+        // Record beginning of identifier.
+        final int start = position;
+        // Scan identifier.
+        final int length = scanIdentifier();
+        // Check to see if it is a keyword.
+        final TokenType type = TokenLookup.lookupKeyword(content, start, length);
+        // Add keyword or identifier token.
+        add(type, start);
+    }
+
+    /**
+     * Convert a string to a JavaScript string object.
+     *
+     * @param start  Position in source content.
+     * @param length Length of token.
+     * @return JavaScript string object.
+     */
+    private String valueOfString(final int start, final int length, final boolean strict) throws RuntimeException {
+        // Save the current position.
+        final int savePosition = position;
+        // Calculate the end position.
+        final int end = start + length;
+        // Reset to beginning of string.
+        reset(start);
+
+        // Buffer for recording characters.
+        final StringBuilder sb = new StringBuilder(length);
+
+        // Scan until end of string.
+        while (position < end) {
+            // If escape character.
+            if (ch0 == '\\') {
+                skip(1);
+
+                final char next = ch0;
+                final int afterSlash = position;
+
+                skip(1);
+
+                // Special characters.
+                switch (next) {
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7': {
+                    if (strict) {
+                        // "\0" itself is allowed in strict mode. Only other 'real'
+                        // octal escape sequences are not allowed (eg. "\02", "\31").
+                        // See section 7.8.4 String literals production EscapeSequence
+                        if (next != '0' || (ch0 >= '0' && ch0 <= '9')) {
+                            error(Lexer.message("strict.no.octal"), STRING, position, limit);
+                        }
+                    }
+                    reset(afterSlash);
+                    // Octal sequence.
+                    final int ch = valueOfSequence(8, 3, false, false, STRING);
+
+                    if (ch < 0) {
+                        sb.append('\\');
+                        sb.append('x');
+                    } else {
+                        sb.append((char)ch);
+                    }
+                    break;
+                }
+                case 'n':
+                    sb.append('\n');
+                    break;
+                case 't':
+                    sb.append('\t');
+                    break;
+                case 'b':
+                    sb.append('\b');
+                    break;
+                case 'f':
+                    sb.append('\f');
+                    break;
+                case 'r':
+                    sb.append('\r');
+                    break;
+                case '\'':
+                    sb.append('\'');
+                    break;
+                case '\"':
+                    sb.append('\"');
+                    break;
+                case '\\':
+                    sb.append('\\');
+                    break;
+                case '\r': // CR | CRLF
+                    if (ch0 == '\n') {
+                        skip(1);
+                    }
+                    // fall through
+                case '\n': // LF
+                case '\u2028': // LS
+                case '\u2029': // PS
+                    // continue on the next line, slash-return continues string
+                    // literal
+                    break;
+                case 'x': {
+                    // Hex sequence.
+                    final int ch = valueOfSequence(16, 2, false, true, STRING);
+
+                    if (ch < 0) {
+                        sb.append('\\');
+                        sb.append('x');
+                    } else {
+                        sb.append((char)ch);
+                    }
+                }
+                    break;
+                case 'u': {
+                    // Unicode sequence.
+                    final int ch = valueOfSequence(16, 4, false, true, STRING);
+
+                    if (ch < 0) {
+                        sb.append('\\');
+                        sb.append('u');
+                    } else {
+                        sb.append((char)ch);
+                    }
+                }
+                    break;
+                case 'v':
+                    sb.append('\u000B');
+                    break;
+                // All other characters.
+                default:
+                    sb.append(next);
+                    break;
+                }
+            } else {
+                // Add regular character.
+                sb.append(ch0);
+                skip(1);
+            }
+        }
+
+        // Restore position.
+        reset(savePosition);
+
+        return sb.toString();
+    }
+
+    /**
+     * Scan over a string literal.
+     */
+    private void scanString(final boolean add) {
+        // Type of string.
+        TokenType type = STRING;
+        // Record starting quote.
+        final char quote = ch0;
+        // Skip over quote.
+        skip(1);
+
+        // Record beginning of string content.
+        final State stringState = saveState();
+
+        // Scan until close quote or end of line.
+        while (!atEOF() && ch0 != quote && !isEOL(ch0)) {
+            // Skip over escaped character.
+            if (ch0 == '\\') {
+                type = ESCSTRING;
+                skip(1);
+                if (isEOL(ch0)) {
+                    // Multiline string literal
+                    skipEOL(false);
+                    continue;
+                }
+            }
+            // Skip literal character.
+            skip(1);
+        }
+
+        // If close quote.
+        if (ch0 == quote) {
+            // Skip close quote.
+            skip(1);
+        } else {
+            error(Lexer.message("missing.close.quote"), STRING, position, limit);
+        }
+
+        // If not just scanning.
+        if (add) {
+            // Record end of string.
+            stringState.setLimit(position - 1);
+
+            if (scripting && !stringState.isEmpty()) {
+                switch (quote) {
+                case '`':
+                    // Mark the beginning of an exec string.
+                    add(EXECSTRING, stringState.position, stringState.limit);
+                    // Frame edit string with left brace.
+                    add(LBRACE, stringState.position, stringState.position);
+                    // Process edit string.
+                    editString(type, stringState);
+                    // Frame edit string with right brace.
+                    add(RBRACE, stringState.limit, stringState.limit);
+                    break;
+                case '"':
+                    // Only edit double quoted strings.
+                    editString(type, stringState);
+                    break;
+                case '\'':
+                    // Add string token without editing.
+                    add(type, stringState.position, stringState.limit);
+                    break;
+                default:
+                    break;
+                }
+            } else {
+                /// Add string token without editing.
+                add(type, stringState.position, stringState.limit);
+            }
+        }
+    }
+
+    /**
+     * Convert string to number.
+     *
+     * @param valueString  String to convert.
+     * @param radix        Numeric base.
+     * @return Converted number.
+     */
+    private static Number valueOf(final String valueString, final int radix) throws NumberFormatException {
+        try {
+            return Integer.valueOf(valueString, radix);
+        } catch (final NumberFormatException e) {
+            try {
+                return Long.valueOf(valueString, radix);
+            } catch (final NumberFormatException e2) {
+                if (radix == 10) {
+                    return Double.valueOf(valueString);
+                }
+
+                double value = 0.0;
+
+                for (int i = 0; i < valueString.length(); i++) {
+                    final char ch = valueString.charAt(i);
+                    // Preverified, should always be a valid digit.
+                    final int digit = convertDigit(ch, radix);
+                    value *= radix;
+                    value += digit;
+                }
+
+                return value;
+            }
+        }
+    }
+
+    /**
+     * Convert string to number.
+     *
+     * @param valueString String to convert.
+     * @return Converted number.
+     */
+    private static Number valueOf(final String valueString) throws NumberFormatException {
+        return JSType.narrowestIntegerRepresentation(Double.valueOf(valueString));
+    }
+
+    /**
+     * Scan a number.
+     */
+    private void scanNumber() {
+        // Record beginning of number.
+        final int start = position;
+        // Assume value is a decimal.
+        TokenType type = DECIMAL;
+
+        // First digit of number.
+        int digit = convertDigit(ch0, 10);
+
+        // If number begins with 0x.
+        if (digit == 0 && (ch1 == 'x' || ch1 == 'X') && convertDigit(ch2, 16) != -1) {
+            // Skip over 0xN.
+            skip(3);
+            // Skip over remaining digits.
+            while (convertDigit(ch0, 16) != -1) {
+                skip(1);
+            }
+
+            type = HEXADECIMAL;
+        } else {
+            // Check for possible octal constant.
+            boolean octal = digit == 0;
+            // Skip first digit if not leading '.'.
+            if (digit != -1) {
+                skip(1);
+            }
+
+            // Skip remaining digits.
+            while ((digit = convertDigit(ch0, 10)) != -1) {
+                // Check octal only digits.
+                octal = octal && digit < 8;
+                // Skip digit.
+                skip(1);
+            }
+
+            if (octal && position - start > 1) {
+                type = OCTAL;
+            } else if (ch0 == '.' || ch0 == 'E' || ch0 == 'e') {
+                // Must be a double.
+                if (ch0 == '.') {
+                    // Skip period.
+                    skip(1);
+                    // Skip mantissa.
+                    while (convertDigit(ch0, 10) != -1) {
+                        skip(1);
+                    }
+                }
+
+                // Detect exponent.
+                if (ch0 == 'E' || ch0 == 'e') {
+                    // Skip E.
+                    skip(1);
+                    // Detect and skip exponent sign.
+                    if (ch0 == '+' || ch0 == '-') {
+                        skip(1);
+                    }
+                    // Skip exponent.
+                    while (convertDigit(ch0, 10) != -1) {
+                        skip(1);
+                    }
+                }
+
+                type = FLOATING;
+            }
+        }
+
+        // Add number token.
+        add(type, start);
+    }
+
+    /**
+     * Convert a regex token to a token object.
+     *
+     * @param start  Position in source content.
+     * @param length Length of regex token.
+     * @return Regex token object.
+     */
+    XMLToken valueOfXML(final int start, final int length) {
+        return new XMLToken(source.getString(start, length));
+    }
+
+    /**
+     * Scan over a XML token.
+     *
+     * @return TRUE if is an XML literal.
+     */
+    private boolean scanXMLLiteral() {
+        assert ch0 == '<' && Character.isJavaIdentifierStart(ch1);
+        if (XML_LITERALS) {
+            // Record beginning of xml expression.
+            final int start = position;
+
+            int openCount = 0;
+
+            do {
+                if (ch0 == '<') {
+                    if (ch1 == '/' && Character.isJavaIdentifierStart(ch2)) {
+                        skip(3);
+                        openCount--;
+                    } else if (Character.isJavaIdentifierStart(ch1)) {
+                        skip(2);
+                        openCount++;
+                    } else if (ch1 == '?') {
+                        skip(2);
+                    } else if (ch1 == '!' && ch2 == '-' && ch3 == '-') {
+                        skip(4);
+                    } else {
+                        reset(start);
+                        return false;
+                    }
+
+                    while (!atEOF() && ch0 != '>') {
+                        if (ch0 == '/' && ch1 == '>') {
+                            openCount--;
+                            skip(1);
+                            break;
+                        } else if (ch0 == '\"' || ch0 == '\'') {
+                            scanString(false);
+                        } else {
+                            skip(1);
+                        }
+                    }
+
+                    if (ch0 != '>') {
+                        reset(start);
+                        return false;
+                    }
+
+                    skip(1);
+                } else if (atEOF()) {
+                    reset(start);
+                    return false;
+                } else {
+                    skip(1);
+                }
+            } while (openCount > 0);
+
+            add(XML, start);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Scan over identifier characters.
+     *
+     * @return Length of identifier or zero if none found.
+     */
+    private int scanIdentifier() {
+        final int start = position;
+
+        // Make sure first character is valid start character.
+        if (ch0 == '\\' && ch1 == 'u') {
+            final int ch = valueOfSequence(16, 4, true, true, TokenType.IDENT);
+
+            if (!Character.isJavaIdentifierStart(ch)) {
+                error(Lexer.message("illegal.identifier.character"), TokenType.IDENT, start, position);
+            }
+        } else if (!Character.isJavaIdentifierStart(ch0)) {
+            // Not an identifier.
+            return 0;
+        }
+
+        // Make sure remaining characters are valid part characters.
+        while (!atEOF()) {
+            if (ch0 == '\\' && ch1 == 'u') {
+                final int ch = valueOfSequence(16, 4, true, true, TokenType.IDENT);
+
+                if (!Character.isJavaIdentifierPart(ch)) {
+                    error(Lexer.message("illegal.identifier.character"), TokenType.IDENT, start, position);
+                }
+            } else if (Character.isJavaIdentifierPart(ch0)) {
+                skip(1);
+            } else {
+                break;
+            }
+        }
+
+        // Length of identifier sequence.
+        return position - start;
+    }
+
+    /**
+     * Compare two identifiers (in content) for equality.
+     *
+     * @param aStart  Start of first identifier.
+     * @param aLength Length of first identifier.
+     * @param bStart  Start of second identifier.
+     * @param bLength Length of second identifier.
+     * @return True if equal.
+     */
+    private boolean identifierEqual(final int aStart, final int aLength, final int bStart, final int bLength) {
+        if (aLength == bLength) {
+            for (int i = 0; i < aLength; i++) {
+                if (content[aStart + i] != content[bStart + i]) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Detect if a line starts with a marker identifier.
+     *
+     * @param identStart  Start of identifier.
+     * @param identLength Length of identifier.
+     * @return True if detected.
+     */
+    private boolean hasHereMarker(final int identStart, final int identLength) {
+        // Skip any whitespace.
+        skipWhitespace(false);
+
+        return identifierEqual(identStart, identLength, position, scanIdentifier());
+    }
+
+    /**
+     * Lexer to service edit strings.
+     */
+    private static class EditStringLexer extends Lexer {
+        /** Type of string literals to emit. */
+        final TokenType stringType;
+
+        /*
+         * Constructor.
+         */
+
+        EditStringLexer(final Lexer lexer, final TokenType stringType, final State stringState) {
+            super(lexer, stringState);
+
+            this.stringType = stringType;
+        }
+
+        /**
+         * Lexify the contents of the string.
+         */
+        @Override
+        public void lexify() {
+            // Record start of string position.
+            int stringStart = position;
+            // Indicate that the priming first string has not been emitted.
+            boolean primed = false;
+
+            while (true) {
+                // Detect end of content.
+                if (atEOF()) {
+                    break;
+                }
+
+                // Honour escapes (should be well formed.)
+                if (ch0 == '\\' && stringType == ESCSTRING) {
+                    skip(2);
+
+                    continue;
+                }
+
+                // If start of expression.
+                if (ch0 == '$' && ch1 == '{') {
+                    if (!primed || stringStart != position) {
+                        if (primed) {
+                            add(ADD, stringStart, stringStart + 1);
+                        }
+
+                        add(stringType, stringStart, position);
+                        primed = true;
+                    }
+
+                    // Skip ${
+                    skip(2);
+
+                    // Save expression state.
+                    final State expressionState = saveState();
+
+                    // Start with one open brace.
+                    int braceCount = 1;
+
+                    // Scan for the rest of the string.
+                    while (!atEOF()) {
+                        // If closing brace.
+                        if (ch0 == '}') {
+                            // Break only only if matching brace.
+                            if (--braceCount == 0) {
+                                break;
+                            }
+                        } else if (ch0 == '{') {
+                            // Bump up the brace count.
+                            braceCount++;
+                        }
+
+                        // Skip to next character.
+                        skip(1);
+                    }
+
+                    // If braces don't match then report an error.
+                    if (braceCount != 0) {
+                        error(Lexer.message("edit.string.missing.brace"), LBRACE, expressionState.position - 1, 1);
+                    }
+
+                    // Mark end of expression.
+                    expressionState.setLimit(position);
+                    // Skip closing brace.
+                    skip(1);
+
+                    // Start next string.
+                    stringStart = position;
+
+                    // Concatenate expression.
+                    add(ADD, expressionState.position, expressionState.position + 1);
+                    add(LPAREN, expressionState.position, expressionState.position + 1);
+
+                    // Scan expression.
+                    final Lexer lexer = new Lexer(this, expressionState);
+                    lexer.lexify();
+
+                    // Close out expression parenthesis.
+                    add(RPAREN, position - 1, position);
+
+                    continue;
+                }
+
+                // Next character in string.
+                skip(1);
+            }
+
+            // If there is any unemitted string portion.
+            if (stringStart != limit) {
+                // Concatenate remaining string.
+                if (primed) {
+                    add(ADD, stringStart, 1);
+                }
+
+                add(stringType, stringStart, limit);
+            }
+        }
+
+    }
+
+    /**
+     * Edit string for nested expressions.
+     *
+     * @param stringType  Type of string literals to emit.
+     * @param stringState State of lexer at start of string.
+     */
+    private void editString(final TokenType stringType, final State stringState) {
+        // Use special lexer to scan string.
+        final EditStringLexer lexer = new EditStringLexer(this, stringType, stringState);
+        lexer.lexify();
+
+        // Need to keep lexer informed.
+        last = stringType;
+    }
+
+    /**
+     * Scan over a here string.
+     *
+     * @return TRUE if is a here string.
+     */
+    private boolean scanHereString() {
+        assert ch0 == '<' && ch1 == '<';
+        if (scripting) {
+            // Record beginning of here string.
+            final State saved = saveState();
+
+            // << or <<<
+            final boolean excludeLastEOL = ch2 != '<';
+
+            if (excludeLastEOL) {
+                skip(2);
+            } else {
+                skip(3);
+            }
+
+            // Scan identifier.
+            final int identStart = position;
+            final int identLength = scanIdentifier();
+
+            // Check for identifier.
+            if (identLength == 0) {
+                // Treat as shift.
+                restoreState(saved);
+
+                return false;
+            }
+
+            // Record rest of line.
+            final State restState = saveState();
+            skipLine(false);
+            restState.setLimit(position);
+
+            // Record beginning of string.
+            final State stringState = saveState();
+            int stringEnd = position;
+
+            // Hunt down marker.
+            while (!atEOF()) {
+                // Skip any whitespace.
+                skipWhitespace(false);
+
+                if (hasHereMarker(identStart, identLength)) {
+                    break;
+                }
+
+                skipLine(false);
+                stringEnd = position;
+            }
+
+            // Record end of string.
+            stringState.setLimit(stringEnd);
+
+            // If marker is missing.
+            if (stringState.isEmpty() || atEOF()) {
+                error(Lexer.message("here.missing.end.marker", source.getString(identStart, identLength)), last, position, position);
+                restoreState(saved);
+
+                return false;
+            }
+
+            // Remove last end of line if specified.
+            if (excludeLastEOL) {
+                // Handles \n.
+                if (content[stringEnd - 1] == '\n') {
+                    stringEnd--;
+                }
+
+                // Handles \r and \r\n.
+                if (content[stringEnd - 1] == '\r') {
+                    stringEnd--;
+                }
+
+                // Update end of string.
+                stringState.setLimit(stringEnd);
+            }
+
+            // Edit string if appropriate.
+            if (scripting && !stringState.isEmpty()) {
+                editString(STRING, stringState);
+            } else {
+                // Add here string.
+                add(STRING, stringState.position, stringState.limit);
+            }
+
+            // Scan rest of original line.
+            final Lexer restLexer = new Lexer(this, restState);
+
+            restLexer.lexify();
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Breaks source content down into lex units, adding tokens to the token
+     * stream. The routine scans until the stream buffer is full. Can be called
+     * repeatedly until EOF is detected.
+     */
+    public void lexify() {
+        while (!stream.isFull() || nested) {
+            // Skip over whitespace.
+            skipWhitespace(true);
+
+            // Detect end of file.
+            if (atEOF()) {
+                if (!nested) {
+                    // Add an EOF token at the end.
+                    add(EOF, position);
+                }
+
+                break;
+            }
+
+            // Check for comments. Note that we don't scan for regexp and other literals here as
+            // we may not have enough context to distinguish them from similar looking operators.
+            // Instead we break on ambiguous operators below and let the parser decide.
+            if (ch0 == '/' && skipComments()) {
+                continue;
+            }
+
+            if (scripting && ch0 == '#' && skipComments()) {
+                continue;
+            }
+
+            // TokenType for lookup of delimiter or operator.
+            TokenType type;
+
+            if (ch0 == '.' && convertDigit(ch1, 10) != -1) {
+                // '.' followed by digit.
+                // Scan and add a number.
+                scanNumber();
+            } else if ((type = TokenLookup.lookupOperator(ch0, ch1, ch2, ch3)) != null) {
+                // Get the number of characters in the token.
+                final int typeLength = type.getLength();
+                // Skip that many characters.
+                skip(typeLength);
+                // Add operator token.
+                add(type, position - typeLength);
+                // Some operator tokens also mark the beginning of regexp, XML, or here string literals.
+                // We break to let the parser decide what it is.
+                if (canStartLiteral(type)) {
+                    break;
+                }
+            } else if (Character.isJavaIdentifierStart(ch0) || ch0 == '\\' && ch1 == 'u') {
+                // Scan and add identifier or keyword.
+                scanIdentifierOrKeyword();
+            } else if (isStringDelimiter(ch0)) {
+                // Scan and add a string.
+                scanString(true);
+            } else if (Character.isDigit(ch0)) {
+                // Scan and add a number.
+                scanNumber();
+            } else {
+                // Don't recognize this character.
+                skip(1);
+                add(ERROR, position - 1);
+            }
+        }
+    }
+
+    /**
+     * Return value of token given its token descriptor.
+     *
+     * @param token  Token descriptor.
+     * @return JavaScript value.
+     */
+    Object getValueOf(final long token, final boolean strict) {
+        final int start = Token.descPosition(token);
+        final int len = Token.descLength(token);
+
+        switch (Token.descType(token)) {
+        case DECIMAL:
+            return Lexer.valueOf(source.getString(start, len), 10); // number
+        case OCTAL:
+            return Lexer.valueOf(source.getString(start, len), 8); // number
+        case HEXADECIMAL:
+            return Lexer.valueOf(source.getString(start + 2, len - 2), 16); // number
+        case FLOATING:
+            return Lexer.valueOf(source.getString(start, len)); // number
+        case STRING:
+            return source.getString(start, len); // String
+        case ESCSTRING:
+            return valueOfString(start, len, strict); // String
+        case IDENT:
+            return valueOfIdent(start, len); // String
+        case REGEX:
+            return valueOfPattern(start, len); // RegexToken::LexerToken
+        case XML:
+            return valueOfXML(start, len); // XMLToken::LexerToken
+        default:
+            break;
+        }
+
+        return null;
+    }
+
+    private static String message(final String msgId, final String... args) {
+        return ECMAErrors.getMessage("lexer.error." + msgId, args);
+    }
+
+    /**
+     * Generate a runtime exception
+     *
+     * @param message       error message
+     * @param type          token type
+     * @param start         start position of lexed error
+     * @param length        length of lexed error
+     * @throws ParserException  unconditionally
+     */
+    protected void error(final String message, final TokenType type, final int start, final int length) throws ParserException {
+        final long token     = Token.toDesc(type, start, length);
+        final int  pos       = Token.descPosition(token);
+        final int  lineNum   = source.getLine(pos);
+        final int  columnNum = source.getColumn(pos);
+        final String formatted = ErrorManager.format(message, source, lineNum, columnNum, token);
+        throw new ParserException(JSErrorType.SYNTAX_ERROR, formatted, source, lineNum, columnNum, token);
+    }
+
+    /**
+     * Helper class for Lexer tokens, e.g XML or RegExp tokens.
+     * This is the abstract superclass
+     */
+    public static abstract class LexerToken {
+        private final String expression;
+
+        /**
+         * Constructor
+         * @param expression token expression
+         */
+        protected LexerToken(final String expression) {
+            this.expression = expression;
+        }
+
+        /**
+         * Get the expression
+         * @return expression
+         */
+        public String getExpression() {
+            return expression;
+        }
+    }
+
+    /**
+     * Temporary container for regular expressions.
+     */
+    public static class RegexToken extends LexerToken {
+        /** Options. */
+        private final String options;
+
+        /**
+         * Constructor.
+         *
+         * @param expression  regexp expression
+         * @param options     regexp options
+         */
+        public RegexToken(final String expression, final String options) {
+            super(expression);
+            this.options = options;
+        }
+
+        /**
+         * Get regexp options
+         * @return options
+         */
+        public String getOptions() {
+            return options;
+        }
+
+        @Override
+        public String toString() {
+            return '/' + getExpression() + '/' + options;
+        }
+    }
+
+    /**
+     * Temporary container for XML expression.
+     */
+    public static class XMLToken extends LexerToken {
+
+        /**
+         * Constructor.
+         *
+         * @param expression  XML expression
+         */
+        public XMLToken(final String expression) {
+            super(expression);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
new file mode 100644
index 0000000..41149e4
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
@@ -0,0 +1,3086 @@
+/*
+ * 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.parser;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
+import static jdk.nashorn.internal.codegen.CompilerConstants.FUNCTION_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT;
+import static jdk.nashorn.internal.parser.TokenType.ASSIGN;
+import static jdk.nashorn.internal.parser.TokenType.CASE;
+import static jdk.nashorn.internal.parser.TokenType.CATCH;
+import static jdk.nashorn.internal.parser.TokenType.COLON;
+import static jdk.nashorn.internal.parser.TokenType.COMMARIGHT;
+import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
+import static jdk.nashorn.internal.parser.TokenType.DECPREFIX;
+import static jdk.nashorn.internal.parser.TokenType.ELSE;
+import static jdk.nashorn.internal.parser.TokenType.EOF;
+import static jdk.nashorn.internal.parser.TokenType.EOL;
+import static jdk.nashorn.internal.parser.TokenType.FINALLY;
+import static jdk.nashorn.internal.parser.TokenType.FUNCTION;
+import static jdk.nashorn.internal.parser.TokenType.IDENT;
+import static jdk.nashorn.internal.parser.TokenType.IF;
+import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
+import static jdk.nashorn.internal.parser.TokenType.LBRACE;
+import static jdk.nashorn.internal.parser.TokenType.LPAREN;
+import static jdk.nashorn.internal.parser.TokenType.RBRACE;
+import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
+import static jdk.nashorn.internal.parser.TokenType.RPAREN;
+import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
+import static jdk.nashorn.internal.parser.TokenType.TERNARY;
+import static jdk.nashorn.internal.parser.TokenType.WHILE;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import jdk.nashorn.internal.codegen.CompilerConstants;
+import jdk.nashorn.internal.codegen.Namespace;
+import jdk.nashorn.internal.ir.AccessNode;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.Block;
+import jdk.nashorn.internal.ir.BreakNode;
+import jdk.nashorn.internal.ir.BreakableNode;
+import jdk.nashorn.internal.ir.CallNode;
+import jdk.nashorn.internal.ir.CaseNode;
+import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ContinueNode;
+import jdk.nashorn.internal.ir.DoWhileNode;
+import jdk.nashorn.internal.ir.EmptyNode;
+import jdk.nashorn.internal.ir.ExecuteNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.IndexNode;
+import jdk.nashorn.internal.ir.LabelNode;
+import jdk.nashorn.internal.ir.LineNumberNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
+import jdk.nashorn.internal.ir.PropertyKey;
+import jdk.nashorn.internal.ir.PropertyNode;
+import jdk.nashorn.internal.ir.ReferenceNode;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.SwitchNode;
+import jdk.nashorn.internal.ir.TernaryNode;
+import jdk.nashorn.internal.ir.ThrowNode;
+import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.WhileNode;
+import jdk.nashorn.internal.ir.WithNode;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.JSErrorType;
+import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptingFunctions;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.Timing;
+
+/**
+ * Builds the IR.
+ */
+public class Parser extends AbstractParser {
+    /** Current script environment. */
+    private final ScriptEnvironment env;
+
+    /** Is scripting mode. */
+    private final boolean scripting;
+
+    /** Top level script being parsed. */
+    private FunctionNode script;
+
+    /** Current function being parsed. */
+    private FunctionNode function;
+
+    /** Current parsing block. */
+    private Block block;
+
+    /** Namespace for function names where not explicitly given */
+    private final Namespace namespace;
+
+    private static DebugLogger LOG = new DebugLogger("parser");
+
+    /**
+     * Constructor
+     *
+     * @param env     script environment
+     * @param source  source to parse
+     * @param errors  error manager
+     */
+    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors) {
+        this(env, source, errors, env._strict);
+    }
+
+    /**
+     * Construct a parser.
+     *
+     * @param env     script environment
+     * @param source  source to parse
+     * @param errors  error manager
+     * @param strict  parser created with strict mode enabled.
+     */
+    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict) {
+        super(source, errors, strict);
+        this.env   = env;
+        this.namespace = new Namespace(env.getNamespace());
+        this.scripting = env._scripting;
+    }
+
+    /**
+     * Execute parse and return the resulting function node.
+     * Errors will be thrown and the error manager will contain information
+     * if parsing should fail
+     *
+     * This is the default parse call, which will name the function node
+     * "runScript" {@link CompilerConstants#RUN_SCRIPT}
+     *
+     * @return function node resulting from successful parse
+     */
+    public FunctionNode parse() {
+        return parse(RUN_SCRIPT.tag());
+    }
+
+    /**
+     * Execute parse and return the resulting function node.
+     * Errors will be thrown and the error manager will contain information
+     * if parsing should fail
+     *
+     * @param scriptName name for the script, given to the parsed FunctionNode
+     *
+     * @return function node resulting from successful parse
+     */
+    public FunctionNode parse(final String scriptName) {
+        final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
+        LOG.info(this + " begin for '" + scriptName + "'");
+
+        try {
+            stream = new TokenStream();
+            lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
+
+            // Set up first token (skips opening EOL.)
+            k = -1;
+            next();
+
+            // Begin parse.
+            return program(scriptName);
+        } catch (final Exception e) {
+            // Extract message from exception.  The message will be in error
+            // message format.
+            String message = e.getMessage();
+
+            // If empty message.
+            if (message == null) {
+                message = e.toString();
+            }
+
+            // Issue message.
+            if (e instanceof ParserException) {
+                errors.error((ParserException)e);
+            } else {
+                errors.error(message);
+            }
+
+            if (env._dump_on_error) {
+                e.printStackTrace(env.getErr());
+            }
+
+            return null;
+         } finally {
+             final String end = this + " end '" + scriptName + "'";
+             if (Timing.isEnabled()) {
+                 Timing.accumulateTime(toString(), System.currentTimeMillis() - t0);
+                 LOG.info(end + "' in " + (System.currentTimeMillis() - t0) + " ms");
+             } else {
+                 LOG.info(end);
+             }
+         }
+    }
+
+    /**
+     * Skip to a good parsing recovery point.
+     */
+    private void recover(final Exception e) {
+        if (e != null) {
+            // Extract message from exception.  The message will be in error
+            // message format.
+            String message = e.getMessage();
+
+            // If empty message.
+            if (message == null) {
+                message = e.toString();
+            }
+
+            // Issue message.
+            if (e instanceof ParserException) {
+                errors.error((ParserException)e);
+            } else {
+                errors.error(message);
+            }
+
+            if (env._dump_on_error) {
+                e.printStackTrace(env.getErr());
+            }
+        }
+
+        // Skip to a recovery point.
+loop:
+        while (true) {
+            switch (type) {
+            case EOF:
+                // Can not go any further.
+                break loop;
+            case EOL:
+            case SEMICOLON:
+            case RBRACE:
+                // Good recovery points.
+                next();
+                break loop;
+            default:
+                // So we can recover after EOL.
+                nextOrEOL();
+                break;
+            }
+        }
+    }
+
+    /**
+     * Set up a new block.
+     *
+     * @return New block.
+     */
+    private Block newBlock() {
+        return block = new Block(source, token, Token.descPosition(token), block, function);
+    }
+
+    /**
+     * Set up a new function block.
+     *
+     * @param ident Name of function.
+     * @return New block.
+     */
+    private FunctionNode newFunctionBlock(final IdentNode ident) {
+        // Build function name.
+        final StringBuilder sb = new StringBuilder();
+
+        if (block != null) {
+            block.addParentName(sb);
+        }
+
+        sb.append(ident != null ? ident.getName() : FUNCTION_PREFIX.tag());
+        final String name = namespace.uniqueName(sb.toString());
+        assert function != null || name.equals(RUN_SCRIPT.tag())  : "name = " + name;// must not rename runScript().
+
+        // Start new block.
+        final FunctionNode functionBlock = new FunctionNode(source, token, Token.descPosition(token), namespace, block, ident, name);
+        block = function = functionBlock;
+        function.setStrictMode(isStrictMode);
+
+        return functionBlock;
+    }
+
+    /**
+     * Restore the current block.
+     */
+    private void restoreBlock() {
+        block = block.getParent();
+        function = block.getFunction();
+    }
+
+    /**
+     * Get the statements in a block.
+     * @return Block statements.
+     */
+    private Block getBlock(final boolean needsBraces) {
+        // Set up new block. Captures LBRACE.
+        final Block newBlock = newBlock();
+        pushControlNode(newBlock);
+
+        // Block opening brace.
+        if (needsBraces) {
+            expect(LBRACE);
+        }
+
+        try {
+            // Accumulate block statements.
+            statementList();
+        } finally {
+            restoreBlock();
+            popControlNode();
+        }
+
+    final int possibleEnd = Token.descPosition(token) + Token.descLength(token);
+
+        // Block closing brace.
+        if (needsBraces) {
+            expect(RBRACE);
+        }
+
+        newBlock.setFinish(possibleEnd);
+
+        return newBlock;
+    }
+
+    /**
+     * Get all the statements generated by a single statement.
+     * @return Statements.
+     */
+    private Block getStatement() {
+        if (type == LBRACE) {
+            return getBlock(true);
+        }
+        // Set up new block. Captures first token.
+        final Block newBlock = newBlock();
+
+        try {
+            // Accumulate statements.
+            statement();
+        } finally {
+            restoreBlock();
+        }
+
+        return newBlock;
+    }
+
+    /**
+     * Detect calls to special functions.
+     * @param ident Called function.
+     */
+    private void detectSpecialFunction(final IdentNode ident) {
+        final String name = ident.getName();
+
+        if (EVAL.tag().equals(name)) {
+            function.setHasEval();
+        }
+    }
+
+    /**
+     * Detect use of special properties.
+     * @param ident Referenced property.
+     */
+    private void detectSpecialProperty(final IdentNode ident) {
+        final String name = ident.getName();
+
+        if (ARGUMENTS.tag().equals(name)) {
+            function.setUsesArguments();
+        }
+    }
+
+    /**
+     * Tells whether a IdentNode can be used as L-value of an assignment
+     *
+     * @param ident IdentNode to be checked
+     * @return whether the ident can be used as L-value
+     */
+    private static boolean checkIdentLValue(final IdentNode ident) {
+        return Token.descType(ident.getToken()).getKind() != TokenKind.KEYWORD;
+    }
+
+    /**
+     * Verify an assignment expression.
+     * @param op  Operation token.
+     * @param lhs Left hand side expression.
+     * @param rhs Right hand side expression.
+     * @return Verified expression.
+     */
+    private Node verifyAssignment(final long op, final Node lhs, final Node rhs) {
+        final TokenType opType = Token.descType(op);
+
+        switch (opType) {
+        case ASSIGN:
+        case ASSIGN_ADD:
+        case ASSIGN_BIT_AND:
+        case ASSIGN_BIT_OR:
+        case ASSIGN_BIT_XOR:
+        case ASSIGN_DIV:
+        case ASSIGN_MOD:
+        case ASSIGN_MUL:
+        case ASSIGN_SAR:
+        case ASSIGN_SHL:
+        case ASSIGN_SHR:
+        case ASSIGN_SUB:
+            if (!(lhs instanceof AccessNode ||
+                  lhs instanceof IndexNode ||
+                  lhs instanceof IdentNode)) {
+                if (env._early_lvalue_error) {
+                    error(JSErrorType.REFERENCE_ERROR, AbstractParser.message("invalid.lvalue"), lhs.getToken());
+                }
+                return referenceError(lhs, rhs);
+            }
+
+            if (lhs instanceof IdentNode) {
+                if (! checkIdentLValue((IdentNode)lhs)) {
+                    return referenceError(lhs, rhs);
+                }
+                verifyStrictIdent((IdentNode)lhs, "assignment");
+            }
+            break;
+
+        default:
+            break;
+        }
+
+        // Build up node.
+        return new BinaryNode(source, op, lhs, rhs);
+    }
+
+    /**
+     * Reduce increment/decrement to simpler operations.
+     * @param firstToken First token.
+     * @param tokenType  Operation token (INCPREFIX/DEC.)
+     * @param expression Left hand side expression.
+     * @param isPostfix  Prefix or postfix.
+     * @return           Reduced expression.
+     */
+    private Node incDecExpression(final long firstToken, final TokenType tokenType, final Node expression, final boolean isPostfix) {
+        long incDecToken = firstToken;
+        if (isPostfix) {
+            incDecToken = Token.recast(incDecToken, tokenType == DECPREFIX ? DECPOSTFIX : INCPOSTFIX);
+        }
+
+        final UnaryNode node = new UnaryNode(source, incDecToken, expression);
+        if (isPostfix) {
+            node.setStart(expression.getStart());
+            node.setFinish(Token.descPosition(incDecToken) + Token.descLength(incDecToken));
+        }
+
+        return node;
+    }
+
+    /**
+     * Find a label node in the label stack.
+     * @param ident Ident to find.
+     * @return null or the found label node.
+     */
+    private LabelNode findLabel(final IdentNode ident) {
+        for (final LabelNode labelNode : function.getLabelStack()) {
+            if (labelNode.getLabel().equals(ident)) {
+                return labelNode;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Add a label to the label stack.
+     * @param labelNode Label to add.
+     */
+    private void pushLabel(final LabelNode labelNode) {
+        function.getLabelStack().push(labelNode);
+    }
+
+    /**
+      * Remove a label from the label stack.
+      */
+    private void popLabel() {
+        function.getLabelStack().pop();
+    }
+
+    /**
+     * Track the current nesting of controls for break and continue.
+     * @param node For, while, do or switch node.
+     */
+    private void pushControlNode(final Node node) {
+        final boolean isLoop = node instanceof WhileNode;
+        final boolean isBreakable = node instanceof BreakableNode || node instanceof Block;
+        function.getControlStack().push(node);
+
+        for (final LabelNode labelNode : function.getLabelStack()) {
+            if (isBreakable && labelNode.getBreakNode() == null) {
+                labelNode.setBreakNode(node);
+            }
+
+            if (isLoop && labelNode.getContinueNode() == null) {
+                labelNode.setContinueNode(node);
+            }
+        }
+    }
+
+    /**
+     * Finish with control.
+     */
+    private void popControlNode() {
+        // Get control stack.
+        final Stack<Node> controlStack = function.getControlStack();
+
+        // Can be empty if missing brace.
+        if (!controlStack.isEmpty()) {
+            controlStack.pop();
+        }
+    }
+
+    private void popControlNode(final Node node) {
+        // Get control stack.
+        final Stack<Node> controlStack = function.getControlStack();
+
+        // Can be empty if missing brace.
+        if (!controlStack.isEmpty() && controlStack.peek() == node) {
+            controlStack.pop();
+        }
+    }
+
+    private boolean isInWithBlock() {
+        final Stack<Node> controlStack = function.getControlStack();
+        for (int i = controlStack.size() - 1; i >= 0; i--) {
+            final Node node = controlStack.get(i);
+
+            if (node instanceof WithNode) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private <T extends Node> T findControl(final Class<T> ctype) {
+        final Stack<Node> controlStack = function.getControlStack();
+        for (int i = controlStack.size() - 1; i >= 0; i--) {
+            final Node node = controlStack.get(i);
+
+            if (ctype.isAssignableFrom(node.getClass())) {
+                return ctype.cast(node);
+            }
+        }
+
+        return null;
+    }
+
+    private <T extends Node> List<T> findControls(final Class<T> ctype, final Node to) {
+        final List<T> nodes = new ArrayList<>();
+        final Stack<Node> controlStack = function.getControlStack();
+        for (int i = controlStack.size() - 1; i >= 0; i--) {
+            final Node node = controlStack.get(i);
+
+            if (to == node) {
+                break; //stop looking
+            }
+
+            if (ctype.isAssignableFrom(node.getClass())) {
+                nodes.add(ctype.cast(node));
+            }
+        }
+
+        return nodes;
+    }
+
+    private <T extends Node> int countControls(final Class<T> ctype, final Node to) {
+        return findControls(ctype, to).size();
+    }
+
+
+    /**
+     * -----------------------------------------------------------------------
+     *
+     * Grammar based on
+     *
+     *      ECMAScript Language Specification
+     *      ECMA-262 5th Edition / December 2009
+     *
+     * -----------------------------------------------------------------------
+     */
+
+    /**
+     * Program :
+     *      SourceElements?
+     *
+     * See 14
+     *
+     * Parse the top level script.
+     */
+    private FunctionNode program(final String scriptName) {
+        // Make a fake token for the script.
+        final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
+        // Set up the script to append elements.
+        script = newFunctionBlock(new IdentNode(source, functionToken, Token.descPosition(functionToken), scriptName));
+        // set kind to be SCRIPT
+        script.setKind(FunctionNode.Kind.SCRIPT);
+        // Set the first token of the script.
+        script.setFirstToken(functionToken);
+        // Gather source elements.
+        sourceElements();
+        expect(EOF);
+        // Set the last token of the script.
+        script.setLastToken(token);
+        script.setFinish(source.getLength() - 1);
+
+        return script;
+    }
+
+    /**
+     * Directive value or null if statement is not a directive.
+     *
+     * @param stmt Statement to be checked
+     * @return Directive value if the given statement is a directive
+     */
+    private String getDirective(final Node stmt) {
+        if (stmt instanceof ExecuteNode) {
+            final Node expr = ((ExecuteNode)stmt).getExpression();
+            if (expr instanceof LiteralNode) {
+                final LiteralNode<?> lit = (LiteralNode<?>)expr;
+                final long litToken = lit.getToken();
+                final TokenType tt = Token.descType(litToken);
+                // A directive is either a string or an escape string
+                if (tt == TokenType.STRING || tt == TokenType.ESCSTRING) {
+                    // Make sure that we don't unescape anything. Return as seen in source!
+                    return source.getString(lit.getStart(), Token.descLength(litToken));
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Return last node in a statement list.
+     *
+     * @param statements Statement list.
+     *
+     * @return Last (non-debug) statement or null if empty block.
+     */
+    private static Node lastStatement(final List<Node> statements) {
+        for (int lastIndex = statements.size() - 1; lastIndex >= 0; lastIndex--) {
+            final Node node = statements.get(lastIndex);
+            if (!node.isDebug()) {
+                return node;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * SourceElements :
+     *      SourceElement
+     *      SourceElements SourceElement
+     *
+     * See 14
+     *
+     * Parse the elements of the script or function.
+     */
+    private void sourceElements() {
+        List<Node>    directiveStmts = null;
+        boolean       checkDirective = true;
+        final boolean oldStrictMode = isStrictMode;
+
+        try {
+            // If is a script, then process until the end of the script.
+            while (type != EOF) {
+                // Break if the end of a code block.
+                if (type == RBRACE) {
+                    break;
+                }
+
+                try {
+                    // Get the next element.
+                    statement(true);
+
+                    // check for directive prologues
+                    if (checkDirective) {
+                        // skip any debug statement like line number to get actual first line
+                        final Node lastStatement = lastStatement(block.getStatements());
+
+                        // get directive prologue, if any
+                        final String directive = getDirective(lastStatement);
+
+                        // If we have seen first non-directive statement,
+                        // no more directive statements!!
+                        checkDirective = directive != null;
+
+                        if (checkDirective) {
+                            if (!oldStrictMode) {
+                                if (directiveStmts == null) {
+                                    directiveStmts = new ArrayList<>();
+                                }
+                                directiveStmts.add(lastStatement);
+                            }
+
+                            // handle use strict directive
+                            if ("use strict".equals(directive)) {
+                                isStrictMode = true;
+                                function.setStrictMode(true);
+
+                                // We don't need to check these, if lexical environment is already strict
+                                if (!oldStrictMode && directiveStmts != null) {
+                                    // check that directives preceding this one do not violate strictness
+                                    for (final Node statement : directiveStmts) {
+                                        // the get value will force unescape of preceeding
+                                        // escaped string directives
+                                        getValue(statement.getToken());
+                                    }
+
+                                    // verify that function name as well as parameter names
+                                    // satisfy strict mode restrictions.
+                                    verifyStrictIdent(function.getIdent(), "function name");
+                                    for (final IdentNode param : function.getParameters()) {
+                                        verifyStrictIdent(param, "function parameter");
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } catch (final Exception e) {
+                    // Recover parsing.
+                    recover(e);
+                }
+
+                // No backtracking from here on.
+                stream.commit(k);
+            }
+        } finally {
+            isStrictMode = oldStrictMode;
+        }
+    }
+
+    /**
+     * Statement :
+     *      Block
+     *      VariableStatement
+     *      EmptyStatement
+     *      ExpressionStatement
+     *      IfStatement
+     *      IterationStatement
+     *      ContinueStatement
+     *      BreakStatement
+     *      ReturnStatement
+     *      WithStatement
+     *      LabelledStatement
+     *      SwitchStatement
+     *      ThrowStatement
+     *      TryStatement
+     *      DebuggerStatement
+     *
+     * see 12
+     *
+     * Parse any of the basic statement types.
+     */
+    private void statement() {
+        statement(false);
+    }
+
+    /**
+     * @param topLevel does this statement occur at the "top level" of a script or a function?
+     */
+    private void statement(final boolean topLevel) {
+        final LineNumberNode lineNumberNode = lineNumber();
+
+        if (type == FUNCTION) {
+            // As per spec (ECMA section 12), function declarations as arbitrary statement
+            // is not "portable". Implementation can issue a warning or disallow the same.
+            if (isStrictMode && !topLevel) {
+                error(AbstractParser.message("strict.no.func.here"), token);
+            }
+            functionExpression(true);
+            return;
+        }
+
+        block.addStatement(lineNumberNode);
+
+        switch (type) {
+        case LBRACE:
+            block();
+            break;
+        case RBRACE:
+            break;
+        case VAR:
+            variableStatement(true);
+            break;
+        case SEMICOLON:
+            emptyStatement();
+            break;
+        case IF:
+            ifStatement();
+            break;
+        case FOR:
+            forStatement();
+            break;
+        case WHILE:
+            whileStatement();
+            break;
+        case DO:
+            doStatement();
+            break;
+        case CONTINUE:
+            continueStatement();
+            break;
+        case BREAK:
+            breakStatement();
+            break;
+        case RETURN:
+            returnStatement();
+            break;
+        case YIELD:
+            yieldStatement();
+            break;
+        case WITH:
+            withStatement();
+            break;
+        case SWITCH:
+            switchStatement();
+            break;
+        case THROW:
+            throwStatement();
+            break;
+        case TRY:
+            tryStatement();
+            break;
+        case DEBUGGER:
+            debuggerStatement();
+            break;
+        case RPAREN:
+        case RBRACKET:
+        case EOF:
+            expect(SEMICOLON);
+            break;
+        default:
+            if (type == IDENT || isNonStrictModeIdent()) {
+                if (T(k + 1) == COLON) {
+                    labelStatement();
+                    return;
+                }
+            }
+
+            expressionStatement();
+            break;
+        }
+    }
+
+    /**
+     * block :
+     *      { StatementList? }
+     *
+     * see 12.1
+     *
+     * Parse a statement block.
+     */
+    private void block() {
+        // Get statements in block.
+        final Block newBlock = getBlock(true);
+
+        // Force block execution.
+        final ExecuteNode executeNode = new ExecuteNode(source, newBlock.getToken(), finish, newBlock);
+
+        block.addStatement(executeNode);
+    }
+
+    /**
+     * StatementList :
+     *      Statement
+     *      StatementList Statement
+     *
+     * See 12.1
+     *
+     * Parse a list of statements.
+     */
+    private void statementList() {
+        // Accumulate statements until end of list. */
+loop:
+        while (type != EOF) {
+            switch (type) {
+            case EOF:
+            case CASE:
+            case DEFAULT:
+            case RBRACE:
+                break loop;
+            default:
+                break;
+            }
+
+            // Get next statement.
+            statement();
+        }
+    }
+
+    /**
+     * Make sure that in strict mode, the identifier name used is allowed.
+     *
+     * @param ident         Identifier that is verified
+     * @param contextString String used in error message to give context to the user
+     */
+    @SuppressWarnings("fallthrough")
+    private void verifyStrictIdent(final IdentNode ident, final String contextString) {
+        if (isStrictMode) {
+            switch (ident.getName()) {
+            case "eval":
+            case "arguments":
+                error(AbstractParser.message("strict.name", ident.getName(), contextString), ident.getToken());
+            default:
+                break;
+            }
+        }
+    }
+
+    /**
+     * VariableStatement :
+     *      var VariableDeclarationList ;
+     *
+     * VariableDeclarationList :
+     *      VariableDeclaration
+     *      VariableDeclarationList , VariableDeclaration
+     *
+     * VariableDeclaration :
+     *      Identifier Initializer?
+     *
+     * Initializer :
+     *      = AssignmentExpression
+     *
+     * See 12.2
+     *
+     * Parse a VAR statement.
+     * @param isStatement True if a statement (not used in a FOR.)
+     */
+    private List<VarNode> variableStatement(final boolean isStatement) {
+        // VAR tested in caller.
+        next();
+
+        final List<VarNode> vars = new ArrayList<>();
+
+        while (true) {
+            // Get starting token.
+            final long varToken = token;
+            // Get name of var.
+            final IdentNode name = getIdent();
+            verifyStrictIdent(name, "variable name");
+
+            // Assume no init.
+            Node init = null;
+
+            // Look for initializer assignment.
+            if (type == ASSIGN) {
+                next();
+
+                // Get initializer expression. Suppress IN if not statement.
+                init = assignmentExpression(!isStatement);
+            }
+
+            // Allocate var node.
+            final VarNode var = new VarNode(source, varToken, finish, name, init);
+            if (isStatement) {
+                function.addDeclaration(var);
+            }
+
+            vars.add(var);
+            // Add to current block.
+            block.addStatement(var);
+
+            if (type != COMMARIGHT) {
+                break;
+            }
+            next();
+        }
+
+        // If is a statement then handle end of line.
+        if (isStatement) {
+            boolean semicolon = type == SEMICOLON;
+            endOfLine();
+            if (semicolon) {
+                block.setFinish(finish);
+            }
+        }
+
+        return vars;
+    }
+
+    /**
+     * EmptyStatement :
+     *      ;
+     *
+     * See 12.3
+     *
+     * Parse an empty statement.
+     */
+    private void emptyStatement() {
+        if (env._empty_statements) {
+            block.addStatement(new EmptyNode(source, token,
+                    Token.descPosition(token) + Token.descLength(token)));
+        }
+
+        // SEMICOLON checked in caller.
+        next();
+    }
+
+    /**
+     * ExpressionStatement :
+     *      Expression ; // [lookahead ~( or  function )]
+     *
+     * See 12.4
+     *
+     * Parse an expression used in a statement block.
+     */
+    private void expressionStatement() {
+        // Lookahead checked in caller.
+        final long expressionToken = token;
+
+        // Get expression and add as statement.
+        final Node expression = expression();
+
+        ExecuteNode executeNode = null;
+        if (expression != null) {
+            executeNode = new ExecuteNode(source, expressionToken, finish, expression);
+            block.addStatement(executeNode);
+        } else {
+            expect(null);
+        }
+
+        endOfLine();
+
+        if (executeNode != null) {
+            executeNode.setFinish(finish);
+            block.setFinish(finish);
+        }
+    }
+
+    /**
+     * IfStatement :
+     *      if ( Expression ) Statement else Statement
+     *      if ( Expression ) Statement
+     *
+     * See 12.5
+     *
+     * Parse an IF statement.
+     */
+    private void ifStatement() {
+        // Capture IF token.
+        final long ifToken = token;
+         // IF tested in caller.
+        next();
+
+        expect(LPAREN);
+
+        // Get the test expression.
+        final Node test = expression();
+
+        expect(RPAREN);
+
+        // Get the pass statement.
+        final Block pass = getStatement();
+
+        // Assume no else.
+        Block fail = null;
+
+        if (type == ELSE) {
+            next();
+
+            // Get the else block.
+            fail = getStatement();
+        }
+
+        // Construct and add new if node.
+        final IfNode ifNode = new IfNode(source, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail);
+
+        block.addStatement(ifNode);
+    }
+
+    /**
+     * ... IterationStatement:
+     *           ...
+     *           for ( Expression[NoIn]?; Expression? ; Expression? ) Statement
+     *           for ( var VariableDeclarationList[NoIn]; Expression? ; Expression? ) Statement
+     *           for ( LeftHandSideExpression in Expression ) Statement
+     *           for ( var VariableDeclaration[NoIn] in Expression ) Statement
+     *
+     * See 12.6
+     *
+     * Parse a FOR statement.
+     */
+    private void forStatement() {
+        // Create FOR node, capturing FOR token.
+        final ForNode forNode = new ForNode(source, token, Token.descPosition(token));
+
+        pushControlNode(forNode);
+
+        // Set up new block for scope of vars. Captures first token.
+        final Block outer = newBlock();
+
+        try {
+            // FOR tested in caller.
+            next();
+
+            // Nashorn extension: for each expression.
+            // iterate property values rather than property names.
+            if (!env._no_syntax_extensions && type == IDENT && "each".equals(getValue())) {
+                forNode.setIsForEach();
+                next();
+            }
+
+            expect(LPAREN);
+
+            /// Capture control information.
+            forControl(forNode);
+
+            expect(RPAREN);
+
+            // Set the for body.
+            final Block body = getStatement();
+            forNode.setBody(body);
+            forNode.setFinish(body.getFinish());
+            outer.setFinish(body.getFinish());
+
+            // Add for to current block.
+            block.addStatement(forNode);
+        } finally {
+            restoreBlock();
+            popControlNode();
+        }
+
+        block.addStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer));
+     }
+
+    /**
+     * ... IterationStatement :
+     *           ...
+     *           Expression[NoIn]?; Expression? ; Expression?
+     *           var VariableDeclarationList[NoIn]; Expression? ; Expression?
+     *           LeftHandSideExpression in Expression
+     *           var VariableDeclaration[NoIn] in Expression
+     *
+     * See 12.6
+     *
+     * Parse the control section of a FOR statement.  Also used for
+     * comprehensions.
+     * @param forNode Owning FOR.
+     */
+    private void forControl(final ForNode forNode) {
+        List<VarNode> vars = null;
+
+        switch (type) {
+        case VAR:
+            // Var statements captured in for outer block.
+            vars = variableStatement(false);
+            break;
+
+        case SEMICOLON:
+            break;
+
+        default:
+            final Node expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
+            forNode.setInit(expression);
+        }
+
+        switch (type) {
+        case SEMICOLON:
+            // for (init; test; modify)
+            expect(SEMICOLON);
+
+            // Get the test expression.
+            if (type != SEMICOLON) {
+                forNode.setTest(expression());
+            }
+
+            expect(SEMICOLON);
+
+            // Get the modify expression.
+            if (type != RPAREN) {
+                final Node expression = expression();
+                forNode.setModify(expression);
+            }
+
+            break;
+
+        case IN:
+            forNode.setIsForIn();
+
+            if (vars != null) {
+                // for (var i in obj)
+                if (vars.size() == 1) {
+                    forNode.setInit(new IdentNode(vars.get(0).getName()));
+                } else {
+                    // for (var i, j in obj) is invalid
+                    error(AbstractParser.message("many.vars.in.for.in.loop"), vars.get(1).getToken());
+                }
+
+            } else {
+                // for (expr in obj)
+                final Node init = forNode.getInit();
+                assert init != null : "for..in init expression can not be null here";
+
+                // check if initial expression is a valid L-value
+                if (!(init instanceof AccessNode ||
+                      init instanceof IndexNode ||
+                      init instanceof IdentNode)) {
+                    error(AbstractParser.message("not.lvalue.for.in.loop"), init.getToken());
+                }
+
+                if (init instanceof IdentNode) {
+                    if (! checkIdentLValue((IdentNode)init)) {
+                        error(AbstractParser.message("not.lvalue.for.in.loop"), init.getToken());
+                    }
+                    verifyStrictIdent((IdentNode)init, "for-in iterator");
+                }
+            }
+
+            next();
+
+            // Get the collection expression.
+            forNode.setModify(expression());
+            break;
+
+        default:
+            expect(SEMICOLON);
+            break;
+        }
+
+    }
+
+    /**
+     * ...IterationStatement :
+     *           ...
+     *           while ( Expression ) Statement
+     *           ...
+     *
+     * See 12.6
+     *
+     * Parse while statement.
+     */
+    private void whileStatement() {
+        // Capture WHILE token.
+        final long whileToken = token;
+        // WHILE tested in caller.
+        next();
+
+        // Construct WHILE node.
+        final WhileNode whileNode = new WhileNode(source, whileToken, Token.descPosition(whileToken));
+        pushControlNode(whileNode);
+
+        try {
+            expect(LPAREN);
+
+            // Get the test expression.
+            final Node test = expression();
+            whileNode.setTest(test);
+
+            expect(RPAREN);
+
+            // Get WHILE body.
+            final Block statements = getStatement();
+            whileNode.setBody(statements);
+            whileNode.setFinish(statements.getFinish());
+
+            // Add WHILE node.
+            block.addStatement(whileNode);
+        } finally {
+            popControlNode();
+        }
+    }
+
+    /**
+     * ...IterationStatement :
+     *           ...
+     *           do Statement while( Expression ) ;
+     *           ...
+     *
+     * See 12.6
+     *
+     * Parse DO WHILE statement.
+     */
+    private void doStatement() {
+        // Capture DO token.
+        final long doToken = token;
+        // DO tested in the caller.
+        next();
+
+        final WhileNode doWhileNode = new DoWhileNode(source, doToken, Token.descPosition(doToken));
+        pushControlNode(doWhileNode);
+
+        try {
+           // Get DO body.
+            final Block statements = getStatement();
+            doWhileNode.setBody(statements);
+
+            expect(WHILE);
+
+            expect(LPAREN);
+
+            // Get the test expression.
+            final Node test = expression();
+            doWhileNode.setTest(test);
+
+            expect(RPAREN);
+
+            if (type == SEMICOLON) {
+                endOfLine();
+            }
+
+            doWhileNode.setFinish(finish);
+
+            // Add DO node.
+            block.addStatement(doWhileNode);
+        } finally {
+            popControlNode();
+        }
+    }
+
+    /**
+     * ContinueStatement :
+     *      continue Identifier? ; // [no LineTerminator here]
+     *
+     * See 12.7
+     *
+     * Parse CONTINUE statement.
+     */
+    private void continueStatement() {
+        // Capture CONTINUE token.
+        final long continueToken = token;
+        // CONTINUE tested in caller.
+        nextOrEOL();
+
+        LabelNode labelNode = null;
+
+        // SEMICOLON or label.
+        switch (type) {
+        case RBRACE:
+        case SEMICOLON:
+        case EOL:
+            break;
+
+        default:
+            final IdentNode ident = getIdent();
+            labelNode = findLabel(ident);
+
+            if (labelNode == null) {
+                error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
+            }
+
+            break;
+        }
+
+        final Node targetNode = labelNode != null ? labelNode.getContinueNode() : findControl(WhileNode.class);
+
+        if (targetNode == null) {
+            error(AbstractParser.message("illegal.continue.stmt"), continueToken);
+        }
+
+        endOfLine();
+
+        // Construct and add CONTINUE node.
+        final ContinueNode continueNode = new ContinueNode(source, continueToken, finish, labelNode, targetNode, findControl(TryNode.class));
+        continueNode.setScopeNestingLevel(countControls(WithNode.class, targetNode));
+
+        block.addStatement(continueNode);
+    }
+
+    /**
+     * BreakStatement :
+     *      break Identifier? ; // [no LineTerminator here]
+     *
+     * See 12.8
+     *
+     */
+    private void breakStatement() {
+        // Capture BREAK token.
+        final long breakToken = token;
+        // BREAK tested in caller.
+        nextOrEOL();
+
+        LabelNode labelNode = null;
+
+        // SEMICOLON or label.
+        switch (type) {
+        case RBRACE:
+        case SEMICOLON:
+        case EOL:
+            break;
+
+        default:
+            final IdentNode ident = getIdent();
+            labelNode = findLabel(ident);
+
+            if (labelNode == null) {
+                error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
+            }
+
+            break;
+        }
+
+        final Node targetNode = labelNode != null ? labelNode.getBreakNode() : findControl(BreakableNode.class);
+
+        if (targetNode == null) {
+            error(AbstractParser.message("illegal.break.stmt"), breakToken);
+        }
+
+        endOfLine();
+
+        // Construct and add BREAK node.
+        final BreakNode breakNode = new BreakNode(source, breakToken, finish, labelNode, targetNode, findControl(TryNode.class));
+        breakNode.setScopeNestingLevel(countControls(WithNode.class, targetNode));
+
+        block.addStatement(breakNode);
+    }
+
+    /**
+     * ReturnStatement :
+     *      return Expression? ; // [no LineTerminator here]
+     *
+     * See 12.9
+     *
+     * Parse RETURN statement.
+     */
+    private void returnStatement() {
+        // check for return outside function
+        if (function.getKind() == FunctionNode.Kind.SCRIPT) {
+            error(AbstractParser.message("invalid.return"));
+        }
+
+        // Capture RETURN token.
+        final long returnToken = token;
+        // RETURN tested in caller.
+        nextOrEOL();
+
+        Node expression = null;
+
+        // SEMICOLON or expression.
+        switch (type) {
+        case RBRACE:
+        case SEMICOLON:
+        case EOL:
+            break;
+
+        default:
+            expression = expression();
+            break;
+        }
+
+        endOfLine();
+
+        // Construct and add RETURN node.
+        final ReturnNode returnNode = new ReturnNode(source, returnToken, finish, expression, findControl(TryNode.class));
+        block.addStatement(returnNode);
+    }
+
+    /**
+     * YieldStatement :
+     *      yield Expression? ; // [no LineTerminator here]
+     *
+     * JavaScript 1.8
+     *
+     * Parse YIELD statement.
+     */
+    private void yieldStatement() {
+        // Capture YIELD token.
+        final long yieldToken = token;
+        // YIELD tested in caller.
+        nextOrEOL();
+
+        Node expression = null;
+
+        // SEMICOLON or expression.
+        switch (type) {
+        case RBRACE:
+        case SEMICOLON:
+        case EOL:
+            break;
+
+        default:
+            expression = expression();
+            break;
+        }
+
+        endOfLine();
+
+        // Construct and add YIELD node.
+        final ReturnNode yieldNode = new ReturnNode(source, yieldToken, finish, expression, findControl(TryNode.class));
+        block.addStatement(yieldNode);
+    }
+
+    /**
+     * WithStatement :
+     *      with ( Expression ) Statement
+     *
+     * See 12.10
+     *
+     * Parse WITH statement.
+     */
+    private void withStatement() {
+        // Capture WITH token.
+        final long withToken = token;
+        // WITH tested in caller.
+        next();
+
+        // ECMA 12.10.1 strict mode restrictions
+        if (isStrictMode) {
+            error(AbstractParser.message("strict.no.with"), withToken);
+        }
+
+        // Get WITH expression.
+        final WithNode withNode = new WithNode(source, withToken, finish, null, null);
+        function.setHasWith();
+
+        try {
+            pushControlNode(withNode);
+
+            expect(LPAREN);
+
+            final Node expression = expression();
+            withNode.setExpression(expression);
+
+            expect(RPAREN);
+
+            // Get WITH body.
+            final Block statements = getStatement();
+            withNode.setBody(statements);
+            withNode.setFinish(finish);
+        } finally {
+            popControlNode(withNode);
+        }
+
+        block.addStatement(withNode);
+    }
+
+    /**
+     * SwitchStatement :
+     *      switch ( Expression ) CaseBlock
+     *
+     * CaseBlock :
+     *      { CaseClauses? }
+     *      { CaseClauses? DefaultClause CaseClauses }
+     *
+     * CaseClauses :
+     *      CaseClause
+     *      CaseClauses CaseClause
+     *
+     * CaseClause :
+     *      case Expression : StatementList?
+     *
+     * DefaultClause :
+     *      default : StatementList?
+     *
+     * See 12.11
+     *
+     * Parse SWITCH statement.
+     */
+    private void switchStatement() {
+        // Capture SWITCH token.
+        final long switchToken = token;
+        // SWITCH tested in caller.
+        next();
+
+        // Create and add switch statement.
+        final SwitchNode switchNode = new SwitchNode(source, switchToken, Token.descPosition(switchToken));
+        pushControlNode(switchNode);
+
+        try {
+            expect(LPAREN);
+
+            // Get switch expression.
+            final Node switchExpression = expression();
+            switchNode.setExpression(switchExpression);
+
+            expect(RPAREN);
+
+            expect(LBRACE);
+
+            // Prepare to accumulate cases.
+            final List<CaseNode> cases = new ArrayList<>();
+            CaseNode defaultCase = null;
+
+            while (type != RBRACE) {
+                // Prepare for next case.
+                Node caseExpression = null;
+                final long caseToken = token;
+
+                switch (type) {
+                case CASE:
+                    next();
+
+                    // Get case expression.
+                    caseExpression = expression();
+
+                    break;
+
+                case DEFAULT:
+                    if (defaultCase != null) {
+                        error(AbstractParser.message("duplicate.default.in.switch"));
+                    }
+
+                    next();
+
+                    break;
+
+                default:
+                    // Force an error.
+                    expect(CASE);
+                    break;
+                }
+
+                expect(COLON);
+
+                // Get CASE body.
+                final Block statements = getBlock(false);
+                final CaseNode caseNode = new CaseNode(source, caseToken, finish, caseExpression, statements);
+                statements.setFinish(finish);
+
+                if (caseExpression == null) {
+                    defaultCase = caseNode;
+                }
+
+                cases.add(caseNode);
+            }
+
+            switchNode.setCases(cases);
+            switchNode.setDefaultCase(defaultCase);
+
+            next();
+
+            switchNode.setFinish(finish);
+
+            block.addStatement(switchNode);
+        } finally {
+            popControlNode();
+        }
+    }
+
+    /**
+     * LabelledStatement :
+     *      Identifier : Statement
+     *
+     * See 12.12
+     *
+     * Parse label statement.
+     */
+    private void labelStatement() {
+        // Capture label token.
+        final long labelToken = token;
+        // Get label ident.
+        final IdentNode ident = getIdent();
+
+        expect(COLON);
+
+        if (findLabel(ident) != null) {
+            error(AbstractParser.message("duplicate.label", ident.getName()), labelToken);
+        }
+
+        try {
+            // Create and add label.
+            final LabelNode labelNode = new LabelNode(source, labelToken, finish, ident, null);
+            pushLabel(labelNode);
+            // Get and save body.
+            final Block statements = getStatement();
+            labelNode.setBody(statements);
+            labelNode.setFinish(finish);
+
+            block.addStatement(labelNode);
+        } finally {
+            // Remove label.
+            popLabel();
+        }
+    }
+
+   /**
+     * ThrowStatement :
+     *      throw Expression ; // [no LineTerminator here]
+     *
+     * See 12.13
+     *
+     * Parse throw statement.
+     */
+    private void throwStatement() {
+        // Capture THROW token.
+        final long throwToken = token;
+        // THROW tested in caller.
+        nextOrEOL();
+
+        Node expression = null;
+
+        // SEMICOLON or expression.
+        switch (type) {
+        case RBRACE:
+        case SEMICOLON:
+        case EOL:
+            break;
+
+        default:
+            expression = expression();
+            break;
+        }
+
+        if (expression == null) {
+            error(AbstractParser.message("expected.operand", type.getNameOrType()));
+        }
+
+        endOfLine();
+
+        // Construct and add THROW node.
+        final ThrowNode throwNode = new ThrowNode(source, throwToken, finish, expression, findControl(TryNode.class));
+        block.addStatement(throwNode);
+    }
+
+    /**
+     * TryStatement :
+     *      try Block Catch
+     *      try Block Finally
+     *      try Block Catch Finally
+     *
+     * Catch :
+     *      catch( Identifier if Expression ) Block
+     *      catch( Identifier ) Block
+     *
+     * Finally :
+     *      finally Block
+     *
+     * See 12.14
+     *
+     * Parse TRY statement.
+     */
+    private void tryStatement() {
+        // Capture TRY token.
+        final long tryToken = token;
+        // TRY tested in caller.
+        next();
+
+        // Container block needed to act as target for labeled break statements
+        final Block outer = newBlock();
+        pushControlNode(outer);
+
+        // Create try.
+        final TryNode tryNode = new TryNode(source, tryToken, Token.descPosition(tryToken), findControl(TryNode.class));
+        pushControlNode(tryNode);
+
+        try {
+            // Get TRY body.
+            final Block tryBody = getBlock(true);
+
+            // Prepare to accumulate catches.
+            final List<Block> catchBlocks = new ArrayList<>();
+
+            while (type == CATCH) {
+                // Capture CATCH token.
+                final long catchToken = token;
+                next();
+
+                expect(LPAREN);
+
+                // Get exception ident.
+                final IdentNode exception = getIdent();
+
+                // ECMA 12.4.1 strict mode restrictions
+                verifyStrictIdent(exception, "catch argument");
+
+                // Check for conditional catch.
+                Node ifExpression = null;
+
+                if (type == IF) {
+                    next();
+
+                    // Get the exception condition.
+                    ifExpression = expression();
+                }
+
+                expect(RPAREN);
+
+                try {
+                    final Block catchBlock = newBlock();
+
+                    // Get CATCH body.
+                    final Block catchBody = getBlock(true);
+
+                    // Create and add catch.
+                    final CatchNode catchNode = new CatchNode(source, catchToken, finish, exception, ifExpression, catchBody);
+                    block.addStatement(catchNode);
+                    catchBlocks.add(catchBlock);
+                } finally {
+                    restoreBlock();
+                }
+
+                // If unconditional catch then should to be the end.
+                if (ifExpression == null) {
+                    break;
+                }
+            }
+
+            popControlNode();
+
+            // Prepare to capture finally statement.
+            Block finallyStatements = null;
+
+            if (type == FINALLY) {
+                next();
+
+                // Get FINALLY body.
+                finallyStatements = getBlock(true);
+            }
+
+            // Need at least one catch or a finally.
+            if (catchBlocks.isEmpty() && finallyStatements == null) {
+                error(AbstractParser.message("missing.catch.or.finally"), tryToken);
+            }
+
+            tryNode.setBody(tryBody);
+            tryNode.setCatchBlocks(catchBlocks);
+            tryNode.setFinallyBody(finallyStatements);
+            tryNode.setFinish(finish);
+            outer.setFinish(finish);
+
+            // Add try.
+            outer.addStatement(tryNode);
+        } finally {
+            popControlNode(tryNode);
+            restoreBlock();
+            popControlNode(outer);
+        }
+
+        block.addStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer));
+    }
+
+    /**
+     * DebuggerStatement :
+     *      debugger ;
+     *
+     * See 12.15
+     *
+     * Parse debugger statement.
+     */
+    private void  debuggerStatement() {
+        // Capture DEBUGGER token.
+        final long debuggerToken = token;
+        // DEBUGGER tested in caller.
+        next();
+
+        endOfLine();
+
+        final RuntimeNode runtimeNode = new RuntimeNode(source, debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Node>());
+        block.addStatement(runtimeNode);
+    }
+
+    /**
+     * PrimaryExpression :
+     *      this
+     *      Identifier
+     *      Literal
+     *      ArrayLiteral
+     *      ObjectLiteral
+     *      ( Expression )
+     *
+     *  See 11.1
+     *
+     * Parse primary expression.
+     * @return Expression node.
+     */
+    @SuppressWarnings("fallthrough")
+    private Node primaryExpression() {
+        // Capture first token.
+        final long primaryToken = token;
+
+        switch (type) {
+        case THIS:
+            final String name = type.getName();
+            next();
+            return new IdentNode(source, primaryToken, finish, name);
+        case IDENT:
+            final IdentNode ident = getIdent();
+            if (ident == null) {
+                break;
+            }
+            detectSpecialProperty(ident);
+            return ident;
+        case OCTAL:
+            if (isStrictMode) {
+               error(AbstractParser.message("strict.no.octal"), token);
+            }
+        case STRING:
+        case ESCSTRING:
+        case DECIMAL:
+        case HEXADECIMAL:
+        case FLOATING:
+        case REGEX:
+        case XML:
+            return getLiteral();
+        case EXECSTRING:
+            return execString(primaryToken);
+        case FALSE:
+            next();
+            return LiteralNode.newInstance(source, primaryToken, finish, false);
+        case TRUE:
+            next();
+            return LiteralNode.newInstance(source, primaryToken, finish, true);
+        case NULL:
+            next();
+            return LiteralNode.newInstance(source, primaryToken, finish);
+        case LBRACKET:
+            return arrayLiteral();
+        case LBRACE:
+            return objectLiteral();
+        case LPAREN:
+            next();
+
+            final Node expression = expression();
+
+            expect(RPAREN);
+
+            return expression;
+
+        default:
+            // In this context some operator tokens mark the start of a literal.
+            if (lexer.scanLiteral(primaryToken, type)) {
+                next();
+                return getLiteral();
+            }
+            if (isNonStrictModeIdent()) {
+                return getIdent();
+            }
+            break;
+        }
+
+        return null;
+    }
+
+    /**
+     * Convert execString to a call to $EXEC.
+     *
+     * @param primaryToken Original string token.
+     * @return callNode to $EXEC.
+     */
+    Node execString(final long primaryToken) {
+        // Synthesize an ident to call $EXEC.
+        final IdentNode execIdent = new IdentNode(source, primaryToken, finish, ScriptingFunctions.EXEC_NAME);
+        // Skip over EXECSTRING.
+        next();
+        // Set up argument list for call.
+        final List<Node> arguments = new ArrayList<>();
+        // Skip beginning of edit string expression.
+        expect(LBRACE);
+        // Add the following expression to arguments.
+        arguments.add(expression());
+        // Skip ending of edit string expression.
+        expect(RBRACE);
+
+        return new CallNode(source, primaryToken, finish, execIdent, arguments);
+    }
+
+    /**
+     * ArrayLiteral :
+     *      [ Elision? ]
+     *      [ ElementList ]
+     *      [ ElementList , Elision? ]
+     *      [ expression for (LeftHandExpression in expression) ( (if ( Expression ) )? ]
+     *
+     * ElementList : Elision? AssignmentExpression
+     *      ElementList , Elision? AssignmentExpression
+     *
+     * Elision :
+     *      ,
+     *      Elision ,
+     *
+     * See 12.1.4
+     * JavaScript 1.8
+     *
+     * Parse array literal.
+     * @return Expression node.
+     */
+    private Node arrayLiteral() {
+        // Capture LBRACKET token.
+        final long arrayToken = token;
+        // LBRACKET tested in caller.
+        next();
+
+        // Prepare to accummulating elements.
+        final List<Node> elements = new ArrayList<>();
+        // Track elisions.
+        boolean elision = true;
+loop:
+        while (true) {
+             switch (type) {
+            case RBRACKET:
+                next();
+
+                break loop;
+
+            case COMMARIGHT:
+                next();
+
+                // If no prior expression
+                if (elision) {
+                    elements.add(null);
+                }
+
+                elision = true;
+
+                break;
+
+            default:
+                if (! elision) {
+                    error(AbstractParser.message("expected.comma", type.getNameOrType()));
+                }
+                // Add expression element.
+                final Node expression = assignmentExpression(false);
+
+                if (expression != null) {
+                    elements.add(expression);
+                } else {
+                    expect(RBRACKET);
+                }
+
+                elision = false;
+                break;
+            }
+        }
+
+        return LiteralNode.newInstance(source, arrayToken, finish, elements);
+    }
+
+    /**
+     * ObjectLiteral :
+     *      { }
+     *      { PropertyNameAndValueList } { PropertyNameAndValueList , }
+     *
+     * PropertyNameAndValueList :
+     *      PropertyAssignment
+     *      PropertyNameAndValueList , PropertyAssignment
+     *
+     * See 11.1.5
+     *
+     * Parse an object literal.
+     * @return Expression node.
+     */
+    private Node objectLiteral() {
+        // Capture LBRACE token.
+        final long objectToken = token;
+        // LBRACE tested in caller.
+        next();
+
+        // Object context.
+        Block objectContext = null;
+        // Prepare to accumulate elements.
+        final List<Node> elements = new ArrayList<>();
+        final Map<Object, PropertyNode> map = new HashMap<>();
+
+        try {
+            // Create a block for the object literal.
+            objectContext = newBlock();
+
+            boolean commaSeen = true;
+loop:
+            while (true) {
+                switch (type) {
+                case RBRACE:
+                    next();
+                    break loop;
+
+                case COMMARIGHT:
+                    next();
+                    commaSeen = true;
+                    break;
+
+                default:
+                    if (! commaSeen) {
+                        error(AbstractParser.message("expected.comma", type.getNameOrType()));
+                    }
+
+                    commaSeen = false;
+                    // Get and add the next property.
+                    final PropertyNode property = propertyAssignment();
+                    final Object key = property.getKeyName();
+                    final PropertyNode existingProperty = map.get(key);
+
+                    if (existingProperty != null) {
+                        // ECMA section 11.1.5 Object Initialiser
+                        // point # 4 on property assignment production
+                        final Node value  = property.getValue();
+                        final Node getter = property.getGetter();
+                        final Node setter = property.getSetter();
+
+                        final Node prevValue  = existingProperty.getValue();
+                        final Node prevGetter = existingProperty.getGetter();
+                        final Node prevSetter = existingProperty.getSetter();
+
+                        boolean redefinitionOk = true;
+                        // ECMA 11.1.5 strict mode restrictions
+                        if (isStrictMode) {
+                            if (value != null && prevValue != null) {
+                                redefinitionOk = false;
+                            }
+                        }
+
+                        final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
+                        final boolean isAccessor = getter != null || setter != null;
+
+                        // data property redefined as accessor property
+                        if (prevValue != null && isAccessor) {
+                            redefinitionOk = false;
+                        }
+
+                        // accessor property redefined as data
+                        if (isPrevAccessor && value != null) {
+                            redefinitionOk = false;
+                        }
+
+                        if (isAccessor && isPrevAccessor) {
+                            if (getter != null && prevGetter != null ||
+                                setter != null && prevSetter != null) {
+                                redefinitionOk = false;
+                            }
+                        }
+
+                        if (! redefinitionOk) {
+                            error(AbstractParser.message("property.redefinition", key.toString()), property.getToken());
+                        }
+
+                        if (value != null) {
+                            final Node existingValue = existingProperty.getValue();
+
+                            if (existingValue == null) {
+                                existingProperty.setValue(value);
+                            } else {
+                                final long propertyToken = Token.recast(existingProperty.getToken(), COMMARIGHT);
+                                existingProperty.setValue(new BinaryNode(source, propertyToken, existingValue, value));
+                            }
+
+                            existingProperty.setGetter(null);
+                            existingProperty.setSetter(null);
+                        }
+
+                        if (getter != null) {
+                            existingProperty.setGetter(getter);
+                        }
+
+                        if (setter != null) {
+                            existingProperty.setSetter(setter);
+                        }
+                    } else {
+                        map.put(key, property);
+                        elements.add(property);
+                    }
+
+                    break;
+                }
+            }
+        } finally {
+            restoreBlock();
+        }
+
+        // Construct new object literal.
+        objectContext.setFinish(finish);
+        objectContext.setStart(Token.descPosition(objectToken));
+
+        return new ObjectNode(source, objectToken, finish, objectContext, elements);
+    }
+
+    /**
+     * PropertyName :
+     *      IdentifierName
+     *      StringLiteral
+     *      NumericLiteral
+     *
+     * See 11.1.5
+     *
+     * @return PropertyName node
+     */
+    @SuppressWarnings("fallthrough")
+    private PropertyKey propertyName() {
+        switch (type) {
+        case IDENT:
+            return getIdent();
+        case OCTAL:
+            if (isStrictMode) {
+                error(AbstractParser.message("strict.no.octal"), token);
+            }
+        case STRING:
+        case ESCSTRING:
+        case DECIMAL:
+        case HEXADECIMAL:
+        case FLOATING:
+            return getLiteral();
+        default:
+            return getIdentifierName();
+        }
+    }
+
+    /**
+     * PropertyAssignment :
+     *      PropertyName : AssignmentExpression
+     *      get PropertyName ( ) { FunctionBody }
+     *      set PropertyName ( PropertySetParameterList ) { FunctionBody }
+     *
+     * PropertySetParameterList :
+     *      Identifier
+     *
+     * PropertyName :
+     *      IdentifierName
+     *      StringLiteral
+     *      NumericLiteral
+     *
+     * See 11.1.5
+     *
+     * Parse an object literal property.
+     * @return Property or reference node.
+     */
+    private PropertyNode propertyAssignment() {
+        // Capture firstToken.
+        final long propertyToken = token;
+
+        FunctionNode functionNode;
+        List<IdentNode> parameters;
+        PropertyNode propertyNode;
+        PropertyKey propertyName;
+
+        if (type == IDENT) {
+            // Get IDENT.
+            final String ident = (String)expectValue(IDENT);
+
+            if (type != COLON) {
+                final long getSetToken = token;
+
+                switch (ident) {
+                case "get":
+                    final PropertyKey getIdent = propertyName();
+                    final String getterName = getIdent.getPropertyName();
+                    final IdentNode getNameNode = new IdentNode(source, ((Node)getIdent).getToken(), finish, "get " + getterName);
+                    expect(LPAREN);
+                    expect(RPAREN);
+                    parameters = new ArrayList<>();
+                    functionNode = functionBody(getSetToken, getNameNode, parameters, FunctionNode.Kind.GETTER);
+                    propertyNode = new PropertyNode(source, propertyToken, finish, getIdent, null);
+                    propertyNode.setGetter(new ReferenceNode(source, propertyToken, finish, functionNode));
+                    return propertyNode;
+
+                case "set":
+                    final PropertyKey setIdent = propertyName();
+                    final String setterName = setIdent.getPropertyName();
+                    final IdentNode setNameNode = new IdentNode(source, ((Node)setIdent).getToken(), finish, "set " + setterName);
+                    expect(LPAREN);
+                    final IdentNode argIdent = getIdent();
+                    verifyStrictIdent(argIdent, "setter argument");
+                    expect(RPAREN);
+                    parameters = new ArrayList<>();
+                    parameters.add(argIdent);
+                    functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER);
+                    propertyNode = new PropertyNode(source, propertyToken, finish, setIdent, null);
+                    propertyNode.setSetter(new ReferenceNode(source, propertyToken, finish, functionNode));
+                    return propertyNode;
+
+                default:
+                    break;
+                }
+            }
+
+            propertyName =  new IdentNode(source, propertyToken, finish, ident);
+        } else {
+            propertyName = propertyName();
+        }
+
+        expect(COLON);
+
+        final Node value = assignmentExpression(false);
+        propertyNode =  new PropertyNode(source, propertyToken, finish, propertyName, value);
+        return propertyNode;
+    }
+
+    /**
+     * LeftHandSideExpression :
+     *      NewExpression
+     *      CallExpression
+     *
+     * CallExpression :
+     *      MemberExpression Arguments
+     *      CallExpression Arguments
+     *      CallExpression [ Expression ]
+     *      CallExpression . IdentifierName
+     *
+     * See 11.2
+     *
+     * Parse left hand side expression.
+     * @return Expression node.
+     */
+    private Node leftHandSideExpression() {
+        long callToken = token;
+
+        Node lhs = memberExpression();
+
+        if (type == LPAREN) {
+            final List<Node> arguments = argumentList();
+
+            // Catch special functions.
+            if (lhs instanceof IdentNode) {
+                detectSpecialFunction((IdentNode)lhs);
+            }
+
+            lhs = new CallNode(source, callToken, finish, lhs, arguments);
+            if (isInWithBlock()) {
+                ((CallNode)lhs).setInWithBlock();
+            }
+        }
+
+loop:
+        while (true) {
+            // Capture token.
+            callToken = token;
+
+            switch (type) {
+            case LPAREN:
+                // Get NEW or FUNCTION arguments.
+                final List<Node> arguments = argumentList();
+
+                // Create call node.
+                lhs = new CallNode(source, callToken, finish, lhs, arguments);
+                if (isInWithBlock()) {
+                    ((CallNode)lhs).setInWithBlock();
+                }
+
+                break;
+
+            case LBRACKET:
+                next();
+
+                // Get array index.
+                final Node rhs = expression();
+
+                expect(RBRACKET);
+
+                // Create indexing node.
+                lhs = new IndexNode(source, callToken, finish, lhs, rhs);
+
+                break;
+
+            case PERIOD:
+                next();
+
+                final IdentNode property = getIdentifierName();
+
+                // Create property access node.
+                lhs = new AccessNode(source, callToken, finish, lhs, property);
+
+                break;
+
+            default:
+                break loop;
+            }
+        }
+
+        return lhs;
+    }
+
+    /**
+     * NewExpression :
+     *      MemberExpression
+     *      new NewExpression
+     *
+     * See 11.2
+     *
+     * Parse new expression.
+     * @return Expression node.
+     */
+    private Node newExpression() {
+        final long newToken = token;
+        // NEW is tested in caller.
+        next();
+
+        // Get function base.
+        final Node constructor = memberExpression();
+        if (constructor == null) {
+            return null;
+        }
+        // Get arguments.
+        List<Node> arguments;
+
+        // Allow for missing arguments.
+        if (type == LPAREN) {
+            arguments = argumentList();
+        } else {
+            arguments = new ArrayList<>();
+        }
+
+        // Nashorn extension: This is to support the following interface implementation
+        // syntax:
+        //
+        //     var r = new java.lang.Runnable() {
+        //         run: function() { println("run"); }
+        //     };
+        //
+        // The object literal following the "new Constructor()" expresssion
+        // is passed as an additional (last) argument to the constructor.
+
+        if (!env._no_syntax_extensions && type == LBRACE) {
+            arguments.add(objectLiteral());
+        }
+
+        final CallNode callNode = new CallNode(source, constructor.getToken(), finish, constructor, arguments);
+        if (isInWithBlock()) {
+            callNode.setInWithBlock();
+        }
+
+        return new UnaryNode(source, newToken, callNode);
+    }
+
+    /**
+     * MemberExpression :
+     *      PrimaryExpression
+     *      FunctionExpression
+     *      MemberExpression [ Expression ]
+     *      MemberExpression . IdentifierName
+     *      new MemberExpression Arguments
+     *
+     * See 11.2
+     *
+     * Parse member expression.
+     * @return Expression node.
+     */
+    private Node memberExpression() {
+        // Prepare to build operation.
+        Node lhs;
+
+        switch (type) {
+        case NEW:
+            // Get new exppression.
+            lhs = newExpression();
+            break;
+
+        case FUNCTION:
+            // Get function expression.
+            lhs = functionExpression(false);
+            break;
+
+        default:
+            // Get primary expression.
+            lhs = primaryExpression();
+            break;
+        }
+
+loop:
+        while (true) {
+            // Capture token.
+            final long callToken = token;
+
+            switch (type) {
+            case LBRACKET:
+                next();
+
+                // Get array index.
+                final Node index = expression();
+
+                expect(RBRACKET);
+
+                // Create indexing node.
+                lhs = new IndexNode(source, callToken, finish, lhs, index);
+
+                break;
+
+            case PERIOD:
+                if (lhs == null) {
+                    error(AbstractParser.message("expected.operand", type.getNameOrType()));
+                    return null;
+                }
+
+                next();
+
+                final IdentNode property = getIdentifierName();
+
+                // Create property access node.
+                lhs = new AccessNode(source, callToken, finish, lhs, property);
+
+                break;
+
+            default:
+                break loop;
+            }
+        }
+
+        return lhs;
+    }
+
+    /**
+     * Arguments :
+     *      ( )
+     *      ( ArgumentList )
+     *
+     * ArgumentList :
+     *      AssignmentExpression
+     *      ArgumentList , AssignmentExpression
+     *
+     * See 11.2
+     *
+     * Parse function call arguments.
+     * @return Argument list.
+     */
+    private List<Node> argumentList() {
+        // Prepare to accumulate list of arguments.
+        final List<Node> nodeList = new ArrayList<>();
+        // LPAREN tested in caller.
+        next();
+
+        // Track commas.
+        boolean first = true;
+
+        while (type != RPAREN) {
+            // Comma prior to every argument except the first.
+            if (!first) {
+                expect(COMMARIGHT);
+            } else {
+                first = false;
+            }
+
+            // Get argument expression.
+            nodeList.add(assignmentExpression(false));
+        }
+
+        expect(RPAREN);
+
+        return nodeList;
+   }
+
+    /**
+     * FunctionDeclaration :
+     *      function Identifier ( FormalParameterList? ) { FunctionBody }
+     *
+     * FunctionExpression :
+     *      function Identifier? ( FormalParameterList? ) { FunctionBody }
+     *
+     * See 13
+     *
+     * Parse function declaration.
+     * @param isStatement True if for is a statement.
+     *
+     * @return Expression node.
+     */
+    private Node functionExpression(final boolean isStatement) {
+        final LineNumberNode lineNumber = lineNumber();
+
+        final long functionToken = token;
+        // FUNCTION is tested in caller.
+        next();
+
+        IdentNode name = null;
+
+        if (type == IDENT || isNonStrictModeIdent()) {
+            name = getIdent();
+            verifyStrictIdent(name, "function name");
+        } else if (isStatement) {
+            // Nashorn extension: anonymous function statements
+            if (env._no_syntax_extensions || !env._anon_functions) {
+                expect(IDENT);
+            }
+        }
+
+        // name is null, generate anonymous name
+        boolean isAnonymous = false;
+        if (name == null) {
+            final String tmpName = "_L" + source.getLine(Token.descPosition(token));
+            name = new IdentNode(source, functionToken, Token.descPosition(functionToken), tmpName);
+            isAnonymous = true;
+        }
+
+        expect(LPAREN);
+
+        final List<IdentNode> parameters = formalParameterList();
+
+        expect(RPAREN);
+
+        final FunctionNode functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL);
+
+        if (isStatement && !isInWithBlock()) {
+            functionNode.setIsStatement();
+            if(ARGUMENTS.tag().equals(name.getName())) {
+                functionNode.findParentFunction().setDefinesArguments();
+            }
+        }
+
+        if (isAnonymous) {
+            functionNode.setIsAnonymous();
+        }
+
+        final ReferenceNode referenceNode = new ReferenceNode(source, functionToken, finish, functionNode);
+
+        final int arity = parameters.size();
+
+        final boolean strict = functionNode.isStrictMode();
+        if (arity > 1) {
+            final HashSet<String> parametersSet = new HashSet<>(arity);
+
+            for (int i = arity - 1; i >= 0; i--) {
+                final IdentNode parameter = parameters.get(i);
+                String parameterName = parameter.getName();
+
+                if (ARGUMENTS.tag().equals(parameterName)) {
+                    functionNode.setDefinesArguments();
+                }
+
+                if (parametersSet.contains(parameterName)) {
+                    // redefinition of parameter name
+                    if (strict) {
+                        error(AbstractParser.message("strict.param.redefinition", parameterName), parameter.getToken());
+                    } else {
+                        // rename in non-strict mode
+                        parameterName = functionNode.uniqueName(parameterName);
+                        final long parameterToken = parameter.getToken();
+                        parameters.set(i, new IdentNode(source, parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
+                    }
+                }
+
+                parametersSet.add(parameterName);
+            }
+        } else if (arity == 1) {
+            if (ARGUMENTS.tag().equals(parameters.get(0).getName())) {
+                functionNode.setDefinesArguments();
+            }
+        }
+
+        if (isStatement) {
+            final VarNode var = new VarNode(source, functionToken, finish, name, referenceNode);
+            if (isInWithBlock()) {
+                function.addDeclaration(var);
+                // Add to current block.
+                block.addStatement(var);
+            } else {
+                functionNode.setFunctionVarNode(var, lineNumber);
+            }
+        }
+
+        return referenceNode;
+    }
+
+    /**
+     * FormalParameterList :
+     *      Identifier
+     *      FormalParameterList , Identifier
+     *
+     * See 13
+     *
+     * Parse function parameter list.
+     * @return List of parameter nodes.
+     */
+    private List<IdentNode> formalParameterList() {
+        // Prepare to gather parameters.
+        final List<IdentNode> parameters = new ArrayList<>();
+        // Track commas.
+        boolean first = true;
+
+        while (type != RPAREN) {
+            // Comma prior to every argument except the first.
+            if (!first) {
+                expect(COMMARIGHT);
+            } else {
+                first = false;
+            }
+
+            // Get and add parameter.
+            final IdentNode ident = getIdent();
+
+            // ECMA 13.1 strict mode restrictions
+            verifyStrictIdent(ident, "function parameter");
+
+            parameters.add(ident);
+        }
+
+        return parameters;
+    }
+
+    /**
+     * FunctionBody :
+     *      SourceElements?
+     *
+     * See 13
+     *
+     * Parse function body.
+     * @return function node (body.)
+     */
+    private FunctionNode functionBody(final long firstToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind) {
+        FunctionNode functionNode = null;
+
+        try {
+            // Create a new function block.
+            functionNode = newFunctionBlock(ident);
+            functionNode.setParameters(parameters);
+            functionNode.setKind(kind);
+            functionNode.setFirstToken(firstToken);
+
+            // Nashorn extension: expression closures
+            if (!env._no_syntax_extensions && type != LBRACE) {
+                /*
+                 * Example:
+                 *
+                 * function square(x) x * x;
+                 * print(square(3));
+                 */
+
+                // just expression as function body
+                final Node expr = expression();
+
+                // create a return statement - this creates code in itself and does not need to be
+                // wrapped into an ExecuteNode
+                final ReturnNode  returnNode = new ReturnNode(source, expr.getToken(), finish, expr, null);
+
+                // add the return statement
+                functionNode.addStatement(returnNode);
+                functionNode.setLastToken(token);
+                functionNode.setFinish(Token.descPosition(token) + Token.descLength(token));
+
+            } else {
+                expect(LBRACE);
+
+                // Gather the function elements.
+                sourceElements();
+
+                functionNode.setLastToken(token);
+                expect(RBRACE);
+                functionNode.setFinish(finish);
+
+            }
+        } finally {
+            restoreBlock();
+        }
+
+        // Add the body of the function to the current block.
+        block.addFunction(functionNode);
+
+        return functionNode;
+    }
+
+    private RuntimeNode referenceError(final Node lhs, final Node rhs) {
+        final ArrayList<Node> args = new ArrayList<>();
+        args.add(lhs);
+        if (rhs == null) {
+            args.add(LiteralNode.newInstance(source, lhs.getToken(), lhs.getFinish()));
+        } else {
+            args.add(rhs);
+        }
+        args.add(LiteralNode.newInstance(source, lhs.getToken(), lhs.getFinish(), lhs.toString()));
+        final RuntimeNode runtimeNode = new RuntimeNode(source, lhs.getToken(),
+                      lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args);
+        return runtimeNode;
+    }
+
+    /*
+     * parse LHS [a, b, ..., c].
+     *
+     * JavaScript 1.8.
+     */
+    //private Node destructureExpression() {
+    //    return null;
+    //}
+
+    /**
+     * PostfixExpression :
+     *      LeftHandSideExpression
+     *      LeftHandSideExpression ++ // [no LineTerminator here]
+     *      LeftHandSideExpression -- // [no LineTerminator here]
+     *
+     * See 11.3
+     *
+     * UnaryExpression :
+     *      PostfixExpression
+     *      delete UnaryExpression
+     *      Node UnaryExpression
+     *      typeof UnaryExpression
+     *      ++ UnaryExpression
+     *      -- UnaryExpression
+     *      + UnaryExpression
+     *      - UnaryExpression
+     *      ~ UnaryExpression
+     *      ! UnaryExpression
+     *
+     * See 11.4
+     *
+     * Parse unary expression.
+     * @return Expression node.
+     */
+    private Node unaryExpression() {
+        final long unaryToken = token;
+
+        switch (type) {
+        case DELETE:
+        case VOID:
+        case TYPEOF:
+        case ADD:
+        case SUB:
+        case BIT_NOT:
+        case NOT:
+            next();
+
+            final Node expr = unaryExpression();
+
+            /*
+             // Not sure if "delete <ident>" is a compile-time error or a
+             // runtime error in strict mode.
+
+             if (isStrictMode) {
+                 if (unaryTokenType == DELETE && expr instanceof IdentNode) {
+                     error(message("strict.cant.delete.ident", ((IdentNode)expr).getName()), expr.getToken());
+                 }
+             }
+             */
+            return new UnaryNode(source, unaryToken, expr);
+
+        case INCPREFIX:
+        case DECPREFIX:
+            final TokenType opType = type;
+            next();
+
+            final Node lhs = leftHandSideExpression();
+            // ++, -- without operand..
+            if (lhs == null) {
+                // error would have been issued when looking for 'lhs'
+                return null;
+            }
+            if (!(lhs instanceof AccessNode ||
+                  lhs instanceof IndexNode ||
+                  lhs instanceof IdentNode)) {
+                return referenceError(lhs, null);
+            }
+
+            if (lhs instanceof IdentNode) {
+                if (! checkIdentLValue((IdentNode)lhs)) {
+                    return referenceError(lhs, null);
+                }
+                verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
+            }
+
+            return incDecExpression(unaryToken, opType, lhs, false);
+
+        default:
+            break;
+        }
+
+        Node expression = leftHandSideExpression();
+
+        if (last != EOL) {
+            switch (type) {
+            case INCPREFIX:
+            case DECPREFIX:
+                final TokenType opType = type;
+                final Node lhs = expression;
+                if (!(lhs instanceof AccessNode ||
+                   lhs instanceof IndexNode ||
+                   lhs instanceof IdentNode)) {
+                    next();
+                    return referenceError(lhs, null);
+                }
+                if (lhs instanceof IdentNode) {
+                    if (! checkIdentLValue((IdentNode)lhs)) {
+                        next();
+                        return referenceError(lhs, null);
+                    }
+                    verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
+                }
+                expression = incDecExpression(token, type, expression, true);
+                next();
+                break;
+            default:
+                break;
+            }
+        }
+
+        if (expression == null) {
+            error(AbstractParser.message("expected.operand", type.getNameOrType()));
+        }
+
+        return expression;
+    }
+
+    /**
+     * MultiplicativeExpression :
+     *      UnaryExpression
+     *      MultiplicativeExpression * UnaryExpression
+     *      MultiplicativeExpression / UnaryExpression
+     *      MultiplicativeExpression % UnaryExpression
+     *
+     * See 11.5
+     *
+     * AdditiveExpression :
+     *      MultiplicativeExpression
+     *      AdditiveExpression + MultiplicativeExpression
+     *      AdditiveExpression - MultiplicativeExpression
+     *
+     * See 11.6
+     *
+     * ShiftExpression :
+     *      AdditiveExpression
+     *      ShiftExpression << AdditiveExpression
+     *      ShiftExpression >> AdditiveExpression
+     *      ShiftExpression >>> AdditiveExpression
+     *
+     * See 11.7
+     *
+     * RelationalExpression :
+     *      ShiftExpression
+     *      RelationalExpression < ShiftExpression
+     *      RelationalExpression > ShiftExpression
+     *      RelationalExpression <= ShiftExpression
+     *      RelationalExpression >= ShiftExpression
+     *      RelationalExpression instanceof ShiftExpression
+     *      RelationalExpression in ShiftExpression // if !noIf
+     *
+     * See 11.8
+     *
+     *      RelationalExpression
+     *      EqualityExpression == RelationalExpression
+     *      EqualityExpression != RelationalExpression
+     *      EqualityExpression === RelationalExpression
+     *      EqualityExpression !== RelationalExpression
+     *
+     * See 11.9
+     *
+     * BitwiseANDExpression :
+     *      EqualityExpression
+     *      BitwiseANDExpression & EqualityExpression
+     *
+     * BitwiseXORExpression :
+     *      BitwiseANDExpression
+     *      BitwiseXORExpression ^ BitwiseANDExpression
+     *
+     * BitwiseORExpression :
+     *      BitwiseXORExpression
+     *      BitwiseORExpression | BitwiseXORExpression
+     *
+     * See 11.10
+     *
+     * LogicalANDExpression :
+     *      BitwiseORExpression
+     *      LogicalANDExpression && BitwiseORExpression
+     *
+     * LogicalORExpression :
+     *      LogicalANDExpression
+     *      LogicalORExpression || LogicalANDExpression
+     *
+     * See 11.11
+     *
+     * ConditionalExpression :
+     *      LogicalORExpression
+     *      LogicalORExpression ? AssignmentExpression : AssignmentExpression
+     *
+     * See 11.12
+     *
+     * AssignmentExpression :
+     *      ConditionalExpression
+     *      LeftHandSideExpression AssignmentOperator AssignmentExpression
+     *
+     * AssignmentOperator :
+     *      = *= /= %= += -= <<= >>= >>>= &= ^= |=
+     *
+     * See 11.13
+     *
+     * Expression :
+     *      AssignmentExpression
+     *      Expression , AssignmentExpression
+     *
+     * See 11.14
+     *
+     * Parse expression.
+     * @return Expression node.
+     */
+    private Node expression() {
+        // TODO - Destructuring array.
+        // Include commas in expression parsing.
+        return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
+    }
+    private Node expression(final Node exprLhs, final int minPrecedence, final boolean noIn) {
+        // Get the precedence of the next operator.
+        int precedence = type.getPrecedence();
+        Node lhs = exprLhs;
+
+        // While greater precedence.
+        while (type.isOperator(noIn) && precedence >= minPrecedence) {
+            // Capture the operator token.
+            final long op = token;
+
+            if (type == TERNARY) {
+                // Skip operator.
+                next();
+
+                // Pass expression. Middle expression of a conditional expression can be a "in"
+                // expression - even in the contexts where "in" is not permitted.
+                final Node rhs = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
+
+                expect(COLON);
+
+                // Fail expression.
+                final Node third = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
+
+                // Build up node.
+                lhs = new TernaryNode(source, op, lhs, rhs, third);
+            } else {
+                // Skip operator.
+                next();
+
+                 // Get the next primary expression.
+                Node rhs = unaryExpression();
+
+                // Get precedence of next operator.
+                int nextPrecedence = type.getPrecedence();
+
+                // Subtask greater precedence.
+                while (type.isOperator(noIn) &&
+                       (nextPrecedence > precedence ||
+                       nextPrecedence == precedence && !type.isLeftAssociative())) {
+                    rhs = expression(rhs, nextPrecedence, noIn);
+                    nextPrecedence = type.getPrecedence();
+                }
+
+                lhs = verifyAssignment(op, lhs, rhs);
+            }
+
+            precedence = type.getPrecedence();
+        }
+
+        return lhs;
+    }
+
+    private Node assignmentExpression(final boolean noIn) {
+        // TODO - Handle decompose.
+        // Exclude commas in expression parsing.
+        return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
+    }
+
+    /**
+     * Parse an end of line.
+     */
+    private void endOfLine() {
+        switch (type) {
+        case SEMICOLON:
+        case EOL:
+            next();
+            break;
+        case RPAREN:
+        case RBRACKET:
+        case RBRACE:
+        case EOF:
+            break;
+        default:
+            if (last != EOL) {
+                expect(SEMICOLON);
+            }
+            break;
+        }
+    }
+
+    /**
+     * Add a line number node at current position
+     */
+    private LineNumberNode lineNumber() {
+        if (env._debug_lines) {
+            return new LineNumberNode(source, token, line);
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "[JavaScript Parsing]";
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/Scanner.java b/nashorn/src/jdk/nashorn/internal/parser/Scanner.java
new file mode 100644
index 0000000..3303439
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/Scanner.java
@@ -0,0 +1,193 @@
+/*
+ * 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.parser;
+
+/**
+ * Utility for scanning thru a char array.
+ *
+ */
+public class Scanner {
+    /** Characters to scan. */
+    protected final char[] content;
+
+    /** Position in content. */
+    protected int position;
+
+    /** Scan limit. */
+    protected final int limit;
+
+    /** Current line number. */
+    protected int line;
+
+    /** Current character in stream */
+    protected char ch0;
+    /** 1 character lookahead */
+    protected char ch1;
+    /** 2 character lookahead */
+    protected char ch2;
+    /** 3 character lookahead */
+    protected char ch3;
+
+    /**
+     * Constructor
+     *
+     * @param content content to scan
+     * @param line    start line number
+     * @param start   position index in content where to start
+     * @param length  length of input
+     */
+    protected Scanner(final char[] content, final int line, final int start, final int length) {
+        this.content  = content;
+        this.position = start;
+        this.limit    = start + length;
+        this.line     = line;
+
+        reset(position);
+    }
+
+    /**
+     * Constructor
+     *
+     * Scan content from beginning to end. Content given as a string
+     *
+     * @param content content to scan
+     */
+    protected Scanner(final String content) {
+        this(content.toCharArray(), 0, 0, content.length());
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param scanner  scanner
+     * @param state    state, the state is a tuple {position, limit, line} only visible internally
+     */
+    Scanner(final Scanner scanner, final State state) {
+        content  = scanner.content;
+        position = state.position;
+        limit    = state.limit;
+        line     = state.line;
+
+        reset(position);
+   }
+
+    /**
+     * Information needed to restore previous state.
+     */
+    static class State {
+        /** Position in content. */
+        public final int position;
+
+        /** Scan limit. */
+        public int limit;
+
+        /** Current line number. */
+        public final int line;
+
+        State(final int position, final int limit, final int line) {
+            this.position = position;
+            this.limit    = limit;
+            this.line     = line;
+        }
+
+        /**
+         * Change the limit for a new scanner.
+         * @param limit New limit.
+         */
+        void setLimit(final int limit) {
+            this.limit = limit;
+        }
+
+        boolean isEmpty() {
+            return position == limit;
+        }
+    }
+
+    /**
+     * Save the state of the scan.
+     * @return Captured state.
+     */
+    State saveState() {
+        return new State(position, limit, line);
+    }
+
+    /**
+     * Restore the state of the scan.
+     * @param state Captured state.
+     */
+    void restoreState(final State state) {
+        position = state.position;
+        line     = state.line;
+
+        reset(position);
+    }
+
+    /**
+     * Returns true of scanner is at end of input
+     * @return true if no more input
+     */
+    protected final boolean atEOF() {
+        return position == limit;
+    }
+
+    /**
+     * Get the ith character from the content.
+     * @param i Index of character.
+     * @return ith character or '\0' if beyond limit.
+     */
+    protected final char charAt(final int i) {
+        // Get a character from the content, '\0' if beyond the end of file.
+        return i < limit ? content[i] : '\0';
+    }
+
+    /**
+     * Reset to a character position.
+     * @param i Position in content.
+     */
+    protected final void reset(final int i) {
+        ch0 = charAt(i);
+        ch1 = charAt(i + 1);
+        ch2 = charAt(i + 2);
+        ch3 = charAt(i + 3);
+        position = i < limit? i : limit;
+    }
+
+    /**
+     * Skip ahead a number of characters.
+     * @param n Number of characters to skip.
+     */
+    protected final void skip(final int n) {
+        if (n == 1 && !atEOF()) {
+            ch0 = ch1;
+            ch1 = ch2;
+            ch2 = ch3;
+            ch3 = charAt(position + 4);
+            position++;
+        } else if (n != 0) {
+            reset(position + n);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/Token.java b/nashorn/src/jdk/nashorn/internal/parser/Token.java
new file mode 100644
index 0000000..0012daa
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/Token.java
@@ -0,0 +1,152 @@
+/*
+ * 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.parser;
+
+import static jdk.nashorn.internal.parser.TokenKind.LITERAL;
+
+import jdk.nashorn.internal.runtime.Source;
+
+/**
+ * Basic parse/lex unit.
+ *
+ */
+public class Token {
+
+    private Token() {
+    }
+
+    /**
+     * Create a compact form of token information.
+     * @param type     Type of token.
+     * @param position Start position of the token in the source.
+     * @param length   Length of the token.
+     * @return Token descriptor.
+     */
+    public static long toDesc(final TokenType type, final int position, final int length) {
+        return (long)position << 32 |
+               (long)length   << 8  |
+               type.ordinal();
+    }
+
+    /**
+     * Extract token position from a token descriptor.
+     * @param token Token descriptor.
+     * @return Start position of the token in the source.
+     */
+    public static int descPosition(final long token) {
+        return (int)(token >>> 32);
+    }
+
+    /**
+     * Extract token length from a token descriptor.
+     * @param token Token descriptor.
+     * @return Length of the token.
+     */
+    public static int descLength(final long token) {
+        return (int)token >>> 8;
+    }
+
+    /**
+     * Extract token type from a token descriptor.
+     * @param token Token descriptor.
+     * @return Type of token.
+     */
+    public static TokenType descType(final long token) {
+        return TokenType.getValues()[(int)token & 0xff];
+    }
+
+    /**
+     * Change the token to use a new type.
+     *
+     * @param token   The original token.
+     * @param newType The new token type.
+     * @return The recast token.
+     */
+    public static long recast(final long token, final TokenType newType) {
+        return token & ~0xFFL | newType.ordinal();
+    }
+
+    /**
+     * Return a string representation of a token.
+     * @param source  Token source.
+     * @param token   Token descriptor.
+     * @param verbose True to include details.
+     * @return String representation.
+     */
+    public static String toString(final Source source, final long token, final boolean verbose) {
+        final TokenType type = Token.descType(token);
+        String result;
+
+        if (source != null && type.getKind() == LITERAL) {
+            result = source.getString(token);
+        } else {
+            result = type.getNameOrType();
+        }
+
+        if (verbose) {
+            final int position = Token.descPosition(token);
+            final int length = Token.descLength(token);
+            result += " (" + position + ", " + length + ")";
+        }
+
+        return result;
+    }
+
+    /**
+     * String conversion of token
+     *
+     * @param source the source
+     * @param token  the token
+     *
+     * @return token as string
+     */
+    public static String toString(final Source source, final long token) {
+        return Token.toString(source, token, false);
+    }
+
+    /**
+     * String conversion of token - version without source given
+     *
+     * @param token  the token
+     *
+     * @return token as string
+     */
+    public static String toString(final long token) {
+        return Token.toString(null, token, false);
+    }
+
+    /**
+     * Static hash code computation function token
+     *
+     * @param token a token
+     *
+     * @return hash code for token
+     */
+    public static int hashCode(final long token) {
+        return (int)(token ^ token >>> 32);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/TokenKind.java b/nashorn/src/jdk/nashorn/internal/parser/TokenKind.java
new file mode 100644
index 0000000..af3029d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/TokenKind.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.parser;
+
+/**
+ * Classification of token types.
+ */
+public enum TokenKind {
+    /** Error, EOF, EOL...*/
+    SPECIAL,
+    /** Unary operators. */
+    UNARY,
+    /** Binary operators. */
+    BINARY,
+    /** [] () {} */
+    BRACKET,
+    /** String recognized as a keyword. */
+    KEYWORD,
+    /** Literal constant. */
+    LITERAL,
+    /** IR only token. */
+    IR,
+    /** Token reserved for future usage. */
+    FUTURE,
+    /** Token reserved for future in strict mode. */
+    FUTURESTRICT
+}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/TokenLookup.java b/nashorn/src/jdk/nashorn/internal/parser/TokenLookup.java
new file mode 100644
index 0000000..56bd37c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/TokenLookup.java
@@ -0,0 +1,222 @@
+/*
+ * 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.parser;
+
+import static jdk.nashorn.internal.parser.TokenKind.SPECIAL;
+import static jdk.nashorn.internal.parser.TokenType.IDENT;
+
+/**
+ * Fast lookup of operators and keywords.
+ *
+ */
+public final class TokenLookup {
+    /**
+     * Lookup table for tokens.
+     */
+    private static final TokenType[] table;
+
+    /**
+     * Table base character.
+     */
+    private static final int tableBase = ' ';
+
+    /**
+     * Table base character.
+     */
+    private static final int tableLimit = '~';
+
+    /**
+     * Table size.
+     */
+    private static final int tableLength = tableLimit - tableBase + 1;
+
+    static {
+        // Construct the table.
+        table = new TokenType[tableLength];
+
+        // For each token type.
+        for (final TokenType tokenType : TokenType.getValues()) {
+            // Get the name.
+            final String name = tokenType.getName();
+
+            // Filter tokens.
+            if (name == null) {
+                continue;
+            }
+
+            // Ignore null and special.
+            if (tokenType.getKind() != SPECIAL) {
+                // Get the first character of the name.
+                final char first = name.charAt(0);
+                // Translate that character into a table index.
+                final int index = first - tableBase;
+                assert index < tableLength : "Token name does not fit lookup table";
+
+                // Get the length of the token so that the longest come first.
+                final int length = tokenType.getLength();
+                // Prepare for table insert.
+                TokenType prev = null;
+                TokenType next = table[index];
+
+                // Find the right spot in the table.
+                while(next != null && next.getLength() > length) {
+                    prev = next;
+                    next = next.getNext();
+                }
+
+                // Insert in table.
+                tokenType.setNext(next);
+
+                if (prev == null) {
+                    table[index] = tokenType;
+                } else {
+                    prev.setNext(tokenType);
+                }
+            }
+        }
+    }
+
+    private TokenLookup() {
+    }
+
+    /**
+     * Lookup keyword.
+     *
+     * @param content parse content char array
+     * @param position index of position to start looking
+     * @param length   max length to scan
+     *
+     * @return token type for keyword
+     */
+    public static TokenType lookupKeyword(final char[] content, final int position, final int length) {
+        assert table != null : "Token lookup table is not initialized";
+
+        // First character of keyword.
+        final char first = content[position];
+
+        // Must be lower case character.
+        if ('a' <= first && first <= 'z') {
+            // Convert to table index.
+            final int index = first - tableBase;
+            // Get first bucket entry.
+            TokenType tokenType = table[index];
+
+            // Search bucket list.
+            while (tokenType != null) {
+                final int tokenLength = tokenType.getLength();
+
+                // if we have a length match maybe a keyword.
+                if (tokenLength == length) {
+                    // Do an exact compare of string.
+                    final String name = tokenType.getName();
+                    int i;
+                    for (i = 0; i < length; i++) {
+                        if (content[position + i] != name.charAt(i)) {
+                            break;
+                        }
+                    }
+
+                    if (i == length) {
+                        // Found a match.
+                        return tokenType;
+                    }
+                } else if (tokenLength < length) {
+                    // Rest of tokens are shorter.
+                    break;
+                }
+
+                // Try next token.
+                tokenType = tokenType.getNext();
+            }
+        }
+
+        // Not found.
+        return IDENT;
+    }
+
+
+    /**
+     * Lookup operator.
+     *
+     * @param ch0 0th char in stream
+     * @param ch1 1st char in stream
+     * @param ch2 2nd char in stream
+     * @param ch3 3rd char in stream
+     *
+     * @return the token type for the operator
+     */
+    public static TokenType lookupOperator(final char ch0, final char ch1, final char ch2, final char ch3) {
+        assert table != null : "Token lookup table is not initialized";
+
+        // Ignore keyword entries.
+        if (tableBase < ch0 && ch0 <= tableLimit && !('a' <= ch0 && ch0 <= 'z')) {
+            // Convert to index.
+            final int index = ch0 - tableBase;
+            // Get first bucket entry.
+            TokenType tokenType = table[index];
+
+            // Search bucket list.
+            while (tokenType != null) {
+                final String name = tokenType.getName();
+
+                switch (name.length()) {
+                case 1:
+                    // One character entry.
+                    return tokenType;
+                case 2:
+                    // Two character entry.
+                    if (name.charAt(1) == ch1) {
+                        return tokenType;
+                    }
+                    break;
+                case 3:
+                    // Three character entry.
+                    if (name.charAt(1) == ch1 &&
+                        name.charAt(2) == ch2) {
+                        return tokenType;
+                    }
+                    break;
+                case 4:
+                    // Four character entry.
+                    if (name.charAt(1) == ch1 &&
+                        name.charAt(2) == ch2 &&
+                        name.charAt(3) == ch3) {
+                        return tokenType;
+                    }
+                    break;
+                default:
+                    break;
+                }
+
+                // Try next token.
+                tokenType = tokenType.getNext();
+            }
+        }
+
+        // Not found.
+        return null;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/TokenStream.java b/nashorn/src/jdk/nashorn/internal/parser/TokenStream.java
new file mode 100644
index 0000000..ee81ce3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/TokenStream.java
@@ -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.parser;
+
+/**
+ *
+ */
+
+/**
+ * Handles streaming of tokens between lexer and parser.
+ *
+ */
+public class TokenStream {
+    /** Initial buffer size. */
+    private static final int INITIAL_SIZE = 256;
+
+    /** Token buffer. */
+    private long[] buffer;
+
+    /** Token count. */
+    private int count;
+
+    /** Cursor to write position in buffer */
+    private int in;
+
+    /** Cursor to read position in buffer */
+    private int out;
+
+    /** Base index in buffer */
+    private int base;
+
+    /**
+     * Constructor.
+     */
+    public TokenStream() {
+        buffer = new long[INITIAL_SIZE];
+        count = 0;
+        in = 0;
+        out = 0;
+        base = 0;
+    }
+
+    /**
+     * Get the next position in the buffer.
+     * @param position Current position in buffer.
+     * @return Next position in buffer.
+     */
+    private int next(final int position) {
+        // Next position.
+        int next = position + 1;
+
+        // If exceeds buffer length.
+        if (next >= buffer.length) {
+            // Wrap around.
+            next = 0;
+        }
+
+        return next;
+    }
+
+     /**
+     * Get the index position in the buffer.
+     * @param k Seek position.
+     * @return Position in buffer.
+     */
+    private int index(final int k) {
+        // Bias k.
+        int index = k - (base - out);
+
+        // If wrap around.
+        if (index >= buffer.length) {
+            index -= buffer.length;
+        }
+
+        return index;
+    }
+
+    /**
+     * Test to see if stream is empty.
+     * @return True if stream is empty.
+     */
+    public boolean isEmpty() {
+        return count == 0;
+    }
+
+    /**
+     * Test to see if stream is full.
+     * @return True if stream is full.
+     */
+    public boolean isFull() {
+        return count == buffer.length;
+    }
+
+    /**
+     * Get the number of tokens in the buffer.
+     * @return Number of tokens.
+     */
+    public int count() {
+        return count;
+    }
+
+    /**
+     * Get the index of the first token in the stream.
+     * @return Index of first buffered token in the stream.
+     */
+    public int first() {
+        return base;
+    }
+
+    /**
+     * Get the index of the last token in the stream.
+     * @return Index of last buffered token in the stream.
+     */
+    public int last() {
+        return base + count - 1;
+    }
+
+    /**
+     * Remove the last token in the stream.
+     */
+    public void removeLast() {
+        if (count != 0) {
+            count--;
+            in--;
+
+            if (in < 0) {
+                in = buffer.length - 1;
+            }
+        }
+    }
+
+    /**
+     * Put a token descriptor to the stream.
+     * @param token Token descriptor to add.
+     */
+    public void put(final long token) {
+        if (count == buffer.length) {
+            grow();
+        }
+
+        buffer[in] = token;
+        count++;
+        in = next(in);
+    }
+
+    /**
+     * Get the kth token descriptor from the stream.
+     * @param k index
+     * @return Token descriptor.
+     */
+    public long get(final int k) {
+        return buffer[index(k)];
+    }
+
+    /**
+     * Advances the base of the stream.
+     * @param k Position of token to be the new base.
+     */
+    public void commit(final int k) {
+        // Advance out.
+        out = index(k);
+        // Adjust count.
+        count -= k - base;
+        // Set base.
+        base = k;
+    }
+
+    /**
+     * Grow the buffer to accommodate more token descriptors.
+     */
+    public void grow() {
+        // Allocate new buffer.
+        final long[] newBuffer = new long[buffer.length * 2];
+
+        // If single chunk.
+        if (in > out) {
+            System.arraycopy(buffer, out, newBuffer, 0, count);
+        } else {
+            final int portion = buffer.length - out;
+            System.arraycopy(buffer, out, newBuffer, 0, portion);
+            System.arraycopy(buffer, 0, newBuffer, portion, count - portion);
+        }
+
+        // Update buffer and indices.
+        out = 0;
+        in = count;
+        buffer = newBuffer;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/TokenType.java b/nashorn/src/jdk/nashorn/internal/parser/TokenType.java
new file mode 100644
index 0000000..9a2b7b2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/parser/TokenType.java
@@ -0,0 +1,287 @@
+/*
+ * 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.parser;
+
+import static jdk.nashorn.internal.parser.TokenKind.BINARY;
+import static jdk.nashorn.internal.parser.TokenKind.BRACKET;
+import static jdk.nashorn.internal.parser.TokenKind.FUTURE;
+import static jdk.nashorn.internal.parser.TokenKind.FUTURESTRICT;
+import static jdk.nashorn.internal.parser.TokenKind.IR;
+import static jdk.nashorn.internal.parser.TokenKind.KEYWORD;
+import static jdk.nashorn.internal.parser.TokenKind.LITERAL;
+import static jdk.nashorn.internal.parser.TokenKind.SPECIAL;
+import static jdk.nashorn.internal.parser.TokenKind.UNARY;
+
+/**
+ * Description of all the JavaScript tokens.
+ */
+@SuppressWarnings("javadoc")
+public enum TokenType {
+    ERROR          (SPECIAL,  null),
+    EOF            (SPECIAL,  null),
+    EOL            (SPECIAL,  null),
+
+    NOT            (UNARY,   "!",    14, false),
+    NE             (BINARY,  "!=",    9, true),
+    NE_STRICT      (BINARY,  "!==",   9, true),
+    MOD            (BINARY,  "%",    13, true),
+    ASSIGN_MOD     (BINARY,  "%=",    2, false),
+    BIT_AND        (BINARY,  "&",     8, true),
+    AND            (BINARY,  "&&",    5, true),
+    ASSIGN_BIT_AND (BINARY,  "&=",    2, false),
+    LPAREN         (BRACKET, "(",    16, true),
+    RPAREN         (BRACKET, ")",     0, true),
+    MUL            (BINARY,  "*",    13, true),
+    ASSIGN_MUL     (BINARY,  "*=",    2, false),
+    ADD            (BINARY,  "+",    12, true),
+    INCPREFIX      (UNARY,   "++",   15, true),
+    ASSIGN_ADD     (BINARY,  "+=",    2, false),
+    COMMARIGHT     (BINARY,  ",",     1, true),
+    SUB            (BINARY,  "-",    12, true),
+    DECPREFIX      (UNARY,   "--",   15, true),
+    ASSIGN_SUB     (BINARY,  "-=",    2, false),
+    PERIOD         (BRACKET, ".",    17, true),
+    DIV            (BINARY,  "/",    13, true),
+    ASSIGN_DIV     (BINARY,  "/=",    2, false),
+    COLON          (BINARY,  ":"),
+    SEMICOLON      (BINARY,  ";"),
+    LT             (BINARY,  "<",    10, true),
+    SHL            (BINARY,  "<<",   11, true),
+    ASSIGN_SHL     (BINARY,  "<<=",   2, false),
+    LE             (BINARY,  "<=",   10, true),
+    ASSIGN         (BINARY,  "=",     2, false),
+    EQ             (BINARY,  "==",    9, true),
+    EQ_STRICT      (BINARY,  "===",   9, true),
+    BIND           (BINARY,  "=>",    9, true),
+    GT             (BINARY,  ">",    10, true),
+    GE             (BINARY,  ">=",   10, true),
+    SAR            (BINARY,  ">>",   11, true),
+    ASSIGN_SAR     (BINARY,  ">>=",   2, false),
+    SHR            (BINARY,  ">>>",  11, true),
+    ASSIGN_SHR     (BINARY,  ">>>=",  2, false),
+    TERNARY        (BINARY,  "?",     3, false),
+    LBRACKET       (BRACKET, "[",    17, true),
+    RBRACKET       (BRACKET, "]",     0, true),
+    BIT_XOR        (BINARY,  "^",     7, true),
+    ASSIGN_BIT_XOR (BINARY,  "^=",    2, false),
+    LBRACE         (BRACKET,  "{"),
+    BIT_OR         (BINARY,  "|",     6, true),
+    ASSIGN_BIT_OR  (BINARY,  "|=",    2, false),
+    OR             (BINARY,  "||",    4, true),
+    RBRACE         (BRACKET, "}"),
+    BIT_NOT        (BINARY,  "~",    14, false),
+
+    // ECMA 7.6.1.1 Keywords, 7.6.1.2 Future Reserved Words.
+    // All other Java keywords are commented out.
+
+//  ABSTRACT       (FUTURE,   "abstract"),
+//  BOOLEAN        (FUTURE,   "boolean"),
+    BREAK          (KEYWORD,  "break"),
+//  BYTE           (FUTURE,   "byte"),
+    CASE           (KEYWORD,  "case"),
+    CATCH          (KEYWORD,  "catch"),
+//  CHAR           (FUTURE,   "char"),
+    CLASS          (FUTURE,   "class"),
+    CONST          (FUTURE,  "const"),
+    CONTINUE       (KEYWORD,  "continue"),
+    DEBUGGER       (KEYWORD,  "debugger"),
+    DEFAULT        (KEYWORD,  "default"),
+    DELETE         (UNARY,    "delete",     14, false),
+    DO             (KEYWORD,  "do"),
+//  DOUBLE         (FUTURE,   "double"),
+//  EACH           (KEYWORD,  "each"),  // Contextual.
+    ELSE           (KEYWORD,  "else"),
+    ENUM           (FUTURE,   "enum"),
+    EXPORT         (FUTURE,   "export"),
+    EXTENDS        (FUTURE,   "extends"),
+    FALSE          (LITERAL,  "false"),
+//  FINAL          (FUTURE,   "final"),
+    FINALLY        (KEYWORD,  "finally"),
+//  FLOAT          (FUTURE,   "float"),
+    FOR            (KEYWORD,  "for"),
+    FUNCTION       (KEYWORD,  "function"),
+//  GET            (KEYWORD,  "get"), // Contextual.
+//  GOTO           (FUTURE,   "goto"),
+    IF             (KEYWORD,   "if"),
+    IMPLEMENTS     (FUTURESTRICT,   "implements"),
+    IMPORT         (FUTURE,   "import"),
+    IN             (BINARY,   "in",         10, true),
+    INSTANCEOF     (BINARY,   "instanceof", 10, true),
+//  INT            (FUTURE,   "int"),
+    INTERFACE      (FUTURESTRICT,   "interface"),
+    LET            (FUTURESTRICT,   "let"),
+//  LONG           (FUTURE,   "long"),
+//  NATIVE         (FUTURE,   "native"),
+    NEW            (UNARY,    "new",        17, false),
+    NULL           (LITERAL,  "null"),
+    PACKAGE        (FUTURESTRICT,   "package"),
+    PRIVATE        (FUTURESTRICT,   "private"),
+    PROTECTED      (FUTURESTRICT,   "protected"),
+    PUBLIC         (FUTURESTRICT,   "public"),
+    RETURN         (KEYWORD,  "return"),
+//  SET            (KEYWORD,  "set"), // Contextual.
+//  SHORT          (FUTURE,   "short"),
+    STATIC         (FUTURESTRICT,   "static"),
+    SUPER          (FUTURE,   "super"),
+    SWITCH         (KEYWORD,  "switch"),
+//  SYNCHRONIZED   (FUTURE,   "synchronized"),
+    THIS           (KEYWORD,  "this"),
+    THROW          (KEYWORD,  "throw"),
+//  THROWS         (FUTURE,   "throws"),
+//  TRANSIENT      (FUTURE,   "transient"),
+    TRUE           (LITERAL,  "true"),
+    TRY            (KEYWORD,  "try"),
+    TYPEOF         (UNARY,    "typeof",     14, false),
+    VAR            (KEYWORD,  "var"),
+    VOID           (UNARY,    "void",       14, false),
+//  VOLATILE       (FUTURE,   "volatile"),
+    WHILE          (KEYWORD,  "while"),
+    WITH           (KEYWORD,  "with"),
+    YIELD          (FUTURESTRICT,  "yield"),
+
+    DECIMAL        (LITERAL,  null),
+    OCTAL          (LITERAL,  null),
+    HEXADECIMAL    (LITERAL,  null),
+    FLOATING       (LITERAL,  null),
+    STRING         (LITERAL,  null),
+    ESCSTRING      (LITERAL,  null),
+    EXECSTRING     (LITERAL,  null),
+    IDENT          (LITERAL,  null),
+    REGEX          (LITERAL,  null),
+    XML            (LITERAL,  null),
+    OBJECT         (LITERAL,  null),
+    ARRAY          (LITERAL,  null),
+
+    COMMALEFT      (IR,       null),
+    CONVERT        (IR,       null),
+    DISCARD        (IR,       null),
+    DECPOSTFIX     (IR,       null),
+    INCPOSTFIX     (IR,       null);
+
+    /** Next token kind in token lookup table. */
+    private TokenType next;
+
+    /** Classification of token. */
+    private final TokenKind kind;
+
+    /** Printable name of token. */
+    private final String name;
+
+    /** Operator precedence. */
+    private final int precedence;
+
+    /** Left associativity */
+    private final boolean isLeftAssociative;
+
+    /** Cache values to avoid cloning. */
+    private static final TokenType[] values;
+
+    TokenType(final TokenKind kind, final String name) {
+        next              = null;
+        this.kind         = kind;
+        this.name         = name;
+        precedence        = 0;
+        isLeftAssociative = false;
+    }
+
+    TokenType(final TokenKind kind, final String name, final int precedence, final boolean isLeftAssociative) {
+        next                   = null;
+        this.kind              = kind;
+        this.name              = name;
+        this.precedence        = precedence;
+        this.isLeftAssociative = isLeftAssociative;
+    }
+
+    /**
+     * Determines if the token has greater precedence than other.
+     * @param other  Compare token.
+     * @param isLeft Is to the left of the other.
+     * @return True if greater precedence.
+     */
+    public boolean needsParens(final TokenType other, final boolean isLeft) {
+        return other.precedence != 0 &&
+               (precedence > other.precedence ||
+               precedence == other.precedence && isLeftAssociative && !isLeft);
+    }
+
+    /**
+     * Determines if the type is a valid operator.
+     * @param noIn TRUE if IN operator should be ignored.
+     * @return TRUE if valid operator.
+     */
+    public boolean isOperator(final boolean noIn) {
+        return kind == BINARY && (!noIn || this != IN) && precedence != 0;
+    }
+
+    /**
+     * Accessors.
+     */
+    public int getLength() {
+        assert name != null : "Token name not set";
+        return name.length();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getNameOrType() {
+        return name == null ? super.name().toLowerCase() : name;
+    }
+
+    public TokenType getNext() {
+        return next;
+    }
+
+    public void setNext(final TokenType next) {
+        this.next = next;
+    }
+
+    public TokenKind getKind() {
+        return kind;
+    }
+
+    public int getPrecedence() {
+        return precedence;
+    }
+
+    public boolean isLeftAssociative() {
+        return isLeftAssociative;
+    }
+
+    boolean startsWith(final char c) {
+        return name != null && name.length() > 0 && name.charAt(0) == c;
+    }
+
+    static TokenType[] getValues() {
+       return values;
+    }
+
+    static {
+        // Avoid cloning of enumeration.
+        values = TokenType.values();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
new file mode 100644
index 0000000..9f6867d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
@@ -0,0 +1,373 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.ACCESSOR_TYPES;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.LOG;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_TYPE;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGetter;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGuardBoxedPrimitiveSetter;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createSetter;
+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.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.lookup.Lookup;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
+
+/**
+ * An AccessorProperty is the most generic property type. An AccessorProperty is
+ * represented as fields in a ScriptObject class.
+ *
+ * @see SpillProperty
+ */
+public class AccessorProperty extends Property {
+    private static final MethodHandle REPLACE_MAP = findOwnMH("replaceMap", Object.class, Object.class, PropertyMap.class, String.class, Class.class, Class.class);
+
+    private static final int NOOF_TYPES = getNumberOfAccessorTypes();
+
+    /** Property getter cache */
+    private MethodHandle[] getters = new MethodHandle[NOOF_TYPES];
+
+    private static final MethodType[] ACCESSOR_GETTER_TYPES = new MethodType[NOOF_TYPES];
+    private static final MethodType[] ACCESSOR_SETTER_TYPES = new MethodType[NOOF_TYPES];
+
+    /** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
+    private MethodHandle primitiveGetter;
+
+    /** Seed setter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
+    private MethodHandle primitiveSetter;
+
+    /** Seed getter for the Object version of this field */
+    private MethodHandle objectGetter;
+
+    /** Seed setter for the Object version of this field */
+    private MethodHandle objectSetter;
+
+    /**
+     * Current type of this object, in object only mode, this is an Object.class. In dual-fields mode
+     * null means undefined, and primitive types are allowed. The reason a special type is used for
+     * undefined, is that are no bits left to represent it in primitive types
+     */
+    private Class<?> currentType;
+
+    static {
+        for (int i = 0; i < NOOF_TYPES; i++) {
+            final Type type = ACCESSOR_TYPES.get(i);
+            ACCESSOR_GETTER_TYPES[i] = MH.type(type.getTypeClass(), Object.class);
+            ACCESSOR_SETTER_TYPES[i] = MH.type(void.class, Object.class, type.getTypeClass());
+        }
+    }
+
+    /**
+     * Delegate constructor. This is used when adding properties to the Global scope, which
+     * is necessary for outermost levels in a script (the ScriptObject is represented by
+     * a JO-prefixed ScriptObject class, but the properties need to be in the Global scope
+     * and are thus rebound with that as receiver
+     *
+     * @param property  accessor property to rebind
+     * @param delegate  delegate script object to rebind receiver to
+     */
+    public AccessorProperty(final AccessorProperty property, final ScriptObject delegate) {
+        this(property);
+
+        this.getters = new MethodHandle[NOOF_TYPES];
+
+        this.primitiveGetter = bindTo(primitiveGetter, delegate);
+        this.primitiveSetter = bindTo(primitiveSetter, delegate);
+        this.objectGetter    = bindTo(objectGetter, delegate);
+        this.objectSetter    = bindTo(objectSetter, delegate);
+
+        setCurrentType(property.getCurrentType());
+    }
+
+    /**
+     * Constructor. Similar to the constructor with both primitive getters and setters, the difference
+     * here being that only one getter and setter (setter is optional for non writable fields) is given
+     * to the constructor, and the rest are created from those. Used e.g. by Nasgen classes
+     *
+     * @param key    the property key
+     * @param flags  the property flags
+     * @param slot   the property field number or spill slot
+     * @param getter the property getter
+     * @param setter the property setter or null if non writable, non configurable
+     */
+    public AccessorProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) {
+        super(key, flags, slot);
+
+        // we don't need to prep the setters these will never be invalidated as this is a nasgen
+        // or known type getter/setter. No invalidations will take place
+
+        final Class<?> getterType = getter.type().returnType();
+        final Class<?> setterType = setter == null ? null : setter.type().parameterType(1);
+
+        assert setterType == null || setterType == getterType;
+
+        if (getterType.isPrimitive()) {
+            for (int i = 0; i < NOOF_TYPES; i++) {
+                getters[i] = MH.asType(
+                    Lookup.filterReturnType(
+                        getter,
+                        getAccessorType(i).getTypeClass()),
+                    ACCESSOR_GETTER_TYPES[i]);
+            }
+        } else {
+            //this will work as the object setter and getter will be converted appropriately
+            objectGetter = getter;
+            objectSetter = setter;
+        }
+
+        setCurrentType(getterType);
+    }
+
+    /**
+     * Constructor for dual field AccessorPropertys.
+     *
+     * @param key              property key
+     * @param flags            property flags
+     * @param structure        structure for objects associated with this property
+     * @param slot             property field number or spill slot
+     */
+    public AccessorProperty(final String key, final int flags, final Class<?> structure, final int slot) {
+        super(key, flags, slot);
+
+        /*
+         *
+         * primitiveGetter and primitiveSetter are only used in dual fields mode. Setting them to null also
+         * works in dual field mode, it only means that the property never has a primitive
+         * representation.
+         */
+        primitiveGetter = null;
+        primitiveSetter = null;
+
+        final MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+        if (isParameter() && hasArguments()) {
+            final MethodHandle arguments   = MH.getter(MethodHandles.lookup(), structure, "arguments", Object.class);
+            final MethodHandle argumentsSO = MH.asType(arguments, arguments.type().changeReturnType(ScriptObject.class));
+
+            objectGetter = MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot);
+            objectSetter = MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot);
+        } else {
+            final String fieldNameObject    = ObjectClassGenerator.getFieldName(slot, Type.OBJECT);
+            final String fieldNamePrimitive = ObjectClassGenerator.getFieldName(slot, ObjectClassGenerator.PRIMITIVE_TYPE);
+
+            objectGetter = MH.getter(lookup, structure, fieldNameObject, Type.OBJECT.getTypeClass());
+            objectSetter = MH.setter(lookup, structure, fieldNameObject, Type.OBJECT.getTypeClass());
+
+            if (!OBJECT_FIELDS_ONLY) {
+                primitiveGetter = MH.getter(lookup, structure, fieldNamePrimitive, PRIMITIVE_TYPE.getTypeClass());
+                primitiveSetter = MH.setter(lookup, structure, fieldNamePrimitive, PRIMITIVE_TYPE.getTypeClass());
+            }
+        }
+
+        Class<?> initialType = null;
+
+        if (OBJECT_FIELDS_ONLY || isAlwaysObject()) {
+            initialType = Object.class;
+        } else if (!canBePrimitive()) {
+            info(key + " cannot be primitive");
+            initialType = Object.class;
+        } else {
+            info(key + " CAN be primitive");
+            if (!canBeUndefined()) {
+                info(key + " is always defined");
+                initialType = int.class; //double works too for less type invalidation, but this requires experimentation, e.g. var x = 17; x += 2 will turn it into double now because of lack of range analysis
+            }
+        }
+
+        // is always object means "is never initialized to undefined, and always of object type
+        setCurrentType(initialType);
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param property  source property
+     */
+    protected AccessorProperty(final AccessorProperty property) {
+        super(property);
+
+        this.getters         = property.getters;
+        this.primitiveGetter = property.primitiveGetter;
+        this.primitiveSetter = property.primitiveSetter;
+        this.objectGetter    = property.objectGetter;
+        this.objectSetter    = property.objectSetter;
+
+        setCurrentType(property.getCurrentType());
+    }
+
+    private static MethodHandle bindTo(final MethodHandle mh, final Object receiver) {
+        if (mh == null) {
+            return null;
+        }
+
+        return MH.dropArguments(MH.bindTo(mh, receiver), 0, Object.class);
+    }
+
+    @Override
+    protected Property copy() {
+        return new AccessorProperty(this);
+    }
+
+    @Override
+    public MethodHandle getGetter(final Class<?> type) {
+        final int i = getAccessorTypeIndex(type);
+        if (getters[i] == null) {
+            getters[i] = debug(
+                MH.asType(
+                    createGetter(
+                        currentType,
+                        type,
+                        primitiveGetter,
+                        objectGetter),
+                    ACCESSOR_GETTER_TYPES[i]),
+                currentType,
+                type,
+                "get");
+        }
+
+        return getters[i];
+    }
+
+    private Property getWiderProperty(final Class<?> type) {
+        final AccessorProperty newProperty = new AccessorProperty(this);
+        newProperty.invalidate(type);
+        return newProperty;
+    }
+
+    private PropertyMap getWiderMap(final PropertyMap oldMap, final Property newProperty) {
+        final PropertyMap newMap = oldMap.replaceProperty(this, newProperty);
+        assert oldMap.size() > 0;
+        assert newMap.size() == oldMap.size();
+        return newMap;
+    }
+
+    // the final three arguments are for debug printout purposes only
+    @SuppressWarnings("unused")
+    private static Object replaceMap(final Object sobj, final PropertyMap newMap, final String key, final Class<?> oldType, final Class<?> newType) {
+        if (DEBUG_FIELDS) {
+            final PropertyMap oldMap = ((ScriptObject)sobj).getMap();
+            info("Type change for '" + key + "' " + oldType + "=>" + newType);
+            finest("setting map " + sobj + " from " + Debug.id(oldMap) + " to " + Debug.id(newMap) + " " + oldMap + " => " + newMap);
+        }
+        ((ScriptObject)sobj).setMap(newMap);
+        return sobj;
+    }
+
+    private MethodHandle generateSetter(final Class<?> forType, final Class<?> type) {
+        MethodHandle mh = createSetter(forType, type, primitiveSetter, objectSetter);
+        mh = MH.asType(mh, ACCESSOR_SETTER_TYPES[getAccessorTypeIndex(type)]); //has to be the case for invokeexact to work in ScriptObject
+        mh = debug(mh, currentType, type, "set");
+        return mh;
+    }
+
+    @Override
+    public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
+        final int i            = getAccessorTypeIndex(type);
+        final int ci           = currentType == null ? -1 : getAccessorTypeIndex(currentType);
+        final Class<?> forType = currentType == null ? type : currentType;
+
+        //if we are asking for an object setter, but are still a primitive type, we might try to box it
+
+        if (needsInvalidator(i, ci)) {
+            final Property     newProperty = getWiderProperty(type);
+            final PropertyMap  newMap      = getWiderMap(currentMap, newProperty);
+            final MethodHandle widerSetter = newProperty.getSetter(type, newMap);
+            final MethodHandle explodeTypeSetter = MH.filterArguments(widerSetter, 0, MH.insertArguments(REPLACE_MAP, 1, newMap, getKey(), currentType, type));
+            if (currentType != null && currentType.isPrimitive() && type == Object.class) {
+                //might try a box check on this to avoid widening field to object storage
+                return createGuardBoxedPrimitiveSetter(currentType, generateSetter(currentType, currentType), explodeTypeSetter);
+            }
+            return explodeTypeSetter;
+        }
+
+        return generateSetter(forType, type);
+    }
+
+    @Override
+    public boolean canChangeType() {
+        if (OBJECT_FIELDS_ONLY) {
+            return false;
+        }
+        return currentType != Object.class && (isConfigurable() || isWritable());
+    }
+
+    private boolean needsInvalidator(final int ti, final int fti) {
+        return canChangeType() && ti > fti;
+    }
+
+    private void invalidate(final Class<?> newType) {
+        getters = new MethodHandle[NOOF_TYPES];
+        setCurrentType(newType);
+    }
+
+    private static void finest(final String str) {
+        if (DEBUG_FIELDS) {
+            LOG.finest(str);
+        }
+    }
+
+    private static void info(final String str) {
+        if (DEBUG_FIELDS) {
+            LOG.info(str);
+        }
+    }
+
+    private MethodHandle debug(final MethodHandle mh, final Class<?> forType, final Class<?> type, final String tag) {
+        if (DEBUG_FIELDS) {
+           final MethodHandle mhd = MethodHandleFactory.addDebugPrintout(
+               LOG,
+               mh,
+               tag + " '" + getKey() + "' (property="+ Debug.id(this) + ", forType=" + stripName(forType) + ", type=" + stripName(type) + ')');
+           return mhd;
+        }
+        return mh;
+    }
+
+    private void setCurrentType(final Class<?> currentType) {
+        this.currentType = currentType;
+    }
+
+    @Override
+    public Class<?> getCurrentType() {
+        return currentType;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), AccessorProperty.class, name, MH.type(rtype, types));
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ArgumentSetter.java b/nashorn/src/jdk/nashorn/internal/runtime/ArgumentSetter.java
new file mode 100644
index 0000000..8546ead
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ArgumentSetter.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+
+/**
+ * A class with static helper methods invoked from generated bytecode for setting values of parameters of variable-arity
+ * functions.
+ */
+public final class ArgumentSetter {
+    private ArgumentSetter() {}
+
+    /** Method handle for setting a function argument at a given index in an arguments object. Used from generated bytecode */
+    public static final Call SET_ARGUMENT      = staticCallNoLookup(ArgumentSetter.class, "setArgument", void.class, Object.class, ScriptObject.class, int.class);
+
+    /** Method handle for setting a function argument at a given index in an arguments array. Used from generated bytecode */
+    public static final Call SET_ARRAY_ELEMENT = staticCallNoLookup(ArgumentSetter.class, "setArrayElement", void.class, Object.class, Object[].class, int.class);
+
+
+    /**
+     * Used from generated bytecode to invoke {@link ScriptObject#setArgument(int, Object)} without having to reorder
+     * the arguments on the stack. When we're generating a store into the argument, we first have the value on the
+     * stack, and only afterwards load the target object and the index.
+     * @param value the value to write at the given argument index.
+     * @param arguments the arguments object that we're writing the value to
+     * @param key the index of the argument
+     */
+    public static void setArgument(final Object value, final ScriptObject arguments, final int key) {
+        arguments.setArgument(key, value);
+    }
+
+    /**
+     * Used from generated bytecode to set a variable arity parameter - an array element - without having to reorder
+     * the arguments on the stack. When we're generating a store into the array, we first have the value on the
+     * stack, and only afterwards load the target array and the index.
+     * @param value the value to write at the given argument index.
+     * @param arguments the arguments array that we're writing the value to
+     * @param key the index of the argument
+     */
+    public static void setArrayElement(final Object value, final Object[] arguments, final int key) {
+        arguments[key] = value;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/BitVector.java b/nashorn/src/jdk/nashorn/internal/runtime/BitVector.java
new file mode 100644
index 0000000..cbf4eb8
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/BitVector.java
@@ -0,0 +1,278 @@
+/*
+ * 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;
+
+import java.util.Arrays;
+
+/**
+ * Faster implementation of BitSet
+ */
+public final class BitVector implements Cloneable {
+    /** Number of bits per slot. */
+    private static final int BITSPERSLOT = 64;
+
+    /** Growth quanta when resizing. */
+    private static final int SLOTSQUANTA = 4;
+
+    /** Shift for indexing. */
+    private static final int BITSHIFT = 6;
+
+    /** Mask for indexing. */
+    private static final int BITMASK = BITSPERSLOT - 1;
+
+    /** Bit area. */
+    private long[] bits;
+
+    /**
+     * Constructor.
+     */
+    public BitVector() {
+        this.bits = new long[SLOTSQUANTA];
+    }
+
+    /**
+     * Constructor
+     * @param length initial length in bits
+     */
+    public BitVector(final long length) {
+        final int need = (int)growthNeeded(length);
+        this.bits = new long[need];
+    }
+
+    /**
+     * Copy constructor
+     * @param bits a bits array from another bit vector
+     */
+    public BitVector(final long[] bits) {
+        this.bits = bits.clone();
+    }
+
+    /**
+     * Copy another BitVector into this one
+     * @param other the source
+     */
+    public void copy(final BitVector other) {
+        bits = other.bits.clone();
+    }
+
+    /**
+     * Calculate the number of slots need for the specified length of bits.
+     * @param length Number of bits required.
+     * @return Number of slots needed.
+     */
+    private static long slotsNeeded(final long length) {
+        return (length + BITMASK) >> BITSHIFT;
+    }
+
+    /**
+     * Calculate the number of slots need for the specified length of bits
+     * rounded to allocation quanta.
+     * @param length Number of bits required.
+     * @return Number of slots needed rounded to allocation quanta.
+     */
+    private static long growthNeeded(final long length) {
+        return (slotsNeeded(length) + SLOTSQUANTA - 1) / SLOTSQUANTA * SLOTSQUANTA;
+    }
+
+    /**
+     * Return a slot from bits, zero if slot is beyond length.
+     * @param index Slot index.
+     * @return Slot value.
+     */
+    private long slot(final int index) {
+        return 0 <= index && index < bits.length ? bits[index] : 0L;
+    }
+
+    /**
+     * Resize the bit vector to accommodate the new length.
+     * @param length Number of bits required.
+     */
+    public void resize(final long length) {
+        final int need = (int)growthNeeded(length);
+
+        if (bits.length != need) {
+            bits = Arrays.copyOf(bits, need);
+        }
+
+        final int shift = (int)(length & BITMASK);
+        int slot = (int)(length >> BITSHIFT);
+
+        if (shift != 0) {
+            bits[slot] &= (1L << shift) - 1;
+            slot++;
+        }
+
+        for ( ; slot < bits.length; slot++) {
+            bits[slot] = 0;
+        }
+    }
+
+    /**
+     * Set a bit in the bit vector.
+     * @param bit Bit number.
+     */
+    public void set(final long bit) {
+        bits[(int)(bit >> BITSHIFT)] |= (1L << (int)(bit & BITMASK));
+    }
+
+    /**
+     * Clear a bit in the bit vector.
+     * @param bit Bit number.
+     */
+    public void clear(final long bit) {
+        bits[(int)(bit >> BITSHIFT)] &= ~(1L << (int)(bit & BITMASK));
+    }
+
+    /**
+     * Toggle a bit in the bit vector.
+     * @param bit Bit number.
+     */
+    public void toggle(final long bit) {
+        bits[(int)(bit >> BITSHIFT)] ^= (1L << (int)(bit & BITMASK));
+    }
+
+    /**
+     * Sets all bits in the vector up to the length.
+     *
+     * @param length max bit where to stop setting bits
+     */
+    public void setTo(final long length) {
+        if (0 < length) {
+            final int lastWord = (int)(length >> BITSHIFT);
+            final long lastBits = (1L << (int)(length & BITMASK)) - 1L;
+            Arrays.fill(bits, 0, lastWord, ~0L);
+
+            if (lastBits != 0L) {
+                bits[lastWord] |= lastBits;
+            }
+        }
+    }
+
+    /**
+     * Clears all bits in the vector.
+     */
+    public void clearAll() {
+        Arrays.fill(bits, 0L);
+    }
+
+    /**
+     * Test if bit is set in the bit vector.
+     * @param bit Bit number.
+     * @return true if bit in question is set
+     */
+    public boolean isSet(final long bit) {
+        return (bits[(int)(bit >> BITSHIFT)] & (1L << (int)(bit & BITMASK))) != 0;
+    }
+
+    /**
+     * Test if a bit is clear in the bit vector.
+     * @param bit Bit number.
+     * @return true if bit in question is clear
+     */
+    public boolean isClear(final long bit) {
+        return (bits[(int)(bit >> BITSHIFT)] & (1L << (int)(bit & BITMASK))) == 0;
+    }
+
+    /**
+     * Shift bits to the left by shift.
+     * @param shift  Amount of shift.
+     * @param length Length of vector after shift.
+     */
+    public void shiftLeft(final long shift, final long length) {
+        if (shift != 0) {
+            final int leftShift  = (int)(shift & BITMASK);
+            final int rightShift = BITSPERSLOT - leftShift;
+            final int slotShift  = (int)(shift >> BITSHIFT);
+            final int slotCount  = bits.length - slotShift;
+            int slot, from;
+
+            if (leftShift == 0) {
+                for (slot = 0, from = slotShift; slot < slotCount; slot++, from++) {
+                    bits[slot] = slot(from);
+                }
+            } else {
+                for (slot = 0, from = slotShift; slot < slotCount; slot++) {
+                    bits[slot] = (slot(from) >>>  leftShift) | (slot(++from) <<  rightShift);
+                }
+            }
+        }
+
+        resize(length);
+    }
+
+    /**
+     * Shift bits to the right by shift.
+     * @param shift  Amount of shift.
+     * @param length Length of vector after shift.
+     */
+    public void shiftRight(final long shift, final long length) {
+        // Make room.
+        resize(length);
+
+        if (shift != 0) {
+            final int rightShift  = (int)(shift & BITMASK);
+            final int leftShift = BITSPERSLOT - rightShift;
+            final int slotShift  = (int)(shift >> BITSHIFT);
+            int slot, from;
+
+            if (leftShift == 0) {
+                for (slot = bits.length, from = slot - slotShift; slot >= slotShift;) {
+                    slot--; from--;
+                    bits[slot] = slot(from);
+                }
+            } else {
+                for (slot = bits.length, from = slot - slotShift; slot > 0;) {
+                    slot--; from--;
+                    bits[slot] = (slot(from - 1) >>>  leftShift) | (slot(from) <<  rightShift);
+                }
+            }
+        }
+
+        // Mask out surplus.
+        resize(length);
+    }
+
+    /**
+     * Set a bit range.
+     * @param fromIndex  from index (inclusive)
+     * @param toIndex    to index (exclusive)
+     */
+    public void setRange(final long fromIndex, final long toIndex) {
+        if (fromIndex < toIndex) {
+            final int firstWord = (int)(fromIndex >> BITSHIFT);
+            final int lastWord = (int)(toIndex - 1 >> BITSHIFT);
+            final long firstBits = (~0L << fromIndex);
+            final long lastBits = (~0L >>> -toIndex);
+            if (firstWord == lastWord) {
+                bits[firstWord] |= firstBits & lastBits;
+            } else {
+                bits[firstWord] |= firstBits;
+                Arrays.fill(bits, firstWord + 1, lastWord, ~0L);
+                bits[lastWord] |= lastBits;
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java
new file mode 100644
index 0000000..5fd1652
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+/**
+ * Interface for installing classes passed to the compiler.
+ * As only the code generating package (i.e. Context) knows about
+ * the ScriptLoader and it would be a security hazard otherwise
+ * the Compiler is given an installation interface for its code.
+ * <p>
+ * The compiler still retains most of the state around code emission
+ * and management internally, so this is to avoid passing around any
+ * logic that isn't directly related to installing a class
+ * @param <T> owner class type for this code installer
+ *
+ */
+public interface CodeInstaller<T> {
+    /**
+     * Return the owner for the CodeInstaller, e.g. a {@link Context}
+     * @return owner
+     */
+    public T getOwner();
+
+    /**
+     * Install a class
+     * @param className name of the class with / separation
+     * @param bytecode  bytecode
+     * @return the installed class
+     */
+    public Class<?> install(final String className, final byte[] bytecode);
+
+    /*
+     * Verify generated bytecode before emission. This is called back from the
+     * {@link ClassEmitter} or the {@link Compiler}. If the "--verify-code" parameter
+     * hasn't been given, this is a nop
+     *
+     * @param bytecode bytecode to verify
+     */
+    public void verify(final byte[] code);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ConsString.java b/nashorn/src/jdk/nashorn/internal/runtime/ConsString.java
new file mode 100644
index 0000000..9cf5155
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ConsString.java
@@ -0,0 +1,117 @@
+/*
+ * 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;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+/**
+ * This class represents a string composed of two parts which may themselves be
+ * instances of <tt>ConsString</tt> or {@link String}. Copying of characters to
+ * a proper string is delayed until it becomes necessary.
+ */
+public final class ConsString implements CharSequence {
+
+    private CharSequence left, right;
+    final private int length;
+    private boolean flat = false;
+
+    /**
+     * Constructor
+     *
+     * Takes two {@link CharSequence} instances that, concatenated, forms this {@code ConsString}
+     *
+     * @param left  left char sequence
+     * @param right right char sequence
+     */
+    public ConsString(final CharSequence left, final CharSequence right) {
+        assert left instanceof String || left instanceof ConsString;
+        assert right instanceof String || right instanceof ConsString;
+        this.left = left;
+        this.right = right;
+        length = left.length() + right.length();
+    }
+
+    @Override
+    public String toString() {
+        if (!flat) {
+            flatten();
+        }
+        return (String) left;
+    }
+
+    @Override
+    public int length() {
+        return length;
+    }
+
+    @Override
+    public char charAt(final int index) {
+        if (!flat) {
+            flatten();
+        }
+        return left.charAt(index);
+    }
+
+    @Override
+    public CharSequence subSequence(final int start, final int end) {
+        if (!flat) {
+            flatten();
+        }
+        return left.subSequence(start, end);
+    }
+
+    private void flatten() {
+        // We use iterative traversal as recursion may exceed the stack size limit.
+        final char[] chars = new char[length];
+        int pos = length;
+        // Strings are most often composed by appending to the end, which causes ConsStrings
+        // to be very unbalanced, with mostly single string elements on the right and a long
+        // linear list on the left. Traversing from right to left helps to keep the stack small
+        // in this scenario.
+        final Deque<CharSequence> stack = new ArrayDeque<>();
+        stack.addFirst(left);
+        CharSequence cs = right;
+
+        do {
+            if (cs instanceof ConsString) {
+                final ConsString cons = (ConsString) cs;
+                stack.addFirst(cons.left);
+                cs = cons.right;
+            } else {
+                final String str = (String) cs;
+                pos -= str.length();
+                str.getChars(0, str.length(), chars, pos);
+                cs = stack.isEmpty() ? null : stack.pollFirst();
+            }
+        } while (cs != null);
+
+        left = new String(chars);
+        right = "";
+        flat = true;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
new file mode 100644
index 0000000..1c4a08c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
@@ -0,0 +1,794 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT;
+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.lookup.Lookup.MH;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Constructor;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.PrivilegedAction;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
+import jdk.nashorn.internal.codegen.Compiler;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.debug.ASTWriter;
+import jdk.nashorn.internal.ir.debug.PrintVisitor;
+import jdk.nashorn.internal.parser.Parser;
+import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
+import jdk.nashorn.internal.runtime.options.Options;
+import sun.reflect.Reflection;
+
+/**
+ * This class manages the global state of execution. Context is immutable.
+ */
+public final class Context {
+
+    /**
+     * ContextCodeInstaller that has the privilege of installing classes in the Context.
+     * Can only be instantiated from inside the context and is opaque to other classes
+     */
+    public static class ContextCodeInstaller implements CodeInstaller<ScriptEnvironment> {
+        private final Context      context;
+        private final ScriptLoader loader;
+        private final CodeSource   codeSource;
+
+        private ContextCodeInstaller(final Context context, final ScriptLoader loader, final CodeSource codeSource) {
+            this.context    = context;
+            this.loader     = loader;
+            this.codeSource = codeSource;
+        }
+
+        /**
+         * Return the context for this installer
+         * @return context
+         */
+        @Override
+        public ScriptEnvironment getOwner() {
+            return context.env;
+        }
+
+        @Override
+        public Class<?> install(final String className, final byte[] bytecode) {
+            return loader.installClass(className, bytecode, codeSource);
+        }
+
+        @Override
+        public void verify(final byte[] code) {
+            context.verify(code);
+        }
+    }
+
+    /** Is Context global debug mode enabled ? */
+    public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug");
+
+    private static final ThreadLocal<ScriptObject> currentGlobal =
+        new ThreadLocal<ScriptObject>() {
+            @Override
+            protected ScriptObject initialValue() {
+                 return null;
+            }
+        };
+
+    /**
+     * Get the current global scope
+     * @return the current global scope
+     */
+    public static ScriptObject getGlobal() {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            // skip getCallerClass and getGlobal and get to the real caller
+            Class<?> caller = Reflection.getCallerClass(2);
+            ClassLoader callerLoader = caller.getClassLoader();
+
+            // Allow this method only for nashorn's own classes, objects
+            // package classes and Java adapter classes. Rest should
+            // have the necessary security permission.
+            if (callerLoader != myLoader &&
+                !(callerLoader instanceof StructureLoader) &&
+                !(JavaAdapterFactory.isAdapterClass(caller))) {
+                sm.checkPermission(new RuntimePermission("getNashornGlobal"));
+            }
+        }
+
+        return getGlobalTrusted();
+    }
+
+    /**
+     * Set the current global scope
+     * @param global the global scope
+     */
+    public static void setGlobal(final ScriptObject global) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("setNashornGlobal"));
+        }
+
+        if (global != null && !(global instanceof GlobalObject)) {
+            throw new IllegalArgumentException("global does not implement GlobalObject!");
+        }
+
+        setGlobalTrusted(global);
+    }
+
+    /**
+     * Get context of the current global
+     * @return current global scope's context.
+     */
+    public static Context getContext() {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("getNashornContext"));
+        }
+        return getContextTrusted();
+    }
+
+    /**
+     * Get current context's error writer
+     *
+     * @return error writer of the current context
+     */
+    public static PrintWriter getCurrentErr() {
+        final ScriptObject global = getGlobalTrusted();
+        return (global != null)? global.getContext().getErr() : new PrintWriter(System.err);
+    }
+
+    /**
+     * Output text to this Context's error stream
+     * @param str text to write
+     */
+    public static void err(final String str) {
+        err(str, true);
+    }
+
+    /**
+     * Output text to this Context's error stream, optionally with
+     * a newline afterwards
+     *
+     * @param str  text to write
+     * @param crlf write a carriage return/new line after text
+     */
+    @SuppressWarnings("resource")
+    public static void err(final String str, final boolean crlf) {
+        final PrintWriter err = Context.getCurrentErr();
+        if (err != null) {
+            if (crlf) {
+                err.println(str);
+            } else {
+                err.print(str);
+            }
+        }
+    }
+
+    /** Current environment. */
+    private final ScriptEnvironment env;
+
+    /** is this context in strict mode? Cached from env. as this is used heavily. */
+    public final boolean _strict;
+
+    /** class loader to resolve classes from script. */
+    private final ClassLoader  appLoader;
+
+    /** Class loader to load classes from -classpath option, if set. */
+    private final ClassLoader  classPathLoader;
+
+    /** Class loader to load classes compiled from scripts. */
+    private final ScriptLoader scriptLoader;
+
+    /** Current error manager. */
+    private final ErrorManager errors;
+
+    /** Empty map used for seed map for JO objects */
+    final PropertyMap emptyMap = PropertyMap.newEmptyMap(this);
+
+    private static final ClassLoader myLoader = Context.class.getClassLoader();
+    private static final StructureLoader sharedLoader;
+
+    static {
+        sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
+            @Override
+            public StructureLoader run() {
+                return new StructureLoader(myLoader, null);
+            }
+        });
+    }
+
+    /**
+     * ThrowErrorManager that throws ParserException upon error conditions.
+     */
+    public static class ThrowErrorManager extends ErrorManager {
+        @Override
+        public void error(final String message) {
+            throw new ParserException(message);
+        }
+
+        @Override
+        public void error(final ParserException e) {
+            throw e;
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param options options from command line or Context creator
+     * @param errors  error manger
+     * @param appLoader application class loader
+     */
+    public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader) {
+        this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param options options from command line or Context creator
+     * @param errors  error manger
+     * @param out     output writer for this Context
+     * @param err     error writer for this Context
+     * @param appLoader application class loader
+     */
+    public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("createNashornContext"));
+        }
+
+        this.env       = new ScriptEnvironment(options, out, err);
+        this._strict   = env._strict;
+        this.appLoader = appLoader;
+        this.scriptLoader = (ScriptLoader)AccessController.doPrivileged(
+             new PrivilegedAction<ClassLoader>() {
+                @Override
+                public ClassLoader run() {
+                    final StructureLoader structureLoader = new StructureLoader(sharedLoader, Context.this);
+                    return new ScriptLoader(structureLoader, Context.this);
+                }
+             });
+        this.errors    = errors;
+
+        // if user passed -classpath option, make a class loader with that and set it as
+        // thread context class loader so that script can access classes from that path.
+        final String classPath = options.getString("classpath");
+        if (! env._compile_only && classPath != null && !classPath.isEmpty()) {
+            // make sure that caller can create a class loader.
+            if (sm != null) {
+                sm.checkPermission(new RuntimePermission("createClassLoader"));
+            }
+            this.classPathLoader = NashornLoader.createClassLoader(classPath);
+        } else {
+            this.classPathLoader = null;
+        }
+
+        // print version info if asked.
+        if (env._version) {
+            getErr().println("nashorn " + Version.version());
+        }
+
+        if (env._fullversion) {
+            getErr().println("nashorn full version " + Version.fullVersion());
+        }
+    }
+
+    /**
+     * Get the error manager for this context
+     * @return error manger
+     */
+    public ErrorManager getErrorManager() {
+        return errors;
+    }
+
+    /**
+     * Get the script environment for this context
+     * @return script environment
+     */
+    public ScriptEnvironment getEnv() {
+        return env;
+    }
+
+    /**
+     * Get the output stream for this context
+     * @return output print writer
+     */
+    public PrintWriter getOut() {
+        return env.getOut();
+    }
+
+    /**
+     * Get the error stream for this context
+     * @return error print writer
+     */
+    public PrintWriter getErr() {
+        return env.getErr();
+    }
+
+    /**
+     * Get the PropertyMap of the current global scope
+     * @return the property map of the current global scope
+     */
+    public static PropertyMap getGlobalMap() {
+        return Context.getGlobalTrusted().getMap();
+    }
+
+    /**
+     * Compile a top level script.
+     *
+     * @param source the source
+     * @param scope  the scope
+     *
+     * @return top level function for script
+     */
+    public ScriptFunction compileScript(final Source source, final ScriptObject scope) {
+        return compileScript(source, scope, this.errors);
+    }
+
+    /**
+     * Entry point for {@code eval}
+     *
+     * @param initialScope The scope of this eval call
+     * @param string       Evaluated code as a String
+     * @param callThis     "this" to be passed to the evaluated code
+     * @param location     location of the eval call
+     * @param strict       is this {@code eval} call from a strict mode code?
+     *
+     * @return the return value of the {@code eval}
+     */
+    public Object eval(final ScriptObject initialScope, final String string, final Object callThis, final Object location, final boolean strict) {
+        final String  file       = (location == UNDEFINED || location == null) ? "<eval>" : location.toString();
+        final Source  source     = new Source(file, string);
+        final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval?
+        final ScriptObject global = Context.getGlobalTrusted();
+
+        ScriptObject scope = initialScope;
+
+        // ECMA section 10.1.1 point 2 says eval code is strict if it begins
+        // with "use strict" directive or eval direct call itself is made
+        // from from strict mode code. We are passed with caller's strict mode.
+        boolean strictFlag = directEval && strict;
+
+        Class<?> clazz = null;
+        try {
+            clazz = compile(source, new ThrowErrorManager(), strictFlag);
+        } catch (final ParserException e) {
+            e.throwAsEcmaException(global);
+            return null;
+        }
+
+        if (!strictFlag) {
+            // We need to get strict mode flag from compiled class. This is
+            // because eval code may start with "use strict" directive.
+            try {
+                strictFlag = clazz.getField(STRICT_MODE.tag()).getBoolean(null);
+            } catch (final NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+                //ignored
+                strictFlag = false;
+            }
+        }
+
+        // In strict mode, eval does not instantiate variables and functions
+        // in the caller's environment. A new environment is created!
+        if (strictFlag) {
+            // Create a new scope object
+            final ScriptObject strictEvalScope = ((GlobalObject)global).newObject();
+
+            // bless it as a "scope"
+            strictEvalScope.setIsScope();
+
+            // set given scope to be it's proto so that eval can still
+            // access caller environment vars in the new environment.
+            strictEvalScope.setProto(scope);
+            scope = strictEvalScope;
+        }
+
+        ScriptFunction func = getRunScriptFunction(clazz, scope);
+        Object evalThis;
+        if (directEval) {
+            evalThis = (callThis instanceof ScriptObject || strictFlag) ? callThis : global;
+        } else {
+            evalThis = global;
+        }
+
+        return ScriptRuntime.apply(func, evalThis);
+    }
+
+    /**
+     * Implementation of {@code load} Nashorn extension. Load a script file from a source
+     * expression
+     *
+     * @param scope  the scope
+     * @param from   source expression for script
+     *
+     * @return return value for load call (undefined)
+     *
+     * @throws IOException if source cannot be found or loaded
+     */
+    public Object load(final ScriptObject scope, final Object from) throws IOException {
+        Object src = (from instanceof ConsString)?  from.toString() : from;
+        Source source = null;
+
+        // load accepts a String (which could be a URL or a file name), a File, a URL
+        // or a ScriptObject that has "name" and "source" (string valued) properties.
+        if (src instanceof String) {
+            final String srcStr = (String)src;
+            final File   file   = new File(srcStr);
+            if (srcStr.indexOf(':') != -1) {
+                if (srcStr.startsWith("nashorn:")) {
+                    final String resource = "resources/" + srcStr.substring("nashorn:".length());
+                    // NOTE: even sandbox scripts should be able to load scripts in nashorn: scheme
+                    // These scripts are always available and are loaded from nashorn.jar's resources.
+                    source = AccessController.doPrivileged(
+                            new PrivilegedAction<Source>() {
+                                @Override
+                                public Source run() {
+                                    try {
+                                        final URL resURL = Context.class.getResource(resource);
+                                        return (resURL != null)? new Source(srcStr, resURL) : null;
+                                    } catch (final IOException exp) {
+                                        return null;
+                                    }
+                                }
+                            });
+                } else {
+                    URL url = null;
+                    try {
+                        //check for malformed url. if malformed, it may still be a valid file
+                        url = new URL(srcStr);
+                    } catch (final MalformedURLException e) {
+                        url = file.toURI().toURL();
+                    }
+                    source = new Source(url.toString(), url);
+                }
+            } else if (file.isFile()) {
+                source = new Source(srcStr, file);
+            }
+        } else if (src instanceof File && ((File)src).isFile()) {
+            final File file = (File)src;
+            source = new Source(file.getName(), file);
+        } else if (src instanceof URL) {
+            final URL url = (URL)src;
+            source = new Source(url.toString(), url);
+        } else if (src instanceof ScriptObject) {
+            final ScriptObject sobj = (ScriptObject)src;
+            if (sobj.has("script") && sobj.has("name")) {
+                final String script = JSType.toString(sobj.get("script"));
+                final String name   = JSType.toString(sobj.get("name"));
+                source = new Source(name, script);
+            }
+        }
+
+        if (source != null) {
+            return evaluateSource(source, scope, scope);
+        }
+
+        throw typeError("cant.load.script", ScriptRuntime.safeToString(from));
+    }
+
+    /**
+     * Load or get a structure class. Structure class names are based on the number of parameter fields
+     * and {@link AccessorProperty} fields in them. Structure classes are used to represent ScriptObjects
+     *
+     * @see ObjectClassGenerator
+     * @see AccessorProperty
+     * @see ScriptObject
+     *
+     * @param fullName  full name of class, e.g. jdk.nashorn.internal.objects.JO2P1 contains 2 fields and 1 parameter.
+     *
+     * @return the {@code Class<?>} for this structure
+     *
+     * @throws ClassNotFoundException if structure class cannot be resolved
+     */
+    public static Class<?> forStructureClass(final String fullName) throws ClassNotFoundException {
+        return Class.forName(fullName, true, sharedLoader);
+    }
+
+    /**
+     * Lookup a Java class. This is used for JSR-223 stuff linking in from
+     * {@link jdk.nashorn.internal.objects.NativeJava} and {@link jdk.nashorn.internal.runtime.NativeJavaPackage}
+     *
+     * @param fullName full name of class to load
+     *
+     * @return the {@code Class<?>} for the name
+     *
+     * @throws ClassNotFoundException if class cannot be resolved
+     */
+    public Class<?> findClass(final String fullName) throws ClassNotFoundException {
+        // check package access as soon as possible!
+        final int index = fullName.lastIndexOf('.');
+        if (index != -1) {
+            final SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                sm.checkPackageAccess(fullName.substring(0, index));
+            }
+        }
+
+        // try the script -classpath loader, if that is set
+        if (classPathLoader != null) {
+            try {
+                return Class.forName(fullName, true, classPathLoader);
+            } catch (final ClassNotFoundException ignored) {
+                // ignore, continue search
+            }
+        }
+
+        // Try finding using the "app" loader.
+        return Class.forName(fullName, true, appLoader);
+    }
+
+    /**
+     * Hook to print stack trace for a {@link Throwable} that occurred during
+     * execution
+     *
+     * @param t throwable for which to dump stack
+     */
+    public static void printStackTrace(final Throwable t) {
+        if (Context.DEBUG) {
+            t.printStackTrace(Context.getCurrentErr());
+        }
+    }
+
+    /**
+     * Verify generated bytecode before emission. This is called back from the
+     * {@link ObjectClassGenerator} or the {@link Compiler}. If the "--verify-code" parameter
+     * hasn't been given, this is a nop
+     *
+     * Note that verification may load classes -- we don't want to do that unless
+     * user specified verify option. We check it here even though caller
+     * may have already checked that flag
+     *
+     * @param bytecode bytecode to verify
+     */
+    public void verify(final byte[] bytecode) {
+        if (env._verify_code) {
+            // No verification when security manager is around as verifier
+            // may load further classes - which should be avoided.
+            if (System.getSecurityManager() == null) {
+                CheckClassAdapter.verify(new ClassReader(bytecode), scriptLoader, false, new PrintWriter(System.err, true));
+            }
+        }
+    }
+
+    /**
+     * Create and initialize a new global scope object.
+     *
+     * @return the initialized global scope object.
+     */
+    public ScriptObject createGlobal() {
+        return initGlobal(newGlobal());
+    }
+
+    /**
+     * Create a new uninitialized global scope object
+     * @return the global script object
+     */
+    public ScriptObject newGlobal() {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("createNashornGlobal"));
+        }
+
+        return newGlobalTrusted();
+    }
+
+    /**
+     * Initialize given global scope object.
+     *
+     * @param global the global
+     * @return the initialized global scope object.
+     */
+    public ScriptObject initGlobal(final ScriptObject global) {
+        if (! (global instanceof GlobalObject)) {
+            throw new IllegalArgumentException("not a global object!");
+        }
+
+        // Need only minimal global object, if we are just compiling.
+        if (!env._compile_only) {
+            final ScriptObject oldGlobal = Context.getGlobalTrusted();
+            try {
+                Context.setGlobalTrusted(global);
+                // initialize global scope with builtin global objects
+                ((GlobalObject)global).initBuiltinObjects();
+            } finally {
+                Context.setGlobalTrusted(oldGlobal);
+            }
+        }
+
+        return global;
+    }
+
+    /**
+     * Trusted variants - package-private
+     */
+
+    /**
+     * Return the current global scope
+     * @return current global scope
+     */
+    static ScriptObject getGlobalTrusted() {
+        return currentGlobal.get();
+    }
+
+    /**
+     * Set the current global scope
+     */
+    static void setGlobalTrusted(ScriptObject global) {
+         currentGlobal.set(global);
+    }
+
+    /**
+     * Return the current global's context
+     * @return current global's context
+     */
+    static Context getContextTrusted() {
+        return Context.getGlobalTrusted().getContext();
+    }
+
+    /**
+     * Try to infer Context instance from the Class. If we cannot,
+     * then get it from the thread local variable.
+     *
+     * @param clazz the class
+     * @return context
+     */
+    static Context fromClass(final Class<?> clazz) {
+        final ClassLoader loader = clazz.getClassLoader();
+
+        Context context = null;
+        if (loader instanceof NashornLoader) {
+            context = ((NashornLoader)loader).getContext();
+        }
+
+        return (context != null) ? context : Context.getContextTrusted();
+    }
+
+    private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) {
+        ScriptFunction script = null;
+
+        try {
+            script = compileScript(source, scope, new Context.ThrowErrorManager());
+        } catch (final ParserException e) {
+            e.throwAsEcmaException();
+        }
+
+        return ScriptRuntime.apply(script, thiz);
+    }
+
+    private static ScriptFunction getRunScriptFunction(final Class<?> script, final ScriptObject scope) {
+        if (script == null) {
+            return null;
+        }
+
+        // Get run method - the entry point to the script
+        final MethodHandle runMethodHandle =
+                MH.findStatic(
+                    MethodHandles.lookup(),
+                    script,
+                    RUN_SCRIPT.tag(),
+                    MH.type(
+                        Object.class,
+                        ScriptFunction.class,
+                        Object.class));
+
+        boolean strict;
+
+        try {
+            strict = script.getField(STRICT_MODE.tag()).getBoolean(null);
+        } catch (final NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+            strict = false;
+        }
+
+        // Package as a JavaScript function and pass function back to shell.
+        return ((GlobalObject)Context.getGlobalTrusted()).newScriptFunction(RUN_SCRIPT.tag(), runMethodHandle, scope, strict);
+    }
+
+    private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
+        return getRunScriptFunction(compile(source, errMan, this._strict), scope);
+    }
+
+    private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) {
+        // start with no errors, no warnings.
+        errMan.reset();
+
+        GlobalObject global = null;
+        Class<?> script;
+
+        if (env._class_cache_size > 0) {
+            global = (GlobalObject)Context.getGlobalTrusted();
+            script = global.findCachedClass(source);
+            if (script != null) {
+                return script;
+            }
+        }
+
+        final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse();
+        if (errors.hasErrors() || env._parse_only) {
+            return null;
+        }
+
+        if (env._print_ast) {
+            getErr().println(new ASTWriter(functionNode));
+        }
+
+        if (env._print_parse) {
+            getErr().println(new PrintVisitor(functionNode));
+        }
+
+        final URL          url    = source.getURL();
+        final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader;
+        final CodeSource   cs     = url == null ? null : new CodeSource(url, (CodeSigner[])null);
+        final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs);
+
+        final Compiler compiler = new Compiler(installer, functionNode, strict);
+
+        compiler.compile();
+        script = compiler.install();
+
+        if (global != null) {
+            global.cacheClass(source, script);
+        }
+
+        return script;
+    }
+
+    private ScriptLoader createNewLoader() {
+        return AccessController.doPrivileged(
+             new PrivilegedAction<ScriptLoader>() {
+                @Override
+                public ScriptLoader run() {
+                    // Generated code won't refer to any class generated by context
+                    // script loader and so parent loader can be the structure
+                    // loader -- which is parent of the context script loader.
+                    return new ScriptLoader((StructureLoader)scriptLoader.getParent(), Context.this);
+                }
+             });
+    }
+
+    private ScriptObject newGlobalTrusted() {
+        try {
+            final Class<?> clazz = Class.forName("jdk.nashorn.internal.objects.Global", true, scriptLoader);
+            final Constructor<?> cstr = clazz.getConstructor(Context.class);
+            return (ScriptObject) cstr.newInstance(this);
+        } catch (final Exception e) {
+            printStackTrace(e);
+            if (e instanceof RuntimeException) {
+                throw (RuntimeException)e;
+            }
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Debug.java b/nashorn/src/jdk/nashorn/internal/runtime/Debug.java
new file mode 100644
index 0000000..b712f1d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Debug.java
@@ -0,0 +1,120 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.parser.TokenType.EOF;
+
+import jdk.nashorn.internal.parser.Lexer;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.parser.TokenStream;
+import jdk.nashorn.internal.parser.TokenType;
+
+/**
+ * Utilities for debugging Nashorn.
+ *
+ */
+public final class Debug {
+    private Debug() {
+    }
+
+    /**
+     * Return the system identity hashcode for an object as a human readable
+     * string
+     *
+     * @param x object
+     * @return system identity hashcode as string
+     */
+    public static String id(final Object x) {
+        return "0x" + Integer.toHexString(System.identityHashCode(x));
+    }
+
+    /**
+     * Return a stack trace element description at a depth from where we are not
+     *
+     * @param depth depth
+     * @return stack trace element as string
+     */
+    public static String stackTraceElementAt(final int depth) {
+        return new Throwable().getStackTrace()[depth + 1].toString(); // add 1 to compensate for this method
+    }
+
+    /**
+     * Determine caller for tracing purposes.
+     * @param depth depth to trace
+     * @param count max depth
+     * @param ignores elements to ignore in stack trace
+     * @return caller
+     */
+    public static String caller(final int depth, final int count, final String... ignores) {
+        String result = "";
+        final StackTraceElement[] callers = Thread.currentThread().getStackTrace();
+
+        int c = count;
+loop:
+        for (int i = depth + 1; i < callers.length && c != 0; i++) {
+            final StackTraceElement element = callers[i];
+            final String method = element.getMethodName();
+
+            for (final String ignore : ignores) {
+                if (method.compareTo(ignore) == 0) {
+                    continue loop;
+                }
+            }
+
+            result += (method + ":" + element.getLineNumber() +
+                       "                              ").substring(0, 30);
+            c--;
+        }
+
+        return result.isEmpty() ? "<no caller>" : result;
+    }
+
+    /**
+     * Dump a token stream to stdout
+     *
+     * TODO: most other bugging goes to stderr, change?
+     *
+     * @param source the source
+     * @param lexer  the lexer
+     * @param stream the stream to dump
+     */
+    public static void dumpTokens(final Source source, final Lexer lexer, final TokenStream stream) {
+        TokenType type;
+        int k = 0;
+        do {
+            while (k > stream.last()) {
+                // Get more tokens.
+                lexer.lexify();
+            }
+
+            final long token = stream.get(k);
+            type = Token.descType(token);
+            System.out.println("" + k + ": " + Token.toString(source, token, true));
+            k++;
+        } while(type != EOF);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java b/nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java
new file mode 100644
index 0000000..aa7f05d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java
@@ -0,0 +1,213 @@
+/*
+ * 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;
+
+import java.io.PrintWriter;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Wrapper class for Logging system. This is how you are supposed to register a logger and use it
+ */
+
+public final class DebugLogger {
+    @SuppressWarnings("NonConstantLogger")
+    private final Logger  logger;
+    private final boolean isEnabled;
+
+    private int indent;
+
+    private static final int INDENT_SPACE = 4;
+
+    /**
+     * Constructor
+     *
+     * @param loggerName name of logger - this is the unique key with which it can be identified
+     */
+    public DebugLogger(final String loggerName) {
+        this(loggerName, null);
+    }
+
+    /**
+     * Constructor
+     *
+     * A logger can be paired with a property, e.g. {@code --log:codegen:info} is equivalent to {@code -Dnashorn.codegen.log}
+     *
+     * @param loggerName name of logger - this is the unique key with which it can be identified
+     * @param property   system property activating the logger on {@code info} level
+     */
+    public DebugLogger(final String loggerName, final String property) {
+        if (property != null && Options.getBooleanProperty(property)) {
+            this.logger = Logging.getOrCreateLogger(loggerName, Level.INFO);
+        } else {
+            this.logger = Logging.getLogger(loggerName);
+        }
+        this.isEnabled = logger.getLevel() != Level.OFF;
+    }
+
+    /**
+     * Get the output writer for the logger. Loggers always default to
+     * stderr for output as they are used mainly to output debug info
+     *
+     * Can be inherited so this should not be static.
+     *
+     * @return print writer for log output.
+     */
+    @SuppressWarnings("static-method")
+    public PrintWriter getOutputStream() {
+        return Context.getCurrentErr();
+    }
+
+    /**
+     * Check if the logger is enabled
+     * @return true if enabled
+     */
+    public boolean isEnabled() {
+        return isEnabled;
+    }
+
+    /**
+     * If you want to change the indent level of your logger, call indent with a new position.
+     * Positions start at 0 and are increased by one for a new "tab"
+     *
+     * @param pos indent position
+     */
+    public void indent(final int pos) {
+        if (isEnabled) {
+           indent += pos * INDENT_SPACE;
+        }
+    }
+
+    /**
+     * Add an indent position
+     */
+    public void indent() {
+        indent += INDENT_SPACE;
+    }
+
+    /**
+     * Unindent a position
+     */
+    public void unindent() {
+        indent -= INDENT_SPACE;
+        if (indent < 0) {
+            indent = 0;
+        }
+    }
+
+    /**
+     * Check if the logger is above of the level of detail given
+     * @see java.util.logging.Level
+     *
+     * @param level logging level
+     * @return true if level is above the given one
+     */
+    public boolean levelAbove(final Level level) {
+        return logger.getLevel().intValue() > level.intValue();
+    }
+
+    /**
+     * Shorthand for outputting a log string as log level {@link java.util.logging.Level#FINEST} on this logger
+     * @param str the string to log
+     */
+    public void finest(final String str) {
+        log(str, Level.FINEST);
+    }
+
+    /**
+     * Shorthand for outputting a log string as log level
+     * {@link java.util.logging.Level#FINER} on this logger
+     * @param str the string to log
+     */
+    public void finer(final String str) {
+        log(str, Level.FINER);
+    }
+
+    /**
+     * Shorthand for outputting a log string as log level
+     * {@link java.util.logging.Level#FINE} on this logger
+     * @param str the string to log
+     */
+    public void fine(final String str) {
+        log(str, Level.FINE);
+    }
+
+    /**
+     * Shorthand for outputting a log string as log level
+     * {@link java.util.logging.Level#CONFIG} on this logger
+     * @param str the string to log
+     */
+    public void config(final String str) {
+        log(str, Level.CONFIG);
+    }
+
+    /**
+     * Shorthand for outputting a log string as log level
+     * {@link java.util.logging.Level#INFO} on this logger
+     * @param str the string to log
+     */
+    public void info(final String str) {
+        log(str, Level.INFO);
+    }
+
+    /**
+     * Shorthand for outputting a log string as log level
+     * {@link java.util.logging.Level#WARNING} on this logger
+     * @param str the string to log
+     */
+    public void warning(final String str) {
+        log(str, Level.WARNING);
+    }
+
+    /**
+     * Shorthand for outputting a log string as log level
+     * {@link java.util.logging.Level#SEVERE} on this logger
+     * @param str the string to log
+     */
+    public void severe(final String str) {
+        log(str, Level.SEVERE);
+    }
+
+    /**
+     * Output log line on this logger at a given level of verbosity
+     * @see java.util.logging.Level
+     *
+     * @param str   string to log
+     * @param level minimum log level required for logging to take place
+     */
+    public void log(final String str, final Level level) {
+        if (isEnabled) {
+            final StringBuilder sb = new StringBuilder();
+
+            for (int i = 0 ; i < indent ; i++) {
+                sb.append(' ');
+            }
+            sb.append(str);
+            logger.log(level, sb.toString());
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java b/nashorn/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java
new file mode 100644
index 0000000..dcceccb
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java
@@ -0,0 +1,243 @@
+/*
+ * 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;
+
+/**
+ * If your ScriptObject or similar PropertyAccess implementation only provides the most
+ * generic getters and setters and does nothing fancy with other, more primitive, types,
+ * then it is convenient to inherit this class and just fill out the methods left
+ * abstract
+ */
+public abstract class DefaultPropertyAccess implements PropertyAccess {
+
+    @Override
+    public int getInt(final Object key) {
+        return JSType.toInt32(get(key));
+    }
+
+    @Override
+    public int getInt(final double key) {
+        return getInt(JSType.toObject(key));
+    }
+
+    @Override
+    public int getInt(final long key) {
+        return getInt(JSType.toObject(key));
+    }
+
+    @Override
+    public int getInt(final int key) {
+        return getInt(JSType.toObject(key));
+    }
+
+    @Override
+    public long getLong(final Object key) {
+        return JSType.toLong(get(key));
+    }
+
+    @Override
+    public long getLong(final double key) {
+        return getLong(JSType.toObject(key));
+    }
+
+    @Override
+    public long getLong(final long key) {
+        return getLong(JSType.toObject(key));
+    }
+
+    @Override
+    public long getLong(final int key) {
+        return getLong(JSType.toObject(key));
+    }
+
+    @Override
+    public double getDouble(final Object key) {
+        return JSType.toNumber(get(key));
+    }
+
+    @Override
+    public double getDouble(final double key) {
+        return getDouble(JSType.toObject(key));
+    }
+
+    @Override
+    public double getDouble(final long key) {
+        return getDouble(JSType.toObject(key));
+    }
+
+    @Override
+    public double getDouble(final int key) {
+        return getDouble(JSType.toObject(key));
+    }
+
+    @Override
+    public abstract Object get(Object key);
+
+    @Override
+    public Object get(final double key) {
+        return get(JSType.toObject(key));
+    }
+
+    @Override
+    public Object get(final long key) {
+        return get(JSType.toObject(key));
+    }
+
+    @Override
+    public Object get(final int key) {
+        return get(JSType.toObject(key));
+    }
+
+    @Override
+    public void set(final double key, final int value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final double key, final long value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final double key, final double value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final double key, final Object value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final long key, final int value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final long key, final long value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final long key, final double value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final long key, final Object value, final boolean strict) {
+        set(JSType.toObject(key), value, strict);
+    }
+
+    @Override
+    public void set(final int key, final int value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final int key, final long value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final int key, final double value, final boolean strict) {
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final int key, final Object value, final boolean strict) {
+        set(JSType.toObject(key), value, strict);
+    }
+
+    @Override
+    public void set(final Object key, final int value, final boolean strict) {
+        set(key, JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final Object key, final long value, final boolean strict) {
+        set(key, JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final Object key, final double value, final boolean strict) {
+        set(key, JSType.toObject(value), strict);
+    }
+
+    @Override
+    public abstract void set(Object key, Object value, boolean strict);
+
+    @Override
+    public abstract boolean has(Object key);
+
+    @Override
+    public boolean has(final int key) {
+        return has(JSType.toObject(key));
+    }
+
+    @Override
+    public boolean has(final long key) {
+        return has(JSType.toObject(key));
+    }
+
+    @Override
+    public boolean has(final double key) {
+        return has(JSType.toObject(key));
+    }
+
+    @Override
+    public boolean hasOwnProperty(final int key) {
+        return hasOwnProperty(JSType.toObject(key));
+    }
+
+    @Override
+    public boolean hasOwnProperty(final long key) {
+        return hasOwnProperty(JSType.toObject(key));
+    }
+
+    @Override
+    public boolean hasOwnProperty(final double key) {
+        return hasOwnProperty(JSType.toObject(key));
+    }
+
+    @Override
+    public abstract boolean hasOwnProperty(Object key);
+
+    @Override
+    public boolean delete(final int key, final boolean strict) {
+        return delete(JSType.toObject(key), strict);
+    }
+
+    @Override
+    public boolean delete(final long key, final boolean strict) {
+        return delete(JSType.toObject(key), strict);
+    }
+
+    @Override
+    public boolean delete(final double key, final boolean strict) {
+        return delete(JSType.toObject(key), strict);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java
new file mode 100644
index 0000000..35a0f2f
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java
@@ -0,0 +1,425 @@
+/*
+ * 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;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.scripts.JS;
+
+/**
+ * Helper class to throw various standard "ECMA error" exceptions such as Error, ReferenceError, TypeError etc.
+ */
+public final class ECMAErrors {
+    private static final String MESSAGES_RESOURCE = "jdk.nashorn.internal.runtime.resources.Messages";
+
+    // Without do privileged, under security manager messages can not be loaded.
+    private static final ResourceBundle MESSAGES_BUNDLE;
+    static {
+        MESSAGES_BUNDLE = AccessController.doPrivileged(
+        new PrivilegedAction<ResourceBundle>() {
+            @Override
+            public ResourceBundle run() {
+                return ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
+            }
+        });
+    }
+
+    /** We assume that compiler generates script classes into the known package. */
+    private static final String scriptPackage;
+    static {
+        String name = JS.class.getName();
+        scriptPackage = name.substring(0, name.lastIndexOf('.'));
+    }
+
+    private ECMAErrors() {
+    }
+
+    private static ECMAException error(final Object thrown, final Throwable cause) {
+        return new ECMAException(thrown, cause);
+    }
+
+     /**
+     * Error dispatch mechanism.
+     * Create a {@link ParserException} as the correct JavaScript error
+     *
+     * @param e {@code ParserException} for error dispatcher
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException asEcmaException(final ParserException e) {
+        return asEcmaException(Context.getGlobalTrusted(), e);
+    }
+
+    /**
+     * Error dispatch mechanism.
+     * Create a {@link ParserException} as the correct JavaScript error
+     *
+     * @param global global scope object
+     * @param e {@code ParserException} for error dispatcher
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException asEcmaException(final ScriptObject global, final ParserException e) {
+        final JSErrorType errorType = e.getErrorType();
+        assert errorType != null : "error type for " + e + " was null";
+
+        final GlobalObject globalObj = (GlobalObject)global;
+        final String       msg    = e.getMessage();
+
+        // translate to ECMAScript Error object using error type
+        switch (errorType) {
+        case ERROR:
+            return error(globalObj.newError(msg), e);
+        case EVAL_ERROR:
+            return error(globalObj.newEvalError(msg), e);
+        case RANGE_ERROR:
+            return error(globalObj.newRangeError(msg), e);
+        case REFERENCE_ERROR:
+            return error(globalObj.newReferenceError(msg), e);
+        case SYNTAX_ERROR:
+            return error(globalObj.newSyntaxError(msg), e);
+        case TYPE_ERROR:
+            return error(globalObj.newTypeError(msg), e);
+        case URI_ERROR:
+            return error(globalObj.newURIError(msg), e);
+        default:
+            // should not happen - perhaps unknown error type?
+            throw new AssertionError(e.getMessage());
+        }
+    }
+
+    /**
+     * Create a syntax error (ECMA 15.11.6.4)
+     *
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException syntaxError(final String msgId, final String... args) {
+        return syntaxError(Context.getGlobalTrusted(), msgId, args);
+    }
+
+    /**
+     * Create a syntax error (ECMA 15.11.6.4)
+     *
+     * @param global  global scope object
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException syntaxError(final ScriptObject global, final String msgId, final String... args) {
+        return syntaxError(global, null, msgId, args);
+    }
+
+    /**
+     * Create a syntax error (ECMA 15.11.6.4)
+     *
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException syntaxError(final Throwable cause, final String msgId, final String... args) {
+        return syntaxError(Context.getGlobalTrusted(), cause, msgId, args);
+    }
+
+    /**
+     * Create a syntax error (ECMA 15.11.6.4)
+     *
+     * @param global  global scope object
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException syntaxError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+        final String msg = getMessage("syntax.error." + msgId, args);
+        return error(((GlobalObject)global).newSyntaxError(msg), cause);
+    }
+
+    /**
+     * Create a type error (ECMA 15.11.6.5)
+     *
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException typeError(final String msgId, final String... args) {
+        return typeError(Context.getGlobalTrusted(), msgId, args);
+    }
+
+    /**
+     * Create a type error (ECMA 15.11.6.5)
+     *
+     * @param global  global scope object
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException typeError(final ScriptObject global, final String msgId, final String... args) {
+        return typeError(global, null, msgId, args);
+    }
+
+    /**
+     * Create a type error (ECMA 15.11.6.5)
+     *
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException typeError(final Throwable cause, final String msgId, final String... args) {
+        return typeError(Context.getGlobalTrusted(), cause, msgId, args);
+    }
+
+    /**
+     * Create a type error (ECMA 15.11.6.5)
+     *
+     * @param global  global scope object
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException typeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+        final String msg = getMessage("type.error." + msgId, args);
+        return error(((GlobalObject)global).newTypeError(msg), cause);
+    }
+
+    /**
+     * Create a range error (ECMA 15.11.6.2)
+     *
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException rangeError(final String msgId, final String... args) {
+        return rangeError(Context.getGlobalTrusted(), msgId, args);
+    }
+
+    /**
+     * Create a range error (ECMA 15.11.6.2)
+     *
+     * @param global  global scope object
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException rangeError(final ScriptObject global, final String msgId, final String... args) {
+        return rangeError(global, null, msgId, args);
+    }
+
+    /**
+     * Create a range error (ECMA 15.11.6.2)
+     *
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException rangeError(final Throwable cause, final String msgId, final String... args) {
+        return rangeError(Context.getGlobalTrusted(), cause, msgId, args);
+    }
+
+    /**
+     * Create a range error (ECMA 15.11.6.2)
+     *
+     * @param global  global scope object
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException rangeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+        final String msg = getMessage("range.error." + msgId, args);
+        return error(((GlobalObject)global).newRangeError(msg), cause);
+    }
+
+    /**
+     * Create a reference error (ECMA 15.11.6.3)
+     *
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException referenceError(final String msgId, final String... args) {
+        return referenceError(Context.getGlobalTrusted(), msgId, args);
+    }
+
+    /**
+     * Create a reference error (ECMA 15.11.6.3)
+     *
+     * @param global  global scope object
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException referenceError(final ScriptObject global, final String msgId, final String... args) {
+        return referenceError(global, null, msgId, args);
+    }
+
+    /**
+     * Create a reference error (ECMA 15.11.6.3)
+     *
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException referenceError(final Throwable cause, final String msgId, final String... args) {
+        return referenceError(Context.getGlobalTrusted(), cause, msgId, args);
+    }
+
+    /**
+     * Create a reference error (ECMA 15.11.6.3)
+     *
+     * @param global  global scope object
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException referenceError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+        final String msg = getMessage("reference.error." + msgId, args);
+        return error(((GlobalObject)global).newReferenceError(msg), cause);
+    }
+
+    /**
+     * Create a URI error (ECMA 15.11.6.6)
+     *
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException uriError(final String msgId, final String... args) {
+        return uriError(Context.getGlobalTrusted(), msgId, args);
+    }
+
+    /**
+     * Create a URI error (ECMA 15.11.6.6)
+     *
+     * @param global  global scope object
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException uriError(final ScriptObject global, final String msgId, final String... args) {
+        return uriError(global, null, msgId, args);
+    }
+
+    /**
+     * Create a URI error (ECMA 15.11.6.6)
+     *
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException uriError(final Throwable cause, final String msgId, final String... args) {
+        return uriError(Context.getGlobalTrusted(), cause, msgId, args);
+    }
+
+    /**
+     * Create a URI error (ECMA 15.11.6.6)
+     *
+     * @param global  global scope object
+     * @param cause   native Java {@code Throwable} that is the cause of error
+     * @param msgId   resource tag for error message
+     * @param args    arguments to resource
+     *
+     * @return the resulting {@link ECMAException}
+     */
+    public static ECMAException uriError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+        final String msg = getMessage("uri.error." + msgId, args);
+        return error(((GlobalObject)global).newURIError(msg), cause);
+    }
+
+    /**
+     * Get the exception message by placing the args in the resource defined
+     * by the resource tag. This is visible to, e.g. the {@link jdk.nashorn.internal.parser.Parser}
+     * can use it to generate compile time messages with the correct locale
+     *
+     * @param msgId the resource tag (message id)
+     * @param args  arguments to error string
+     *
+     * @return the filled out error string
+     */
+    public static String getMessage(final String msgId, final String... args) {
+        try {
+            return new MessageFormat(MESSAGES_BUNDLE.getString(msgId)).format(args);
+        } catch (final java.util.MissingResourceException e) {
+            throw new RuntimeException("no message resource found for message id: "+ msgId);
+        }
+    }
+
+
+    /**
+     * Check if a stack trace element is in JavaScript
+     *
+     * @param frame frame
+     *
+     * @return true if frame is in the script
+     */
+    public static boolean isScriptFrame(final StackTraceElement frame) {
+        final String className = frame.getClassName();
+
+        // Look for script package in class name (into which compiler puts generated code)
+        if (className.startsWith(scriptPackage)) {
+            final String source = frame.getFileName();
+            /*
+             * Make sure that it is not some Java code that Nashorn has in that package!
+             * also, we don't want to report JavaScript code that lives in script engine implementation
+             * We want to report only user's own scripts and not any of our own scripts like "engine.js"
+             */
+            return source != null && !source.endsWith(".java") && !source.contains(NashornException.ENGINE_SCRIPT_SOURCE_NAME);
+        }
+        return false;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java b/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java
new file mode 100644
index 0000000..a07fb58
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java
@@ -0,0 +1,262 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.virtualField;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import javax.script.ScriptException;
+import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.codegen.CompilerConstants.FieldAccess;
+
+/**
+ * Exception used to implement ECMAScript "throw" from scripts. The actual thrown
+ * object from script need not be a Java exception and so it is wrapped as an
+ * instance field called "thrown" here. This exception class is also used to
+ * represent ECMA errors thrown from runtime code (for example, TypeError,
+ * ReferenceError thrown from Nashorn engine runtime).
+ */
+@SuppressWarnings("serial")
+public final class ECMAException extends NashornException {
+    /**
+     * Method handle pointing to the constructor {@link ECMAException#ECMAException(Object, String, int, int)},
+     */
+    public static final Call THROW_INIT = constructorNoLookup(ECMAException.class, Object.class, String.class, int.class, int.class);
+
+    /** Field handle to the{@link ECMAException#thrown} field, so that it can be accessed from generated code */
+    public static final FieldAccess THROWN = virtualField(ECMAException.class, "thrown", Object.class);
+
+    private static final String EXCEPTION_PROPERTY = "nashornException";
+
+    /** Object thrown. */
+    public final Object thrown;
+
+    /**
+     * Constructor. This is called from generated code to implement the {@code throw}
+     * instruction from generated script code
+     *
+     * @param thrown    object to be thrown
+     * @param fileName  script file name
+     * @param line      line number of throw
+     * @param column    column number of throw
+     */
+    public ECMAException(final Object thrown, final String fileName, final int line, final int column) {
+        super(ScriptRuntime.safeToString(thrown), asThrowable(thrown), fileName, line, column);
+        this.thrown = thrown;
+        setExceptionToThrown();
+    }
+
+    /**
+     * Constructor. This is called from runtime code in Nashorn to throw things like
+     * type errors.
+     *
+     * @param thrown   object to be thrown
+     * @param cause    Java exception that triggered this throw
+     */
+    public ECMAException(final Object thrown, final Throwable cause) {
+        super(ScriptRuntime.safeToString(thrown), cause);
+        this.thrown = thrown;
+        setExceptionToThrown();
+    }
+
+    /**
+     * Get the thrown object
+     * @return thrown object
+     */
+    public Object getThrown() {
+        return thrown;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        final String fileName = getFileName();
+        final int line = getLineNumber();
+        final int column = getColumnNumber();
+
+        if (fileName != null) {
+            sb.append(fileName);
+            if (line >= 0) {
+                sb.append(':');
+                sb.append(line);
+            }
+            if (column >= 0) {
+                sb.append(':');
+                sb.append(column);
+            }
+            sb.append(' ');
+        } else {
+            sb.append("ECMAScript Exception: ");
+        }
+
+        sb.append(getMessage());
+        return sb.toString();
+    }
+
+    /**
+     * Get the {@link ECMAException}, i.e. the underlying Java object for the
+     * JavaScript error object from a {@link ScriptObject} representing an error
+     *
+     * @param errObj the error object
+     * @return a {@link ECMAException}
+     */
+    public static Object getException(final ScriptObject errObj) {
+        return errObj.get(ECMAException.EXCEPTION_PROPERTY);
+    }
+
+    /**
+     * Print the stack trace for a {@code ScriptObject} representing an error
+     *
+     * @param errObj the error object
+     * @return undefined
+     */
+    public static Object printStackTrace(final ScriptObject errObj) {
+        final Object exception = getException(errObj);
+        if (exception instanceof Throwable) {
+            ((Throwable)exception).printStackTrace(Context.getCurrentErr());
+        } else {
+            Context.err("<stack trace not available>");
+        }
+        return UNDEFINED;
+    }
+
+    /**
+     * Get the line number for a {@code ScriptObject} representing an error
+     *
+     * @param errObj the error object
+     * @return the line number, or undefined if wrapped exception is not a ParserException
+     */
+    public static Object getLineNumber(final ScriptObject errObj) {
+        final Object e = getException(errObj);
+        if (e instanceof NashornException) {
+            return ((NashornException)e).getLineNumber();
+        } else if (e instanceof ScriptException) {
+            return ((ScriptException)e).getLineNumber();
+        }
+
+        return UNDEFINED;
+    }
+
+    /**
+     * Get the column number for a {@code ScriptObject} representing an error
+     *
+     * @param errObj the error object
+     * @return the column number, or undefined if wrapped exception is not a ParserException
+     */
+    public static Object getColumnNumber(final ScriptObject errObj) {
+        final Object e = getException(errObj);
+        if (e instanceof NashornException) {
+            return ((NashornException)e).getColumnNumber();
+        } else if (e instanceof ScriptException) {
+            return ((ScriptException)e).getColumnNumber();
+        }
+
+        return UNDEFINED;
+    }
+
+    /**
+     * Get the file name for a {@code ScriptObject} representing an error
+     *
+     * @param errObj the error object
+     * @return the file name, or undefined if wrapped exception is not a ParserException
+     */
+    public static Object getFileName(final ScriptObject errObj) {
+        final Object e = getException(errObj);
+        if (e instanceof NashornException) {
+            return ((NashornException)e).getFileName();
+        } else if (e instanceof ScriptException) {
+            return ((ScriptException)e).getFileName();
+        }
+
+        return UNDEFINED;
+    }
+
+    /**
+     * Stateless string conversion for an error object
+     *
+     * @param errObj the error object
+     * @return string representation of {@code errObj}
+     */
+    public static String safeToString(final ScriptObject errObj) {
+        Object name = UNDEFINED;
+        try {
+            name = errObj.get("name");
+        } catch (final Exception e) {
+            //ignored
+        }
+
+        if (name == UNDEFINED) {
+            name = "Error";
+        } else {
+            name = ScriptRuntime.safeToString(name);
+        }
+
+        Object msg = UNDEFINED;
+        try {
+            msg = errObj.get("message");
+        } catch (final Exception e) {
+            //ignored
+        }
+
+        if (msg == UNDEFINED) {
+            msg = "";
+        } else {
+            msg = ScriptRuntime.safeToString(msg);
+        }
+
+        if (((String)name).isEmpty()) {
+            return (String)msg;
+        }
+
+        if (((String)msg).isEmpty()) {
+            return (String)name;
+        }
+
+        return (String)name + ": " + (String)msg;
+    }
+
+    private static Throwable asThrowable(final Object obj) {
+        return (obj instanceof Throwable)? (Throwable)obj : null;
+    }
+
+    private void setExceptionToThrown() {
+        /*
+         * Nashorn extension: errorObject.nashornException
+         * Expose this exception via "nashornException" property of on the
+         * thrown object. This exception object can be used to print stack
+         * trace and fileName, line number etc. from script code.
+         */
+
+        if (thrown instanceof ScriptObject) {
+            final ScriptObject sobj = (ScriptObject)thrown;
+            if (!sobj.has(EXCEPTION_PROPERTY)) {
+                sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this);
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ErrorManager.java b/nashorn/src/jdk/nashorn/internal/runtime/ErrorManager.java
new file mode 100644
index 0000000..9a20381
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ErrorManager.java
@@ -0,0 +1,236 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+
+import java.io.PrintWriter;
+import jdk.nashorn.internal.parser.Token;
+
+/**
+ * Handles JavaScript error reporting.
+ */
+public class ErrorManager {
+    // TODO - collect and sort/collapse error messages.
+    // TODO - property based error messages.
+    /** Reporting writer. */
+    private final PrintWriter writer;
+
+    /** Error count. */
+    private int errors;
+
+    /** Warning count */
+    private int warnings;
+
+    /** Limit of the number of messages. */
+    private int limit;
+
+    /** Treat warnings as errors. */
+    private boolean warningsAsErrors;
+
+    /**
+     * Constructor
+     */
+    public ErrorManager() {
+        this(new PrintWriter(System.err, true)); //bootstrapping, context may not be initialized
+    }
+
+    /**
+     * Constructor.
+     * @param writer I/O writer to report on.
+     */
+    public ErrorManager(final PrintWriter writer) {
+        this.writer           = writer;
+        this.limit            = 100;
+        this.warningsAsErrors = false;
+    }
+
+    /**
+     * Check to see if number of errors exceed limit.
+     */
+    private void checkLimit() {
+        int count = errors;
+
+        if (warningsAsErrors) {
+            count += warnings;
+        }
+
+        if (limit != 0 && count > limit) {
+            throw rangeError("too.many.errors", Integer.toString(limit));
+        }
+    }
+
+    /**
+     * Format an error message to include source and line information.
+     * @param message Error message string.
+     * @param source  Source file information.
+     * @param line    Source line number.
+     * @param column  Source column number.
+     * @param token   Offending token descriptor.
+     * @return formatted string
+     */
+    public static String format(final String message, final Source source, final int line, final int column, final long token) {
+        final String        eoln     = System.lineSeparator();
+        final int           position = Token.descPosition(token);
+        final StringBuilder sb       = new StringBuilder();
+
+        // Source description and message.
+        sb.append(source.getName()).
+            append(':').
+            append(line).
+            append(':').
+            append(column).
+            append(' ').
+            append(message).
+            append(eoln);
+
+        // Source content.
+        final String sourceLine = source.getSourceLine(position);
+        sb.append(sourceLine).append(eoln);
+
+        // Pointer to column.
+        for (int i = 0; i < column; i++) {
+            if (sourceLine.charAt(i) == '\t') {
+                sb.append('\t');
+            } else {
+                sb.append(' ');
+            }
+        }
+
+        sb.append('^');
+        // Use will append eoln.
+        // buffer.append(eoln);
+
+        return sb.toString();
+    }
+
+    /**
+     * Report an error using information provided by the ParserException
+     *
+     * @param e ParserException object
+     */
+
+    public void error(final ParserException e) {
+        error(e.getMessage());
+    }
+
+    /**
+     * Report an error message provided
+     *
+     * @param message Error message string.
+     */
+    public void error(final String message) {
+        writer.println(message);
+        writer.flush();
+        errors++;
+        checkLimit();
+    }
+
+    /**
+     * Report a warning using information provided by the ParserException
+     *
+     * @param e ParserException object
+     */
+    public void warning(final ParserException e) {
+        warning(e.getMessage());
+    }
+
+    /**
+     * Report a warning message provided
+     *
+     * @param message Error message string.
+     */
+    public void warning(final String message) {
+        writer.println(message);
+        writer.flush();
+        warnings++;
+        checkLimit();
+    }
+
+    /**
+     * Test to see if errors have occurred.
+     * @return True if errors.
+     */
+    public boolean hasErrors() {
+        return errors != 0;
+    }
+
+    /**
+     * Get the message limit
+     * @return max number of messages
+     */
+    public int getLimit() {
+        return limit;
+    }
+
+    /**
+     * Set the message limit
+     * @param limit max number of messages
+     */
+    public void setLimit(final int limit) {
+        this.limit = limit;
+    }
+
+    /**
+     * Check whether warnings should be treated like errors
+     * @return true if warnings should be treated like errors
+     */
+    public boolean isWarningsAsErrors() {
+        return warningsAsErrors;
+    }
+
+    /**
+     * Set warnings to be treated as errors
+     * @param warningsAsErrors true if warnings should be treated as errors, false otherwise
+     */
+    public void setWarningsAsErrors(final boolean warningsAsErrors) {
+        this.warningsAsErrors = warningsAsErrors;
+    }
+
+    /**
+     * Get the number of errors
+     * @return number of errors
+     */
+    public int getNumberOfErrors() {
+        return errors;
+    }
+
+    /**
+     * Get number of warnings
+     * @return number of warnings
+     */
+    public int getNumberOfWarnings() {
+        return warnings;
+    }
+
+    /**
+     * Clear warnings and error count.
+     */
+    void reset() {
+        warnings = 0;
+        errors = 0;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
new file mode 100644
index 0000000..35ffed9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
@@ -0,0 +1,141 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+
+/**
+ * This class represents the result from a find property search.
+ */
+public final class FindProperty {
+    /** Object where search began. */
+    private final ScriptObject self;
+
+    /** Object where search finish. */
+    private final ScriptObject prototype;
+
+    /** Found property. */
+    private final Property     property;
+
+    /**
+     * Constructor
+     *
+     * @param self      script object where search began
+     * @param prototype prototype where property was found, may be {@code self} if not inherited
+     * @param property  property that was search result
+     */
+    public FindProperty(final ScriptObject self, final ScriptObject prototype, final Property property) {
+        this.self      = self;
+        this.prototype = prototype;
+        this.property  = property;
+    }
+
+    /**
+     * Ask for a getter that returns the given type. The type has nothing to do with the
+     * internal representation of the property. It may be an Object (boxing primitives) or
+     * a primitive (primitive fields with -Dnashorn.fields.dual=true)
+     * @see ObjectClassGenerator
+     *
+     * @param type type of getter, e.g. int.class if we want a function with {@code get()I} signature
+     * @return method handle for the getter
+     */
+    public MethodHandle getGetter(final Class<?> type) {
+        MethodHandle getter = property.getGetter(type);
+        if (property instanceof UserAccessorProperty) {
+            final UserAccessorProperty uc = (UserAccessorProperty)property;
+            getter = MH.insertArguments(getter, 0, isInherited() ? getOwner() : null, uc.getGetterSlot());
+        }
+        return getter;
+    }
+
+    /**
+     * Ask for a setter that sets the given type. The type has nothing to do with the
+     * internal representation of the property. It may be an Object (boxing primitives) or
+     * a primitive (primitive fields with -Dnashorn.fields.dual=true)
+     * @see ObjectClassGenerator
+     *
+     * @param type type of setter, e.g. int.class if we want a function with {@code set(I)V} signature
+     * @param strict are we in strict mode
+     *
+     * @return method handle for the getter
+     */
+    public MethodHandle getSetter(final Class<?> type, final boolean strict) {
+        MethodHandle setter = property.getSetter(type, getOwner().getMap());
+        if (property instanceof UserAccessorProperty) {
+            final UserAccessorProperty uc = (UserAccessorProperty) property;
+            setter = MH.insertArguments(setter, 0, (isInherited() ? getOwner() : null),
+                    uc.getSetterSlot(), strict? property.getKey() : null);
+        }
+
+        return setter;
+    }
+
+    /**
+     * Return the {@code ScriptObject} owning of the property:  this means the prototype.
+     * @return owner of property
+     */
+    public ScriptObject getOwner() {
+        return prototype;
+    }
+
+    /**
+     * Return the property that was found
+     * @return property
+     */
+    public Property getProperty() {
+        return property;
+    }
+
+    /**
+     * Check if the property found was inherited, i.e. not directly in the self
+     * @return true if inherited property
+     */
+    public boolean isInherited() {
+        return self != prototype;
+    }
+
+    /**
+     * Check if the property found was NOT inherited, i.e. defined in the script
+     * object, rather than in the prototype
+     * @return true if not inherited
+     */
+    public boolean isSelf() {
+        return self == prototype;
+    }
+
+    /**
+     * Check if the property is in the scope
+     * @return true if on scope
+     */
+    public boolean isScope() {
+        return prototype.isScope();
+    }
+
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java b/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java
new file mode 100644
index 0000000..713aa69
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java
@@ -0,0 +1,93 @@
+/*
+ * 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;
+
+/**
+ * This is the base class for function scopes.  Subclasses of this class are
+ * produced by the ObjectClassGenerator along with additional fields for storing
+ * local vars.  The number of fields required is determined by ObjectCreator.
+ *
+ * The scope is also responsible for handling the var arg 'arguments' object,
+ * though most of the access is via generated code.
+ *
+ * The constructor of this class is responsible for any function prologue
+ * involving the scope.
+ *
+ * TODO see NASHORN-715.
+ */
+public class FunctionScope extends ScriptObject implements Scope {
+
+    /** Area to store scope arguments. (public for access from scripts.) */
+    public final Object arguments;
+
+    /** Flag to indicate that a split method issued a return statement */
+    private int splitState = -1;
+
+    /**
+     * Constructor
+     *
+     * @param map         property map
+     * @param callerScope caller scope
+     * @param arguments   arguments
+     */
+    public FunctionScope(final PropertyMap map, final ScriptObject callerScope, final Object arguments) {
+        super(map);
+        this.arguments = arguments;
+        setProto(callerScope);
+        setIsScope();
+    }
+
+    /**
+     * Constructor
+     *
+     * @param map         property map
+     * @param callerScope caller scope
+     */
+    public FunctionScope(final PropertyMap map, final ScriptObject callerScope) {
+        super(map);
+        this.arguments = null;
+        setProto(callerScope);
+        setIsScope();
+    }
+
+    /**
+     * Get the current split state.
+     * @return current split state
+     */
+    @Override
+    public int getSplitState() {
+        return splitState;
+    }
+
+    /**
+     * Set the current split state.
+     * @param state current split state
+     */
+    @Override
+    public void setSplitState(final int state) {
+        splitState = state;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
new file mode 100644
index 0000000..9101153
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
@@ -0,0 +1,460 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.JSType.digit;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+
+/**
+ * Utilities used by Global class.
+ *
+ * These are actual implementation methods for functions exposed by global
+ * scope. The code lives here to share the code across the contexts.
+ */
+public final class GlobalFunctions {
+
+    /** Methodhandle to implementation of ECMA 15.1.2.2, parseInt */
+    public static final MethodHandle PARSEINT = findOwnMH("parseInt",   double.class, Object.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA 15.1.2.3, parseFloat */
+    public static final MethodHandle PARSEFLOAT = findOwnMH("parseFloat", double.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA 15.1.2.4, isNaN */
+    public static final MethodHandle IS_NAN = findOwnMH("isNaN",      boolean.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA 15.1.2.5, isFinite */
+    public static final MethodHandle IS_FINITE = findOwnMH("isFinite",   boolean.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA 15.1.3.3, encodeURI */
+    public static final MethodHandle ENCODE_URI = findOwnMH("encodeURI",  Object.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA 15.1.3.4, encodeURIComponent */
+    public static final MethodHandle ENCODE_URICOMPONENT = findOwnMH("encodeURIComponent", Object.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA 15.1.3.1, decodeURI */
+    public static final MethodHandle DECODE_URI = findOwnMH("decodeURI", Object.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA 15.1.3.2, decodeURIComponent */
+    public static final MethodHandle DECODE_URICOMPONENT = findOwnMH("decodeURIComponent", Object.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA B.2.1, escape */
+    public static final MethodHandle ESCAPE = findOwnMH("escape",    String.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA B.2.2, unescape */
+    public static final MethodHandle UNESCAPE = findOwnMH("unescape",  String.class, Object.class, Object.class);
+
+    /** Methodhandle to implementation of ECMA 15.3.4, "anonymous" - Properties of the Function Prototype Object. */
+    public static final MethodHandle ANONYMOUS = findOwnMH("anonymous", Object.class, Object.class);
+
+    private static final String UNESCAPED = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./";
+
+    private GlobalFunctions() {
+    }
+
+    /**
+     * ECMA 15.1.2.2 parseInt implementation
+     *
+     * TODO: specialize
+     *
+     * @param self   self reference
+     * @param string string to parse
+     * @param rad    radix
+     *
+     * @return numeric type representing string contents as an int (TODO: specialize for int case)
+     */
+    //TODO specialize
+    public static double parseInt(final Object self, final Object string, final Object rad) {
+        final String str    = JSType.trimLeft(JSType.toString(string));
+        final int    length = str.length();
+
+        // empty string is not valid
+        if (length == 0) {
+            return Double.NaN;
+        }
+
+        boolean negative = false;
+        int idx = 0;
+
+        // checking for the sign character
+        final char firstChar = str.charAt(idx);
+        if (firstChar < '0') {
+            // Possible leading "+" or "-"
+            if (firstChar == '-') {
+                negative = true;
+            } else if (firstChar != '+') {
+                return Double.NaN;
+            }
+            // skip the sign character
+            idx++;
+        }
+
+        boolean stripPrefix = true;
+        int     radix = JSType.toInt32(rad);
+
+        if (radix != 0) {
+            if (radix < 2 || radix > 36) {
+                return Double.NaN;
+            }
+            if (radix != 16) {
+                stripPrefix = false;
+            }
+        } else {
+            // default radix
+            radix = 10;
+        }
+        // strip "0x" or "0X" and treat radix as 16
+        if (stripPrefix && ((idx + 1) < length)) {
+            final char c1 = str.charAt(idx);
+            final char c2 = str.charAt(idx + 1);
+            if (c1 == '0' && (c2 == 'x' || c2 == 'X')) {
+                radix = 16;
+                // skip "0x" or "0X"
+                idx += 2;
+            }
+        }
+
+        double result = 0.0;
+        int digit;
+        // we should see atleast one valid digit
+        boolean entered = false;
+        while (idx < length) {
+            digit = digit(str.charAt(idx++), radix, true);
+            if (digit < 0) {
+                break;
+            }
+            // we have seen atleast one valid digit in the specified radix
+            entered = true;
+            result *= radix;
+            result += digit;
+        }
+
+        return entered ? (negative ? -result : result) : Double.NaN;
+    }
+
+    /**
+     * ECMA 15.1.2.3 parseFloat implementation
+     *
+     * @param self   self reference
+     * @param string string to parse
+     *
+     * @return numeric type representing string contents
+     */
+    public static double parseFloat(final Object self, final Object string) {
+        final String str    = JSType.trimLeft(JSType.toString(string));
+        final int    length = str.length();
+
+        // empty string is not valid
+        if (length == 0) {
+            return Double.NaN;
+        }
+
+        int     start    = 0;
+        boolean negative = false;
+        char    ch       = str.charAt(0);
+
+        if (ch == '-') {
+            start++;
+            negative = true;
+        } else if (ch == '+') {
+            start++;
+        } else if (ch == 'N') {
+            if (str.startsWith("NaN")) {
+                return Double.NaN;
+            }
+        }
+
+        if (start == length) {
+            // just the sign character
+            return Double.NaN;
+        }
+
+        ch = str.charAt(start);
+        if (ch == 'I') {
+            if (str.substring(start).startsWith("Infinity")) {
+                return negative? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
+            }
+        }
+
+        boolean dotSeen    = false;
+        boolean exponentOk = false;
+        int exponentOffset = -1;
+        int end;
+
+loop:
+        for (end = start; end < length; end++) {
+            ch = str.charAt(end);
+
+            switch (ch) {
+            case '.':
+                // dot allowed only once
+                if (dotSeen) {
+                    break loop;
+                }
+                dotSeen = true;
+                break;
+
+            case 'e':
+            case 'E':
+                // 'e'/'E' allow only once
+                if (exponentOffset != -1) {
+                    break loop;
+                }
+                exponentOffset = end;
+                break;
+
+            case '+':
+            case '-':
+                // Sign of the exponent. But allowed only if the
+                // previous char in the string was 'e' or 'E'.
+                if (exponentOffset != end - 1) {
+                    break loop;
+                }
+                break;
+
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                if (exponentOffset != -1) {
+                    // seeing digit after 'e' or 'E'
+                    exponentOk = true;
+                }
+                break;
+
+            default: // ignore garbage at the end
+                break loop;
+            }
+        }
+
+        // ignore 'e'/'E' followed by '+/-' if not real exponent found
+        if (exponentOffset != -1 && !exponentOk) {
+            end = exponentOffset;
+        }
+
+        if (start == end) {
+            return Double.NaN;
+        }
+
+        try {
+            final double result = Double.valueOf(str.substring(start, end));
+            return negative ? -result : result;
+        } catch (final NumberFormatException e) {
+            return Double.NaN;
+        }
+    }
+
+    /**
+     * ECMA 15.1.2.4, isNaN implementation
+     *
+     * @param self    self reference
+     * @param number  number to check
+     *
+     * @return true if number is NaN
+     */
+    public static boolean isNaN(final Object self, final Object number) {
+        return Double.isNaN(JSType.toNumber(number));
+    }
+
+    /**
+     * ECMA 15.1.2.5, isFinite implementation
+     *
+     * @param self   self reference
+     * @param number number to check
+     *
+     * @return true if number is infinite
+     */
+    public static boolean isFinite(final Object self, final Object number) {
+        final double value = JSType.toNumber(number);
+        return ! (Double.isInfinite(value) || Double.isNaN(value));
+    }
+
+
+    /**
+     * ECMA 15.1.3.3, encodeURI implementation
+     *
+     * @param self  self reference
+     * @param uri   URI to encode
+     *
+     * @return encoded URI
+     */
+    public static Object encodeURI(final Object self, final Object uri) {
+        return URIUtils.encodeURI(self, JSType.toString(uri));
+    }
+
+    /**
+     * ECMA 15.1.3.4, encodeURIComponent implementation
+     *
+     * @param self  self reference
+     * @param uri   URI component to encode
+     *
+     * @return encoded URIComponent
+     */
+    public static Object encodeURIComponent(final Object self, final Object uri) {
+        return URIUtils.encodeURIComponent(self, JSType.toString(uri));
+    }
+
+    /**
+     * ECMA 15.1.3.1, decodeURI implementation
+     *
+     * @param self  self reference
+     * @param uri   URI to decode
+     *
+     * @return decoded URI
+     */
+    public static Object decodeURI(final Object self, final Object uri) {
+        return URIUtils.decodeURI(self, JSType.toString(uri));
+    }
+
+    /**
+     * ECMA 15.1.3.2, decodeURIComponent implementation
+     *
+     * @param self  self reference
+     * @param uri   URI component to encode
+     *
+     * @return decoded URI
+     */
+    public static Object decodeURIComponent(final Object self, final Object uri) {
+        return URIUtils.decodeURIComponent(self, JSType.toString(uri));
+    }
+
+    /**
+     * ECMA B.2.1, escape implementation
+     *
+     * @param self    self reference
+     * @param string  string to escape
+     *
+     * @return escaped string
+     */
+    public static String escape(final Object self, final Object string) {
+        final String str = JSType.toString(string);
+        final int length = str.length();
+
+        if (length == 0) {
+            return str;
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        for (int k = 0; k < length; k++) {
+            final char ch = str.charAt(k);
+            if (UNESCAPED.indexOf(ch) != -1) {
+                sb.append(ch);
+            } else if (ch < 256) {
+                sb.append('%');
+                final byte b = (byte)ch;
+                sb.append(Integer.toHexString(b & 0xFF).toUpperCase());
+            } else {
+                sb.append("%u");
+                sb.append(Integer.toHexString(ch & 0xFFFF).toUpperCase());
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * ECMA B.2.2, unescape implementation
+     *
+     * @param self    self reference
+     * @param string  string to unescape
+     *
+     * @return unescaped string
+     */
+    public static String unescape(final Object self, final Object string) {
+        final String str    = JSType.toString(string);
+        final int    length = str.length();
+
+        if (length == 0) {
+            return str;
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        for (int k = 0; k < length; k++) {
+            char ch = str.charAt(k);
+            if (ch != '%') {
+                sb.append(ch);
+            } else {
+                if (k < (length - 5)) {
+                   if (str.charAt(k + 1) == 'u') {
+                       try {
+                           ch = (char) Integer.parseInt(str.substring(k + 2, k + 6), 16);
+                           sb.append(ch);
+                           k += 5;
+                           continue;
+                       } catch (final NumberFormatException e) {
+                           //ignored
+                       }
+                   }
+                }
+
+                if (k < (length - 2)) {
+                    try {
+                        ch = (char) Integer.parseInt(str.substring(k + 1, k + 3), 16);
+                        sb.append(ch);
+                        k += 2;
+                        continue;
+                    } catch (final NumberFormatException e) {
+                        //ignored
+                    }
+                }
+
+                // everything fails
+                sb.append(ch);
+            }
+        }
+
+        return sb.toString();
+    }
+
+
+    /**
+     * ECMA 15.3.4 Properties of the Function Prototype Object.
+     * The Function prototype object is itself a Function object
+     * (its [[Class]] is "Function") that, when invoked, accepts
+     * any arguments and returns undefined. This method is used to
+     * implement that anonymous function.
+     *
+     * @param self  self reference
+     *
+     * @return undefined
+     */
+    public static Object anonymous(final Object self) {
+        return ScriptRuntime.UNDEFINED;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), GlobalFunctions.class, name, MH.type(rtype, types));
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java
new file mode 100644
index 0000000..b802a1a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java
@@ -0,0 +1,220 @@
+/*
+ * 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;
+
+import java.lang.invoke.MethodHandle;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+
+/**
+ * Runtime interface to the global scope of the current context.
+ * NOTE: never access {@code jdk.nashorn.internal.objects.Global} class directly
+ * from runtime/parser/codegen/ir etc. Always go through this interface.
+ * <p>
+ * The reason for this is that all objects in the @{code jdk.nashorn.internal.objects.*} package
+ * are different per Context and loaded separately by each Context class loader. Attempting
+ * to directly refer to an object in this package from the rest of the runtime
+ * will lead to {@code ClassNotFoundException} thrown upon link time
+ */
+
+public interface GlobalObject {
+    /**
+     * Initialize standard builtin objects like "Object", "Array", "Function" etc.
+     * as well as our extension builtin objects like "Java", "JSAdapter" as properties
+     * of the global scope object.
+     */
+    public void initBuiltinObjects();
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newScriptFunction(String, MethodHandle, ScriptObject, boolean)}
+     *
+     * @param name   function name
+     * @param handle invocation handle for function
+     * @param scope  the scope
+     * @param strict are we in strict mode
+     *
+     * @return new script function
+     */
+   public ScriptFunction newScriptFunction(String name, MethodHandle handle, ScriptObject scope, boolean strict);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#wrapAsObject(Object)}
+     *
+     * @param obj object to wrap
+     * @return    wrapped object
+     */
+   public Object wrapAsObject(Object obj);
+
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#primitiveLookup(LinkRequest, Object)}
+     *
+     * @param request the link request for the dynamic call site.
+     * @param self     self reference
+     *
+     * @return guarded invocation
+     */
+   public GuardedInvocation primitiveLookup(LinkRequest request, Object self);
+
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newObject()}
+     *
+     * @return the new ScriptObject
+     */
+   public ScriptObject newObject();
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#isError(ScriptObject)}
+     *
+     * @param sobj to check if it is an error object
+     * @return true if error object
+     */
+   public boolean isError(ScriptObject sobj);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newError(String)}
+     *
+     * @param msg the error message
+     *
+     * @return the new ScriptObject representing the error
+     */
+   public ScriptObject newError(String msg);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newEvalError(String)}
+     *
+     * @param msg the error message
+     *
+     * @return the new ScriptObject representing the eval error
+     */
+   public ScriptObject newEvalError(String msg);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newRangeError(String)}
+     *
+     * @param msg the error message
+     *
+     * @return the new ScriptObject representing the range error
+     */
+   public ScriptObject newRangeError(String msg);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newReferenceError(String)}
+     *
+     * @param msg the error message
+     *
+     * @return the new ScriptObject representing the reference error
+     */
+   public ScriptObject newReferenceError(String msg);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newSyntaxError(String)}
+     *
+     * @param msg the error message
+     *
+     * @return the new ScriptObject representing the syntax error
+     */
+   public ScriptObject newSyntaxError(String msg);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newTypeError(String)}
+     *
+     * @param msg the error message
+     *
+     * @return the new ScriptObject representing the type error
+     */
+   public ScriptObject newTypeError(String msg);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newURIError(String)}
+     *
+     * @param msg the error message
+     *
+     * @return the new ScriptObject representing the URI error
+     */
+    public ScriptObject newURIError(String msg);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newGenericDescriptor(boolean, boolean)}
+     *
+     * @param configurable is the described property configurable
+     * @param enumerable   is the described property enumerable
+     *
+     * @return property descriptor
+     */
+    public PropertyDescriptor newGenericDescriptor(boolean configurable, boolean enumerable);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newDataDescriptor(Object, boolean, boolean, boolean)}
+     *
+     * @param value        data value
+     * @param configurable is the described property configurable
+     * @param enumerable   is the described property enumerable
+     * @param writable     is the described property writable
+     *
+     * @return property descriptor
+     */
+    public PropertyDescriptor newDataDescriptor(Object value, boolean configurable, boolean enumerable, boolean writable);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newAccessorDescriptor(Object, Object, boolean, boolean)}
+     *
+     * @param get          property getter, or null if none
+     * @param set          property setter, or null if none
+     * @param configurable is the described property configurable
+     * @param enumerable   is the described property enumerable
+     *
+     * @return property descriptor
+     */
+    public PropertyDescriptor newAccessorDescriptor(Object get, Object set, boolean configurable, boolean enumerable);
+
+    /**
+     * Wrapper for {@link jdk.nashorn.internal.objects.Global#getDefaultValue(ScriptObject, Class)}
+     *
+     * @param sobj     script object
+     * @param typeHint type hint
+     *
+     * @return default value
+     */
+    public Object getDefaultValue(ScriptObject sobj, Class<?> typeHint);
+
+    /**
+     * Find the compiled Class for the given script source, if available
+     *
+     * @param source Source object of the script
+     * @return compiled Class object or null
+     */
+    public Class<?> findCachedClass(Source source);
+
+    /**
+     * Put the Source associated Class object in the Source-to-Class cache
+     *
+     * @param source Source of the script
+     * @param clazz compiled Class object for the source
+     */
+    public void cacheClass(Source source, Class<?> clazz);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSErrorType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSErrorType.java
new file mode 100644
index 0000000..d83d018
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSErrorType.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * Native ECMAScript Error types.
+ */
+public enum JSErrorType {
+    /** Generic error */
+    ERROR,
+    /** EvalError */
+    EVAL_ERROR,
+    /** RangeError */
+    RANGE_ERROR,
+    /** Reference Error */
+    REFERENCE_ERROR,
+    /** Syntax Error */
+    SYNTAX_ERROR,
+    /** Type Error */
+    TYPE_ERROR,
+    /** URI Error */
+    URI_ERROR
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
new file mode 100644
index 0000000..ba486be
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
@@ -0,0 +1,223 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.ScriptObject.isArray;
+
+import java.lang.invoke.MethodHandle;
+import java.util.Iterator;
+import java.util.List;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
+import jdk.nashorn.internal.ir.PropertyNode;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.parser.JSONParser;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+/**
+ * Utilities used by "JSON" object implementation.
+ */
+public final class JSONFunctions {
+    private JSONFunctions() {}
+    private static final MethodHandle REVIVER_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
+            ScriptFunction.class, ScriptObject.class, String.class, Object.class);
+
+    /**
+     * Returns JSON-compatible quoted version of the given string.
+     *
+     * @param str String to be quoted
+     * @return JSON-compatible quoted string
+     */
+    public static String quote(final String str) {
+        return JSONParser.quote(str);
+    }
+
+    /**
+     * Parses the given JSON text string and returns object representation.
+     *
+     * @param text JSON text to be parsed
+     * @param reviver  optional value: function that takes two parameters (key, value)
+     * @return Object representation of JSON text given
+     */
+    public static Object parse(final Object text, final Object reviver) {
+        final String     str     = JSType.toString(text);
+        final Context    context = Context.getContextTrusted();
+        final JSONParser parser  = new JSONParser(
+                new Source("<json>", str),
+                new Context.ThrowErrorManager(),
+                (context != null) ?
+                    context.getEnv()._strict :
+                    false);
+
+        Node node;
+
+        try {
+            node = parser.parse();
+        } catch (final ParserException e) {
+            throw ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
+        }
+
+        final ScriptObject global = Context.getGlobalTrusted();
+        Object unfiltered = convertNode(global, node);
+        return applyReviver(global, unfiltered, reviver);
+    }
+
+    // -- Internals only below this point
+
+    // parse helpers
+
+    // apply 'reviver' function if available
+    private static Object applyReviver(final ScriptObject global, final Object unfiltered, final Object reviver) {
+        if (reviver instanceof ScriptFunction) {
+            assert global instanceof GlobalObject;
+            final ScriptObject root = ((GlobalObject)global).newObject();
+            root.set("", unfiltered, root.isStrictContext());
+            return walk(root, "", (ScriptFunction)reviver);
+        }
+        return unfiltered;
+    }
+
+    // This is the abstract "Walk" operation from the spec.
+    private static Object walk(final ScriptObject holder, final Object name, final ScriptFunction reviver) {
+        final Object val = holder.get(name);
+        if (val == ScriptRuntime.UNDEFINED) {
+            return val;
+        } else if (val instanceof ScriptObject) {
+            final ScriptObject     valueObj = (ScriptObject)val;
+            final boolean          strict   = valueObj.isStrictContext();
+            final Iterator<String> iter     = valueObj.propertyIterator();
+
+            while (iter.hasNext()) {
+                final String key        = iter.next();
+                final Object newElement = walk(valueObj, key, reviver);
+
+                if (newElement == ScriptRuntime.UNDEFINED) {
+                    valueObj.delete(key, strict);
+                } else {
+                    valueObj.set(key, newElement, strict);
+                }
+            }
+
+            return valueObj;
+        } else if (isArray(val)) {
+            final ScriptObject      valueArray = (ScriptObject)val;
+            final boolean          strict     = valueArray.isStrictContext();
+            final Iterator<String> iter       = valueArray.propertyIterator();
+
+            while (iter.hasNext()) {
+                final String key        = iter.next();
+                final Object newElement = walk(valueArray, valueArray.get(key), reviver);
+
+                if (newElement == ScriptRuntime.UNDEFINED) {
+                    valueArray.delete(key, strict);
+                } else {
+                    valueArray.set(key, newElement, strict);
+                }
+            }
+            return valueArray;
+        } else {
+            try {
+                // Object.class, ScriptFunction.class, ScriptObject.class, String.class, Object.class);
+                return REVIVER_INVOKER.invokeExact(reviver, holder, JSType.toString(name), val);
+            } catch(Error|RuntimeException t) {
+                throw t;
+            } catch(final Throwable t) {
+                throw new RuntimeException(t);
+            }
+        }
+    }
+
+    // Converts IR node to runtime value
+    private static Object convertNode(final ScriptObject global, final Node node) {
+        assert global instanceof GlobalObject;
+
+        if (node instanceof LiteralNode) {
+            // check for array literal
+            if (node.tokenType() == TokenType.ARRAY) {
+                assert node instanceof LiteralNode.ArrayLiteralNode;
+                final Node[] elements = ((LiteralNode.ArrayLiteralNode)node).getValue();
+
+                // NOTE: We cannot use LiteralNode.isNumericArray() here as that
+                // method uses symbols of element nodes. Since we don't do lower
+                // pass, there won't be any symbols!
+                if (isNumericArray(elements)) {
+                    final double[] values = new double[elements.length];
+                    int   index = 0;
+
+                    for (final Node elem : elements) {
+                        values[index++] = JSType.toNumber(convertNode(global, elem));
+                    }
+                    return ((GlobalObject)global).wrapAsObject(values);
+                }
+
+                final Object[] values = new Object[elements.length];
+                int   index = 0;
+
+                for (final Node elem : elements) {
+                    values[index++] = convertNode(global, elem);
+                }
+
+                return ((GlobalObject)global).wrapAsObject(values);
+            }
+
+            return ((LiteralNode<?>)node).getValue();
+
+        } else if (node instanceof ObjectNode) {
+            final ObjectNode   objNode  = (ObjectNode) node;
+            final ScriptObject object   = ((GlobalObject)global).newObject();
+            final boolean      strict   = global.isStrictContext();
+            final List<Node>   elements = objNode.getElements();
+
+            for (final Node elem : elements) {
+                final PropertyNode pNode     = (PropertyNode) elem;
+                final Node         valueNode = pNode.getValue();
+
+                object.set(pNode.getKeyName(), convertNode(global, valueNode), strict);
+            }
+
+            return object;
+        } else if (node instanceof UnaryNode) {
+            // UnaryNode used only to represent negative number JSON value
+            final UnaryNode unaryNode = (UnaryNode)node;
+            return -((LiteralNode<?>)unaryNode.rhs()).getNumber();
+        } else {
+            return null;
+        }
+    }
+
+    // does the given IR node represent a numeric array?
+    private static boolean isNumericArray(final Node[] values) {
+        for (final Node node : values) {
+            if (node instanceof LiteralNode && ((LiteralNode<?>)node).getValue() instanceof Number) {
+                continue;
+            }
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
new file mode 100644
index 0000000..2197781
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
@@ -0,0 +1,941 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
+import jdk.internal.dynalink.beans.StaticClass;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.parser.Lexer;
+
+/**
+ * Representation for ECMAScript types - this maps directly to the ECMA script standard
+ */
+public enum JSType {
+    /** The undefined type */
+    UNDEFINED,
+
+    /** The null type */
+    NULL,
+
+    /** The boolean type */
+    BOOLEAN,
+
+    /** The number type */
+    NUMBER,
+
+    /** The string type */
+    STRING,
+
+    /** The object type */
+    OBJECT,
+
+    /** The function type */
+    FUNCTION;
+
+    /** Max value for an uint32 in JavaScript */
+    public static final long MAX_UINT = 0xFFFF_FFFFL;
+
+    /** JavaScript compliant conversion function from Object to boolean */
+    public static final Call TO_BOOLEAN = staticCall(JSType.class, "toBoolean", boolean.class, Object.class);
+
+    /** JavaScript compliant conversion function from number to boolean */
+    public static final Call TO_BOOLEAN_D = staticCall(JSType.class, "toBoolean", boolean.class, double.class);
+
+    /** JavaScript compliant conversion function from Object to integer */
+    public static final Call TO_INTEGER = staticCall(JSType.class, "toInteger", int.class, Object.class);
+
+    /** JavaScript compliant conversion function from Object to long */
+    public static final Call TO_LONG = staticCall(JSType.class, "toLong", long.class, Object.class);
+
+    /** JavaScript compliant conversion function from Object to number */
+    public static final Call TO_NUMBER = staticCall(JSType.class, "toNumber", double.class, Object.class);
+
+    /** JavaScript compliant conversion function from Object to int32 */
+    public static final Call TO_INT32 = staticCall(JSType.class, "toInt32", int.class, Object.class);
+
+    /** JavaScript compliant conversion function from double to int32 */
+    public static final Call TO_INT32_D = staticCall(JSType.class, "toInt32", int.class, double.class);
+
+    /** JavaScript compliant conversion function from Object to uint32 */
+    public static final Call TO_UINT32 = staticCall(JSType.class, "toUint32", long.class, Object.class);
+
+    /** JavaScript compliant conversion function from number to uint32 */
+    public static final Call TO_UINT32_D = staticCall(JSType.class, "toUint32", long.class, double.class);
+
+    /** JavaScript compliant conversion function from Object to int64 */
+    public static final Call TO_INT64 = staticCall(JSType.class, "toInt64", long.class, Object.class);
+
+    /** JavaScript compliant conversion function from number to int64 */
+    public static final Call TO_INT64_D = staticCall(JSType.class, "toInt64", long.class, double.class);
+
+    /** JavaScript compliant conversion function from Object to String */
+    public static final Call TO_STRING = staticCall(JSType.class, "toString", String.class, Object.class);
+
+    /** JavaScript compliant conversion function from number to String */
+    public static final Call TO_STRING_D = staticCall(JSType.class, "toString", String.class, double.class);
+
+    /** JavaScript compliant conversion function from Object to primitive */
+    public static final Call TO_PRIMITIVE = staticCall(JSType.class, "toPrimitive", Object.class,  Object.class);
+
+    /**
+     * The external type name as returned by ECMAScript "typeof" operator
+     *
+     * @return type name for this type
+     */
+    public final String typeName() {
+        // For NULL, "object" has to be returned!
+        return ((this == NULL) ? OBJECT : this).name().toLowerCase();
+    }
+
+    /**
+     * Return the JSType for a given object
+     *
+     * @param obj an object
+     *
+     * @return the JSType for the object
+     */
+    public static JSType of(final Object obj) {
+        if (obj == ScriptRuntime.UNDEFINED) {
+            return JSType.UNDEFINED;
+        }
+
+        if (obj == null) {
+            return JSType.NULL;
+        }
+
+        if (obj instanceof Boolean) {
+            return JSType.BOOLEAN;
+        }
+
+        if (obj instanceof Number) {
+            return JSType.NUMBER;
+        }
+
+        if (obj instanceof String || obj instanceof ConsString) {
+            return JSType.STRING;
+        }
+
+        if (obj instanceof ScriptObject) {
+            return (obj instanceof ScriptFunction) ? JSType.FUNCTION : JSType.OBJECT;
+        }
+
+        if (obj instanceof StaticClass) {
+            return JSType.FUNCTION;
+        }
+
+        return JSType.OBJECT;
+    }
+
+    /**
+     * Returns true if double number can be represented as an int
+     *
+     * @param number a long to inspect
+     *
+     * @return true for int representable longs
+     */
+    public static boolean isRepresentableAsInt(final long number) {
+        return (int)number == number;
+    }
+
+    /**
+     * Returns true if double number can be represented as an int
+     *
+     * @param number a double to inspect
+     *
+     * @return true for int representable doubles
+     */
+    public static boolean isRepresentableAsInt(final double number) {
+        return (int)number == number;
+    }
+
+    /**
+     * Returns true if double number can be represented as a long
+     *
+     * @param number a double to inspect
+     * @return true for long representable doubles
+     */
+    public static boolean isRepresentableAsLong(final double number) {
+        return (long)number == number;
+    }
+
+    /**
+     * Get the smallest integer representation of a number. Returns an Integer
+     * for something that is int representable, and Long for something that
+     * is long representable. If the number needs to be a double, this is an
+     * identity function
+     *
+     * @param number number to check
+     *
+     * @return Number instanceof the narrowest possible integer representation for number
+     */
+    public static Number narrowestIntegerRepresentation(final double number) {
+        if (isRepresentableAsInt(number)) {
+            return (int)number;
+        } else if (isRepresentableAsLong(number)) {
+            return (long)number;
+        } else {
+            return number;
+        }
+    }
+
+    /**
+     * Check whether an object is primitive
+     *
+     * @param obj an object
+     *
+     * @return true if object is primitive (includes null and undefined)
+     */
+   public static boolean isPrimitive(final Object obj) {
+        return obj == null ||
+               obj == ScriptRuntime.UNDEFINED ||
+               obj instanceof Boolean ||
+               obj instanceof Number ||
+               obj instanceof String ||
+               obj instanceof ConsString;
+    }
+
+   /**
+    * Primitive converter for an object
+    *
+    * @param obj an object
+    *
+    * @return primitive form of the object
+    */
+    public static Object toPrimitive(final Object obj) {
+        return toPrimitive(obj, null);
+    }
+
+    /**
+     * Primitive converter for an object including type hint
+     * See ECMA 9.1 ToPrimitive
+     *
+     * @param obj  an object
+     * @param hint a type hint
+     *
+     * @return the primitive form of the object
+     */
+    public static Object toPrimitive(final Object obj, final Class<?> hint) {
+        if (!(obj instanceof ScriptObject)) {
+            return obj;
+        }
+
+        final ScriptObject sobj   = (ScriptObject)obj;
+        final Object       result = sobj.getDefaultValue(hint);
+
+        if (!isPrimitive(result)) {
+            throw typeError("bad.default.value", result.toString());
+        }
+
+        return result;
+    }
+
+    /**
+     * JavaScript compliant conversion of number to boolean
+     *
+     * @param num a number
+     *
+     * @return a boolean
+     */
+    public static boolean toBoolean(final double num) {
+        return num != 0 && !Double.isNaN(num);
+    }
+
+    /**
+     * JavaScript compliant conversion of Object to boolean
+     * See ECMA 9.2 ToBoolean
+     *
+     * @param obj an object
+     *
+     * @return a boolean
+     */
+    public static boolean toBoolean(final Object obj) {
+        if (obj instanceof Boolean) {
+            return (Boolean)obj;
+        }
+
+        if (nullOrUndefined(obj)) {
+            return false;
+        }
+
+        if (obj instanceof Number) {
+            final double num = ((Number)obj).doubleValue();
+            return num != 0 && !Double.isNaN(num);
+        }
+
+        if (obj instanceof String || obj instanceof ConsString) {
+            return ((CharSequence)obj).length() > 0;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * JavaScript compliant converter of Object to String
+     * See ECMA 9.8 ToString
+     *
+     * @param obj an object
+     *
+     * @return a string
+     */
+    public static String toString(final Object obj) {
+        return toStringImpl(obj, false);
+    }
+
+    /**
+     * If obj is an instance of {@link ConsString} cast to CharSequence, else return
+     * result of {@link #toString(Object)}.
+     *
+     * @param obj an object
+     * @return an instance of String or ConsString
+     */
+    public static CharSequence toCharSequence(final Object obj) {
+        if (obj instanceof ConsString) {
+            return (CharSequence) obj;
+        }
+        return toString(obj);
+    }
+
+    /**
+     * Check whether a string is representable as a JavaScript number
+     *
+     * @param str  a string
+     *
+     * @return     true if string can be represented as a number
+     */
+    public static boolean isNumber(final String str) {
+        try {
+            Double.parseDouble(str);
+            return true;
+        } catch (final NumberFormatException e) {
+            return false;
+        }
+    }
+
+    /**
+     * JavaScript compliant conversion of integer to String
+     *
+     * @param num an integer
+     *
+     * @return a string
+     */
+    public static String toString(final int num) {
+        return Integer.toString(num);
+    }
+
+    /**
+     * JavaScript compliant conversion of number to String
+     * See ECMA 9.8.1
+     *
+     * @param num a number
+     *
+     * @return a string
+     */
+    public static String toString(final double num) {
+        if (isRepresentableAsInt(num)) {
+            return Integer.toString((int)num);
+        }
+
+        if (num == Double.POSITIVE_INFINITY) {
+            return "Infinity";
+        }
+
+        if (num == Double.NEGATIVE_INFINITY) {
+            return "-Infinity";
+        }
+
+        if (Double.isNaN(num)) {
+            return "NaN";
+        }
+
+        return NumberToString.stringFor(num);
+    }
+
+    /**
+     * JavaScript compliant conversion of number to String
+     *
+     * @param num   a number
+     * @param radix a radix for the conversion
+     *
+     * @return a string
+     */
+    public static String toString(final double num, final int radix) {
+        assert radix >= 2 && radix <= 36 : "invalid radix";
+
+        if (isRepresentableAsInt(num)) {
+            return Integer.toString((int)num, radix);
+        }
+
+        if (num == Double.POSITIVE_INFINITY) {
+            return "Infinity";
+        }
+
+        if (num == Double.NEGATIVE_INFINITY) {
+            return "-Infinity";
+        }
+
+        if (Double.isNaN(num)) {
+            return "NaN";
+        }
+
+        if (num == 0.0) {
+            return "0";
+        }
+
+        final String chars     = "0123456789abcdefghijklmnopqrstuvwxyz";
+        final StringBuilder sb = new StringBuilder();
+
+        final boolean negative  = num < 0.0;
+        final double  signedNum = negative ? -num : num;
+
+        double intPart = Math.floor(signedNum);
+        double decPart = signedNum - intPart;
+
+        // encode integer part from least significant digit, then reverse
+        do {
+            sb.append(chars.charAt((int) (intPart % radix)));
+            intPart /= radix;
+        } while (intPart >= 1.0);
+
+        if (negative) {
+            sb.append('-');
+        }
+        sb.reverse();
+
+        // encode decimal part
+        if (decPart > 0.0) {
+            final int dot = sb.length();
+            sb.append('.');
+            do {
+                decPart *= radix;
+                final double d = Math.floor(decPart);
+                sb.append(chars.charAt((int)d));
+                decPart -= d;
+            } while (decPart > 0.0 && sb.length() - dot < 1100);
+            // somewhat arbitrarily use same limit as V8
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * JavaScript compliant conversion of Object to number
+     * See ECMA 9.3 ToNumber
+     *
+     * @param obj  an object
+     *
+     * @return a number
+     */
+    public static double toNumber(final Object obj) {
+        if (obj instanceof Number) {
+            return ((Number)obj).doubleValue();
+        }
+        return toNumberGeneric(obj);
+    }
+
+    /**
+     * Digit representation for a character
+     *
+     * @param ch     a character
+     * @param radix  radix
+     *
+     * @return the digit for this character
+     */
+    public static int digit(final char ch, final int radix) {
+        return digit(ch, radix, false);
+    }
+
+    /**
+     * Digit representation for a character
+     *
+     * @param ch             a character
+     * @param radix          radix
+     * @param onlyIsoLatin1  iso latin conversion only
+     *
+     * @return the digit for this character
+     */
+    public static int digit(final char ch, final int radix, final boolean onlyIsoLatin1) {
+        final char maxInRadix = (char)('a' + (radix - 1) - 10);
+        final char c          = Character.toLowerCase(ch);
+
+        if (c >= 'a' && c <= maxInRadix) {
+            return Character.digit(ch, radix);
+        }
+
+        if (Character.isDigit(ch)) {
+            if (!onlyIsoLatin1 || ch >= '0' && ch <= '9') {
+                return Character.digit(ch, radix);
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * JavaScript compliant String to number conversion
+     *
+     * @param str  a string
+     *
+     * @return a number
+     */
+    public static double toNumber(final String str) {
+        int end = str.length();
+        if (end == 0) {
+            return 0.0; // Empty string
+        }
+
+        int  start = 0;
+        char f     = str.charAt(0);
+
+        while (Lexer.isJSWhitespace(f)) {
+            if (++start == end) {
+                return 0.0d; // All whitespace string
+            }
+            f = str.charAt(start);
+        }
+
+        // Guaranteed to terminate even without start >= end check, as the previous loop found at least one
+        // non-whitespace character.
+        while (Lexer.isJSWhitespace(str.charAt(end - 1))) {
+            end--;
+        }
+
+        final boolean negative;
+        if (f == '-') {
+            if(++start == end) {
+                return Double.NaN; // Single-char "-" string
+            }
+            f = str.charAt(start);
+            negative = true;
+        } else {
+            if (f == '+') {
+                if (++start == end) {
+                    return Double.NaN; // Single-char "+" string
+                }
+                f = str.charAt(start);
+            }
+            negative = false;
+        }
+
+        final double value;
+        if (start + 1 < end && f == '0' && Character.toLowerCase(str.charAt(start + 1)) == 'x') {
+            //decode hex string
+            value = parseRadix(str.toCharArray(), start + 2, end, 16);
+        } else {
+            // Fast (no NumberFormatException) path to NaN for non-numeric strings. We allow those starting with "I" or
+            // "N" to allow for parsing "NaN" and "Infinity" correctly.
+            if ((f < '0' || f > '9') && f != '.' && f != 'I' && f != 'N') {
+                return Double.NaN;
+            }
+            try {
+                value = Double.parseDouble(str.substring(start, end));
+            } catch (final NumberFormatException e) {
+                return Double.NaN;
+            }
+        }
+
+        return negative ? -value : value;
+    }
+
+    /**
+     * JavaScript compliant Object to integer conversion
+     * See ECMA 9.4 ToInteger
+     *
+     * @param obj  an object
+     * @return an integer
+     */
+    public static int toInteger(final Object obj) {
+        return (int)toNumber(obj);
+    }
+
+    /**
+     * JavaScript compliant Object to long conversion
+     * See ECMA 9.4 ToInteger
+     *
+     * @param obj  an object
+     * @return a long
+     */
+    public static long toLong(final Object obj) {
+        return (long)toNumber(obj);
+    }
+
+    /**
+     * JavaScript compliant Object to int32 conversion
+     * See ECMA 9.5 ToInt32
+     *
+     * @param obj an object
+     * @return an int32
+     */
+    public static int toInt32(final Object obj) {
+        return toInt32(toNumber(obj));
+    }
+
+    /**
+     * JavaScript compliant long to int32 conversion
+     *
+     * @param num a long
+     * @return an int32
+     */
+    public static int toInt32(final long num) {
+        return (int)num;
+    }
+
+    /**
+     * JavaScript compliant number to int32 conversion
+     *
+     * @param num a number
+     * @return an int32
+     */
+    public static int toInt32(final double num) {
+        if (Double.isInfinite(num)) {
+            return 0;
+        }
+        return (int)(long)num;
+    }
+
+    /**
+     * JavaScript compliant Object to int64 conversion
+     *
+     * @param obj an object
+     * @return an int64
+     */
+    public static long toInt64(final Object obj) {
+        return toInt64(toNumber(obj));
+    }
+
+    /**
+     * JavaScript compliant number to int64 conversion
+     *
+     * @param num a number
+     * @return an int64
+     */
+    public static long toInt64(final double num) {
+        if (Double.isInfinite(num)) {
+            return 0L;
+        }
+        return (long)num;
+    }
+
+    /**
+     * JavaScript compliant Object to uint32 conversion
+     *
+     * @param obj an object
+     * @return a uint32
+     */
+    public static long toUint32(final Object obj) {
+        return toUint32(toNumber(obj));
+    }
+
+    /**
+     * JavaScript compliant number to uint32 conversion
+     *
+     * @param num a number
+     * @return a uint32
+     */
+    public static long toUint32(final double num) {
+        if (Double.isInfinite(num)) {
+            return 0L;
+        }
+        return ((long)num) & 0xffff_ffffL;
+    }
+
+    /**
+     * JavaScript compliant Object to uint16 conversion
+     * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer)
+     *
+     * @param obj an object
+     * @return a uint16
+     */
+    public static int toUint16(final Object obj) {
+        return toUint16(toNumber(obj));
+    }
+
+    /**
+     * JavaScript compliant number to uint16 conversion
+     *
+     * @param num a number
+     * @return a uint16
+     */
+    public static int toUint16(final int num) {
+        return num & 0xffff;
+    }
+
+    /**
+     * JavaScript compliant number to uint16 conversion
+     *
+     * @param num a number
+     * @return a uint16
+     */
+    public static int toUint16(final long num) {
+        return ((int)num) & 0xffff;
+    }
+
+    /**
+     * JavaScript compliant number to uint16 conversion
+     *
+     * @param num a number
+     * @return a uint16
+     */
+    public static int toUint16(final double num) {
+        if (Double.isInfinite(num)) {
+            return 0;
+        }
+        return ((int)(long)num) & 0xffff;
+    }
+
+    /**
+     * Check whether a number is finite
+     *
+     * @param num a number
+     * @return true if finite
+     */
+    public static boolean isFinite(final double num) {
+        return !Double.isInfinite(num) && !Double.isNaN(num);
+    }
+
+    /**
+     * Convert a primitive to a double
+     *
+     * @param num a double
+     * @return a boxed double
+     */
+    public static Double toDouble(final double num) {
+        return num;
+    }
+
+    /**
+     * Convert a primitive to a double
+     *
+     * @param num a long
+     * @return a boxed double
+     */
+    public static Double toDouble(final long num) {
+        return (double)num;
+    }
+
+    /**
+     * Convert a primitive to a double
+     *
+     * @param num an int
+     * @return a boxed double
+     */
+    public static Double toDouble(final int num) {
+        return (double)num;
+    }
+
+    /**
+     * Convert a boolean to an Object
+     *
+     * @param bool a boolean
+     * @return a boxed boolean, its Object representation
+     */
+    public static Object toObject(final boolean bool) {
+        return bool;
+    }
+
+    /**
+     * Convert a number to an Object
+     *
+     * @param num an integer
+     * @return the boxed number
+     */
+    public static Object toObject(final int num) {
+        return num;
+    }
+
+    /**
+     * Convert a number to an Object
+     *
+     * @param num a long
+     * @return the boxed number
+     */
+    public static Object toObject(final long num) {
+        return num;
+    }
+
+    /**
+     * Convert a number to an Object
+     *
+     * @param num a double
+     * @return the boxed number
+     */
+    public static Object toObject(final double num) {
+        return num;
+    }
+
+    /**
+     * Identity converter for objects.
+     *
+     * @param obj an object
+     * @return the boxed number
+     */
+    public static Object toObject(final Object obj) {
+        return obj;
+    }
+
+    /**
+     * Object conversion. This is used to convert objects and numbers to their corresponding
+     * NativeObject type
+     * See ECMA 9.9 ToObject
+     *
+     * @param obj     the object to convert
+     *
+     * @return the wrapped object
+     */
+    public static Object toScriptObject(final Object obj) {
+        return toScriptObject(Context.getGlobalTrusted(), obj);
+    }
+
+    /**
+     * Object conversion. This is used to convert objects and numbers to their corresponding
+     * NativeObject type
+     * See ECMA 9.9 ToObject
+     *
+     * @param global  the global object
+     * @param obj     the object to convert
+     *
+     * @return the wrapped object
+     */
+    public static Object toScriptObject(final ScriptObject global, final Object obj) {
+        if (nullOrUndefined(obj)) {
+            throw typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
+        }
+
+        if (obj instanceof ScriptObject) {
+            return obj;
+        }
+
+        return ((GlobalObject)global).wrapAsObject(obj);
+    }
+
+    /**
+     * Check if an object is null or undefined
+     *
+     * @param obj object to check
+     *
+     * @return true if null or undefined
+     */
+    public static boolean nullOrUndefined(final Object obj) {
+        return obj == null || obj == ScriptRuntime.UNDEFINED;
+    }
+
+    static String toStringImpl(final Object obj, final boolean safe) {
+        if (obj instanceof String) {
+            return (String)obj;
+        }
+
+        if (obj instanceof Number) {
+            return toString(((Number)obj).doubleValue());
+        }
+
+        if (obj == ScriptRuntime.UNDEFINED) {
+            return "undefined";
+        }
+
+        if (obj == null) {
+            return "null";
+        }
+
+        if (obj instanceof ScriptObject) {
+            if (safe) {
+                final ScriptObject sobj = (ScriptObject)obj;
+                final GlobalObject gobj = (GlobalObject)Context.getGlobalTrusted();
+                return gobj.isError(sobj) ?
+                    ECMAException.safeToString(sobj) :
+                    sobj.safeToString();
+            }
+
+            return toString(toPrimitive(obj, String.class));
+        }
+
+        if (obj instanceof StaticClass) {
+            return "[JavaClass " + ((StaticClass)obj).getRepresentedClass().getName() + "]";
+        }
+
+        return obj.toString();
+    }
+
+    // trim from left for JS whitespaces.
+    static String trimLeft(final String str) {
+        int start = 0;
+
+        while (start < str.length() && Lexer.isJSWhitespace(str.charAt(start))) {
+            start++;
+        }
+
+        return str.substring(start);
+    }
+
+    private static double parseRadix(final char chars[], final int start, final int length, final int radix) {
+        int pos = 0;
+
+        for (int i = start; i < length ; i++) {
+            if (digit(chars[i], radix) == -1) {
+                break;
+            }
+            pos++;
+        }
+
+        if (pos == 0) {
+            return Double.NaN;
+        }
+
+        double value = 0.0;
+        for (int i = start; i < start + pos; i++) {
+            value *= radix;
+            value += digit(chars[i], radix);
+        }
+
+        return value;
+    }
+
+    private static double toNumberGeneric(final Object obj) {
+        if (obj == null) {
+            return +0.0;
+        }
+
+        if (obj instanceof String) {
+            return toNumber((String)obj);
+        }
+
+        if (obj instanceof ConsString) {
+            return toNumber(obj.toString());
+        }
+
+        if (obj instanceof Boolean) {
+            return (Boolean)obj ? 1 : +0.0;
+        }
+
+        if (obj instanceof ScriptObject) {
+            return toNumber(toPrimitive(obj, Number.class));
+        }
+
+        return Double.NaN;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Logging.java b/nashorn/src/jdk/nashorn/internal/runtime/Logging.java
new file mode 100644
index 0000000..8a69ebf
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Logging.java
@@ -0,0 +1,163 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+/**
+ * Logging system for getting loggers for arbitrary subsystems as
+ * specified on the command line. Supports all standard log levels
+ *
+ */
+public final class Logging {
+
+    private Logging() {
+    }
+
+    /** Loggers */
+
+    private static final Logger disabledLogger = Logger.getLogger("disabled");
+
+    static {
+        try {
+            Logging.disabledLogger.setLevel(Level.OFF);
+        } catch (final SecurityException e) {
+            //ignored
+        }
+    }
+
+    /** Maps logger name to loggers. Names are typically per package */
+    private static final Map<String, Logger> loggers = new HashMap<>();
+
+    private static String lastPart(final String packageName) {
+        final String[] parts = packageName.split("\\.");
+        if (parts.length == 0) {
+            return packageName;
+        }
+        return parts[parts.length - 1];
+    }
+
+    /**
+     * Get a logger for a given class, generating a logger name based on the
+     * class name
+     *
+     * @param name the name to use as key for the logger
+     * @return the logger
+     */
+    public static Logger getLogger(final String name) {
+        final Logger logger = Logging.loggers.get(name);
+        if (logger != null) {
+            return logger;
+        }
+        return Logging.disabledLogger;
+    }
+
+    /**
+     * Get a logger for a given name or create it if not already there, typically
+     * used for mapping system properties to loggers
+     *
+     * @param name the name to use as key
+     * @param level log lever to reset existing logger with, or create new logger with
+     * @return the logger
+     */
+    public static Logger getOrCreateLogger(final String name, final Level level) {
+        final Logger logger = Logging.loggers.get(name);
+        if (logger == null) {
+            return instantiateLogger(name, level);
+        }
+        logger.setLevel(level);
+        return logger;
+    }
+
+    /**
+     * Initialization function that is called to instantiate the logging system. It takes
+     * logger names (keys) and logging labels respectively
+     *
+     * @param map a map where the key is a logger name and the value a logging level
+     * @throws IllegalArgumentException if level or names cannot be parsed
+     */
+    public static void initialize(final Map<String, String> map) throws IllegalArgumentException {
+        try {
+            for (final Entry<String, String> entry : map.entrySet()) {
+                Level level;
+
+                final String key   = entry.getKey();
+                final String value = entry.getValue();
+                if ("".equals(value)) {
+                    level = Level.INFO;
+                } else {
+                    level = Level.parse(value.toUpperCase());
+                }
+
+                final String name = Logging.lastPart(key);
+                final Logger logger = instantiateLogger(name, level);
+
+                Logging.loggers.put(name, logger);
+            }
+        } catch (final IllegalArgumentException | SecurityException e) {
+            throw e;
+        }
+    }
+
+    private static Logger instantiateLogger(final String name, final Level level) {
+        final Logger logger = java.util.logging.Logger.getLogger(name);
+        for (final Handler h : logger.getHandlers()) {
+            logger.removeHandler(h);
+        }
+
+        logger.setLevel(level);
+        logger.setUseParentHandlers(false);
+        final Handler c = new ConsoleHandler();
+
+        c.setFormatter(new Formatter() {
+            @Override
+            public String format(final LogRecord record) {
+                final StringBuilder sb = new StringBuilder();
+
+                sb.append('[')
+                   .append(record.getLoggerName())
+                   .append("] ")
+                   .append(record.getMessage())
+                   .append('\n');
+
+                return sb.toString();
+            }
+        });
+        logger.addHandler(c);
+        c.setLevel(level);
+
+        return logger;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java
new file mode 100644
index 0000000..80a0b8e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java
@@ -0,0 +1,141 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.SecureClassLoader;
+import jdk.nashorn.tools.Shell;
+
+/**
+ * Superclass for Nashorn class loader classes. This stores Context
+ * instance as an instance field. The current context can be
+ * efficiently accessed from a given Class via it's ClassLoader.
+ *
+ */
+abstract class NashornLoader extends SecureClassLoader {
+    private final Context context;
+
+    final Context getContext() {
+        return context;
+    }
+
+    NashornLoader(final ClassLoader parent, final Context context) {
+        super(parent);
+        this.context = context;
+    }
+
+
+    /**
+     * Called by subclass after package access check is done
+     * @param name name of the class to be loaded
+     * @param resolve whether the class should be resolved or not
+     * @return Class object
+     * @throws ClassNotFoundException if class cannot be loaded
+     */
+    protected final Class<?> loadClassTrusted(final String name, final boolean resolve) throws ClassNotFoundException {
+        return super.loadClass(name, resolve);
+    }
+
+    protected static void checkPackageAccess(final String name) {
+        final int i = name.lastIndexOf('.');
+        if (i != -1) {
+            final SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                sm.checkPackageAccess(name.substring(0, i));
+            }
+        }
+    }
+
+    /**
+     * Create a secure URL class loader for the given classpath
+     * @param classPath classpath for the loader to search from
+     * @return the class loader
+     */
+    static ClassLoader createClassLoader(final String classPath) {
+        final ClassLoader parent = Shell.class.getClassLoader();
+        final URL[] urls = pathToURLs(classPath);
+        return URLClassLoader.newInstance(urls, parent);
+    }
+
+    /*
+     * Utility method for converting a search path string to an array
+     * of directory and JAR file URLs.
+     *
+     * @param path the search path string
+     * @return the resulting array of directory and JAR file URLs
+     */
+    private static URL[] pathToURLs(final String path) {
+        final String[] components = path.split(File.pathSeparator);
+        URL[] urls = new URL[components.length];
+        int count = 0;
+        while(count < components.length) {
+            final URL url = fileToURL(new File(components[count]));
+            if (url != null) {
+                urls[count++] = url;
+            }
+        }
+        if (urls.length != count) {
+            final URL[] tmp = new URL[count];
+            System.arraycopy(urls, 0, tmp, 0, count);
+            urls = tmp;
+        }
+        return urls;
+    }
+
+    /*
+     * Returns the directory or JAR file URL corresponding to the specified
+     * local file name.
+     *
+     * @param file the File object
+     * @return the resulting directory or JAR file URL, or null if unknown
+     */
+    private static URL fileToURL(final File file) {
+        String name;
+        try {
+            name = file.getCanonicalPath();
+        } catch (final IOException e) {
+            name = file.getAbsolutePath();
+        }
+        name = name.replace(File.separatorChar, '/');
+        if (!name.startsWith("/")) {
+            name = "/" + name;
+        }
+        // If the file does not exist, then assume that it's a directory
+        if (!file.isFile()) {
+            name = name + "/";
+        }
+        try {
+            return new URL("file", "", name);
+        } catch (final MalformedURLException e) {
+            throw new IllegalArgumentException("file");
+        }
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java
new file mode 100644
index 0000000..d75abd3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java
@@ -0,0 +1,191 @@
+/*
+ * 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;
+
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.beans.StaticClass;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.objects.NativeJava;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Function;
+
+/**
+ * An object that exposes Java packages and classes as its properties. Packages are exposed as objects that have further
+ * sub-packages and classes as their properties. Normally, three instances of this class are exposed as built-in objects
+ * in Nashorn: {@code "Packages"}, {@code "java"}, and {@code "javax"}. Typical usages are:
+ * <pre>
+ * var list = new java.util.ArrayList()
+ * var sprocket = new Packages.com.acme.Sprocket()
+ * </pre>
+ * or you can store the type objects in a variable for later reuse:
+ * <pre>
+ * var ArrayList = java.util.ArrayList
+ * var list = new ArrayList
+ * </pre>
+ * You can also use {@link NativeJava#type(Object, Object)} to access Java classes. These two statements are mostly
+ * equivalent:
+ * <pre>
+ * var listType1 = java.util.ArrayList
+ * var listType2 = Java.type("java.util.ArrayList")
+ * </pre>
+ * The difference is that {@code Java.type()} will throw an error if the class does not exist, while the first
+ * expression will return an empty object, as it must treat all non-existent classes as potentially being further
+ * subpackages. As such, {@code Java.type()} has the potential to catch typos earlier. A further difference is that
+ * {@code Java.type()} doesn't recognize {@code .} (dot) as the separator between outer class name and inner class name,
+ * it only recognizes the dollar sign. These are equivalent:
+ * <pre>
+ * var ftype1 = java.awt.geom.Arc2D$Float
+ * var ftype2 = java.awt.geom.Arc2D.Float
+ * var ftype3 = Java.asType("java.awt.geom.Arc2D$Float")
+ * var ftype4 = Java.asType("java.awt.geom.Arc2D").Float
+ * </pre>
+ */
+public final class NativeJavaPackage extends ScriptObject {
+    /** Full name of package (includes path.) */
+    private final String name;
+
+    /**
+     * Public constructor to be accessible from {@link jdk.nashorn.internal.objects.Global}
+     * @param name  package name
+     * @param proto proto
+     */
+    public NativeJavaPackage(final String name, final ScriptObject proto) {
+        this.name = name;
+        this.setProto(proto);
+    }
+
+    @Override
+    public String getClassName() {
+        return "JavaPackage";
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other instanceof NativeJavaPackage) {
+            return name.equals(((NativeJavaPackage)other).name);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return name == null ? 0 : name.hashCode();
+    }
+
+    /**
+     * Get the full name of the package
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String safeToString() {
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        return "[JavaPackage " + name + "]";
+    }
+
+    @Override
+    public Object getDefaultValue(final Class<?> hint) {
+        if (hint == String.class) {
+            return toString();
+        }
+
+        return super.getDefaultValue(hint);
+    }
+
+    /**
+     * "No such property" call placeholder.
+     *
+     * This can never be called as we override {@link ScriptObject#noSuchProperty}. We do declare it here as it's a signal
+     * to {@link WithObject} that it's worth trying doing a {@code noSuchProperty} on this object.
+     *
+     * @param self self reference
+     * @param name property name
+     * @return never returns
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object __noSuchProperty__(final Object self, final Object name) {
+        throw new AssertionError("__noSuchProperty__ placeholder called");
+    }
+
+    /**
+     * "No such method call" placeholder
+     *
+     * This can never be called as we override {@link ScriptObject#noSuchMethod}. We do declare it here as it's a signal
+     * to {@link WithObject} that it's worth trying doing a noSuchProperty on this object.
+     *
+     * @param self self reference
+     * @param args arguments to method
+     * @return never returns
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static Object __noSuchMethod__(final Object self, final Object... args) {
+        throw new AssertionError("__noSuchMethod__ placeholder called");
+    }
+
+    /**
+     * Handle creation of new attribute.
+     * @param desc the call site descriptor
+     * @param request the link request
+     * @return Link to be invoked at call site.
+     */
+    @Override
+    public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) {
+        final String propertyName = desc.getNameToken(2);
+        final String fullName     = name.isEmpty() ? propertyName : name + "." + propertyName;
+
+        final Context context = getContext();
+        final boolean strict  = context._strict;
+
+        Class<?> javaClass = null;
+        try {
+            javaClass = context.findClass(fullName);
+        } catch (final ClassNotFoundException e) {
+            //ignored
+        }
+
+        if (javaClass == null) {
+            set(propertyName, new NativeJavaPackage(fullName, getProto()), strict);
+        } else {
+            set(propertyName, StaticClass.forClass(javaClass), strict);
+        }
+
+        return super.lookup(desc, request);
+    }
+
+    @Override
+    public GuardedInvocation noSuchMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        return noSuchProperty(desc, request);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/NumberToString.java b/nashorn/src/jdk/nashorn/internal/runtime/NumberToString.java
new file mode 100644
index 0000000..8a05e31
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/NumberToString.java
@@ -0,0 +1,786 @@
+/*
+ * 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;
+
+import java.math.BigInteger;
+
+/**
+ * JavaScript number to string conversion, refinement of sun.misc.FloatingDecimal.
+ */
+public final class NumberToString {
+    /** Is not a number flag */
+    private final boolean isNaN;
+
+    /** Is a negative number flag. */
+    private boolean isNegative;
+
+    /** Decimal exponent value (for E notation.) */
+    private int decimalExponent;
+
+    /** Actual digits. */
+    private char digits[];
+
+    /** Number of digits to use. (nDigits <= digits.length). */
+    private int nDigits;
+
+    /*
+     * IEEE-754 constants.
+     */
+
+    //private static final long   signMask           = 0x8000000000000000L;
+    private static final int    expMask            = 0x7FF;
+    private static final long   fractMask          = 0x000F_FFFF_FFFF_FFFFL;
+    private static final int    expShift           = 52;
+    private static final int    expBias            = 1_023;
+    private static final long   fractHOB           = (1L << expShift);
+    private static final long   expOne             = ((long)expBias) << expShift;
+    private static final int    maxSmallBinExp     = 62;
+    private static final int    minSmallBinExp     = -(63 / 3);
+
+    /** Powers of 5 fitting a long. */
+    private static final long powersOf5[] = {
+        1L,
+        5L,
+        5L * 5,
+        5L * 5 * 5,
+        5L * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+        5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5
+    };
+
+    // Approximately ceil(log2(longPowers5[i])).
+    private static final int nBitsPowerOf5[] = {
+        0,
+        3,
+        5,
+        7,
+        10,
+        12,
+        14,
+        17,
+        19,
+        21,
+        24,
+        26,
+        28,
+        31,
+        33,
+        35,
+        38,
+        40,
+        42,
+        45,
+        47,
+        49,
+        52,
+        54,
+        56,
+        59,
+        61
+    };
+
+    /** Digits used for infinity result. */
+    private static final char infinityDigits[]   = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' };
+
+    /** Digits used for NaN result. */
+    private static final char nanDigits[]        = { 'N', 'a', 'N' };
+
+    /** Zeros used to pad result. */
+    private static final char zeroes[]           = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' };
+
+
+    /**
+     * Convert a number into a JavaScript string.
+     * @param value Double to convert.
+     * @return JavaScript formated number.
+     */
+    public static String stringFor(final double value) {
+        return new NumberToString(value).toString();
+    }
+
+    /*
+     * Constructor.
+     */
+
+    private NumberToString(final double value) {
+        // Double as bits.
+        long bits = Double.doubleToLongBits(value);
+
+        // Get upper word.
+        final int upper = (int)(bits >> 32);
+
+        // Detect sign.
+        isNegative = upper < 0;
+
+        // Extract exponent.
+        int exponent = (upper >> (expShift - 32)) & expMask;
+
+        // Clear sign and exponent.
+        bits &= fractMask;
+
+        // Detect NaN.
+        if (exponent == expMask) {
+            isNaN = true;
+
+            // Detect Infinity.
+            if (bits == 0L) {
+                digits =  infinityDigits;
+            } else {
+                digits = nanDigits;
+                isNegative = false;
+            }
+
+            nDigits = digits.length;
+
+            return;
+        }
+
+        // We have a working double.
+        isNaN = false;
+
+        int nSignificantBits;
+
+        // Detect denormalized value.
+        if (exponent == 0) {
+            // Detect zero value.
+            if (bits == 0L) {
+                decimalExponent = 0;
+                digits = zeroes;
+                nDigits = 1;
+
+                return;
+            }
+
+            // Normalize value, using highest significant bit as HOB.
+            while ((bits & fractHOB) == 0L) {
+                bits <<= 1;
+                exponent -= 1;
+            }
+
+            // Compute number of significant bits.
+            nSignificantBits = expShift + exponent +1;
+            // Bias exponent by HOB.
+            exponent += 1;
+        } else {
+            // Add implicit HOB.
+            bits |= fractHOB;
+            // Compute number of significant bits.
+            nSignificantBits = expShift + 1;
+        }
+
+        // Unbias exponent (represents bit shift).
+        exponent -= expBias;
+
+        // Determine the number of significant bits in the fraction.
+        final int nFractBits = countSignificantBits(bits);
+
+        // Number of bits to the right of the decimal.
+        final int nTinyBits = Math.max(0, nFractBits - exponent - 1);
+
+        // Computed decimal exponent.
+        int decExponent;
+
+        if (exponent <= maxSmallBinExp && exponent >= minSmallBinExp) {
+            // Look more closely at the number to decide if,
+            // with scaling by 10^nTinyBits, the result will fit in
+            // a long.
+            if (nTinyBits < powersOf5.length && (nFractBits + nBitsPowerOf5[nTinyBits]) < 64) {
+                /*
+                 * We can do this:
+                 * take the fraction bits, which are normalized.
+                 * (a) nTinyBits == 0: Shift left or right appropriately
+                 *     to align the binary point at the extreme right, i.e.
+                 *     where a long int point is expected to be. The integer
+                 *     result is easily converted to a string.
+                 * (b) nTinyBits > 0: Shift right by expShift - nFractBits,
+                 *     which effectively converts to long and scales by
+                 *     2^nTinyBits. Then multiply by 5^nTinyBits to
+                 *     complete the scaling. We know this won't overflow
+                 *     because we just counted the number of bits necessary
+                 *     in the result. The integer you get from this can
+                 *     then be converted to a string pretty easily.
+                 */
+
+                if (nTinyBits == 0) {
+                    long halfULP;
+
+                    if (exponent > nSignificantBits) {
+                        halfULP = 1L << (exponent - nSignificantBits - 1);
+                    } else {
+                        halfULP = 0L;
+                    }
+
+                    if (exponent >= expShift) {
+                        bits <<= exponent - expShift;
+                    } else {
+                        bits >>>= expShift - exponent;
+                    }
+
+                    // Discard non-significant low-order bits, while rounding,
+                    // up to insignificant value.
+                    int i;
+                    for (i = 0; halfULP >= 10L; i++) {
+                        halfULP /= 10L;
+                    }
+
+                    /**
+                     * This is the easy subcase --
+                     * all the significant bits, after scaling, are held in bits.
+                     * isNegative and decExponent tell us what processing and scaling
+                     * has already been done. Exceptional cases have already been
+                     * stripped out.
+                     * In particular:
+                     *      bits is a finite number (not Infinite, nor NaN)
+                     *      bits > 0L (not zero, nor negative).
+                     *
+                     * The only reason that we develop the digits here, rather than
+                     * calling on Long.toString() is that we can do it a little faster,
+                     * and besides want to treat trailing 0s specially. If Long.toString
+                     * changes, we should re-evaluate this strategy!
+                     */
+
+                    int decExp = 0;
+
+                    if (i != 0) {
+                         // 10^i == 5^i * 2^i
+                        final long powerOf10 = powersOf5[i] << i;
+                        final long residue = bits % powerOf10;
+                        bits /= powerOf10;
+                        decExp += i;
+
+                        if (residue >= (powerOf10 >> 1)) {
+                            // Round up based on the low-order bits we're discarding.
+                            bits++;
+                        }
+                    }
+
+                    int ndigits = 20;
+                    final char[] digits0 = new char[26];
+                    int digitno = ndigits - 1;
+                    int c = (int)(bits % 10L);
+                    bits /= 10L;
+
+                    while (c == 0) {
+                        decExp++;
+                        c = (int)(bits % 10L);
+                        bits /= 10L;
+                    }
+
+                    while (bits != 0L) {
+                        digits0[digitno--] = (char)(c + '0');
+                        decExp++;
+                        c = (int)(bits % 10L);
+                        bits /= 10;
+                    }
+
+                    digits0[digitno] = (char)(c + '0');
+
+                    ndigits -= digitno;
+                    final char[] result = new char[ndigits];
+                    System.arraycopy(digits0, digitno, result, 0, ndigits);
+
+                    this.digits          = result;
+                    this.decimalExponent = decExp + 1;
+                    this.nDigits         = ndigits;
+
+                    return;
+                }
+            }
+        }
+
+        /*
+         * This is the hard case. We are going to compute large positive
+         * integers B and S and integer decExp, s.t.
+         *      d = (B / S) * 10^decExp
+         *      1 <= B / S < 10
+         * Obvious choices are:
+         *      decExp = floor(log10(d))
+         *      B      = d * 2^nTinyBits * 10^max(0, -decExp)
+         *      S      = 10^max(0, decExp) * 2^nTinyBits
+         * (noting that nTinyBits has already been forced to non-negative)
+         * I am also going to compute a large positive integer
+         *      M      = (1/2^nSignificantBits) * 2^nTinyBits * 10^max(0, -decExp)
+         * i.e. M is (1/2) of the ULP of d, scaled like B.
+         * When we iterate through dividing B/S and picking off the
+         * quotient bits, we will know when to stop when the remainder
+         * is <= M.
+         *
+         * We keep track of powers of 2 and powers of 5.
+         */
+
+        /*
+         * Estimate decimal exponent. (If it is small-ish,
+         * we could double-check.)
+         *
+         * First, scale the mantissa bits such that 1 <= d2 < 2.
+         * We are then going to estimate
+         *          log10(d2) ~=~  (d2-1.5)/1.5 + log(1.5)
+         * and so we can estimate
+         *      log10(d) ~=~ log10(d2) + binExp * log10(2)
+         * take the floor and call it decExp.
+         */
+        final double d2 = Double.longBitsToDouble(expOne | (bits & ~fractHOB));
+        decExponent = (int)Math.floor((d2 - 1.5D) * 0.289529654D + 0.176091259D + exponent * 0.301029995663981D);
+
+        // Powers of 2 and powers of 5, respectively, in B.
+        final int B5 = Math.max(0, -decExponent);
+        int B2 = B5 + nTinyBits + exponent;
+
+        // Powers of 2 and powers of 5, respectively, in S.
+        final int S5 = Math.max(0, decExponent);
+        int S2 = S5 + nTinyBits;
+
+        // Powers of 2 and powers of 5, respectively, in M.
+        final int M5 = B5;
+        int M2 = B2 - nSignificantBits;
+
+        /*
+         * The long integer fractBits contains the (nFractBits) interesting
+         * bits from the mantissa of d (hidden 1 added if necessary) followed
+         * by (expShift + 1 - nFractBits) zeros. In the interest of compactness,
+         * I will shift out those zeros before turning fractBits into a
+         * BigInteger. The resulting whole number will be
+         *      d * 2^(nFractBits - 1 - binExp).
+         */
+
+        bits >>>= expShift + 1 - nFractBits;
+        B2 -= nFractBits - 1;
+        final int common2factor = Math.min(B2, S2);
+        B2 -= common2factor;
+        S2 -= common2factor;
+        M2 -= common2factor;
+
+        /*
+         * HACK!!For exact powers of two, the next smallest number
+         * is only half as far away as we think (because the meaning of
+         * ULP changes at power-of-two bounds) for this reason, we
+         * hack M2. Hope this works.
+         */
+        if (nFractBits == 1) {
+            M2 -= 1;
+        }
+
+        if (M2 < 0) {
+            // Oops.  Since we cannot scale M down far enough,
+            // we must scale the other values up.
+            B2 -= M2;
+            S2 -= M2;
+            M2 =  0;
+        }
+
+        /*
+         * Construct, Scale, iterate.
+         * Some day, we'll write a stopping test that takes
+         * account of the asymmetry of the spacing of floating-point
+         * numbers below perfect powers of 2
+         * 26 Sept 96 is not that day.
+         * So we use a symmetric test.
+         */
+
+        final char digits0[] = this.digits = new char[32];
+        int  ndigit;
+        boolean low, high;
+        long lowDigitDifference;
+        int  q;
+
+        /*
+         * Detect the special cases where all the numbers we are about
+         * to compute will fit in int or long integers.
+         * In these cases, we will avoid doing BigInteger arithmetic.
+         * We use the same algorithms, except that we "normalize"
+         * our FDBigInts before iterating. This is to make division easier,
+         * as it makes our fist guess (quotient of high-order words)
+         * more accurate!
+         */
+
+        // Binary digits needed to represent B, approx.
+        final int Bbits = nFractBits + B2 + ((B5 < nBitsPowerOf5.length) ? nBitsPowerOf5[B5] : (B5*3));
+        // Binary digits needed to represent 10*S, approx.
+        final int tenSbits = S2 + 1 + (((S5 + 1) < nBitsPowerOf5.length) ? nBitsPowerOf5[(S5 + 1)] : ((S5 + 1) * 3));
+
+        if (Bbits < 64 && tenSbits < 64) {
+            long b = (bits * powersOf5[B5]) << B2;
+            final long s = powersOf5[S5] << S2;
+            long m = powersOf5[M5] << M2;
+            final long tens = s * 10L;
+
+            /*
+             * Unroll the first iteration. If our decExp estimate
+             * was too high, our first quotient will be zero. In this
+             * case, we discard it and decrement decExp.
+             */
+
+            ndigit = 0;
+            q = (int)(b / s);
+            b = 10L * (b % s);
+            m *= 10L;
+            low  = b <  m;
+            high = (b + m) > tens;
+
+            if (q == 0 && !high) {
+                // Ignore leading zero.
+                decExponent--;
+            } else {
+                digits0[ndigit++] = (char)('0' + q);
+            }
+
+            if (decExponent < -3 || decExponent >= 8) {
+                high = low = false;
+            }
+
+            while (!low && !high) {
+                q = (int)(b / s);
+                b = 10 * (b % s);
+                m *= 10;
+
+                if (m > 0L) {
+                    low  = b < m;
+                    high = (b + m) > tens;
+                } else {
+                    low = true;
+                    high = true;
+                }
+
+                if (low && q == 0) {
+                    break;
+                }
+                digits0[ndigit++] = (char)('0' + q);
+            }
+
+            lowDigitDifference = (b << 1) - tens;
+        } else {
+            /*
+             * We must do BigInteger arithmetic.
+             * First, construct our BigInteger initial values.
+             */
+
+            BigInteger Bval = multiplyPowerOf5And2(BigInteger.valueOf(bits), B5, B2);
+            BigInteger Sval = constructPowerOf5And2(S5, S2);
+            BigInteger Mval = constructPowerOf5And2(M5, M2);
+
+
+            // Normalize so that BigInteger division works better.
+            final int shiftBias = Long.numberOfLeadingZeros(bits) - 4;
+            Bval = Bval.shiftLeft(shiftBias);
+            Mval = Mval.shiftLeft(shiftBias);
+            Sval = Sval.shiftLeft(shiftBias);
+            final BigInteger tenSval = Sval.multiply(BigInteger.TEN);
+
+            /*
+             * Unroll the first iteration. If our decExp estimate
+             * was too high, our first quotient will be zero. In this
+             * case, we discard it and decrement decExp.
+             */
+
+            ndigit = 0;
+
+            BigInteger[] quoRem = Bval.divideAndRemainder(Sval);
+            q    = quoRem[0].intValue();
+            Bval = quoRem[1].multiply(BigInteger.TEN);
+            Mval = Mval.multiply(BigInteger.TEN);
+            low  = (Bval.compareTo(Mval) < 0);
+            high = (Bval.add(Mval).compareTo(tenSval) > 0);
+
+            if (q == 0 && !high) {
+                // Ignore leading zero.
+                decExponent--;
+            } else {
+                digits0[ndigit++] = (char)('0' + q);
+            }
+
+            if (decExponent < -3 || decExponent >= 8) {
+                high = low = false;
+            }
+
+            while(!low && !high) {
+                quoRem = Bval.divideAndRemainder(Sval);
+                q = quoRem[0].intValue();
+                Bval = quoRem[1].multiply(BigInteger.TEN);
+                Mval = Mval.multiply(BigInteger.TEN);
+                low  = (Bval.compareTo(Mval) < 0);
+                high = (Bval.add(Mval).compareTo(tenSval) > 0);
+
+                if (low && q == 0) {
+                    break;
+                }
+                digits0[ndigit++] = (char)('0' + q);
+            }
+
+            if (high && low) {
+                Bval = Bval.shiftLeft(1);
+                lowDigitDifference = Bval.compareTo(tenSval);
+            } else {
+                lowDigitDifference = 0L;
+            }
+        }
+
+        this.decimalExponent = decExponent + 1;
+        this.digits          = digits0;
+        this.nDigits         = ndigit;
+
+        /*
+         * Last digit gets rounded based on stopping condition.
+         */
+
+        if (high) {
+            if (low) {
+                if (lowDigitDifference == 0L) {
+                    // it's a tie!
+                    // choose based on which digits we like.
+                    if ((digits0[nDigits - 1] & 1) != 0) {
+                        roundup();
+                    }
+                } else if (lowDigitDifference > 0) {
+                    roundup();
+                }
+            } else {
+                roundup();
+            }
+        }
+    }
+
+    /**
+     * Count number of significant bits.
+     * @param bits Double's fraction.
+     * @return Number of significant bits.
+     */
+    private static int countSignificantBits(final long bits) {
+        if (bits != 0) {
+            return 64 - Long.numberOfLeadingZeros(bits) - Long.numberOfTrailingZeros(bits);
+        }
+
+        return 0;
+    }
+
+    /*
+     * Cache big powers of 5 handy for future reference.
+     */
+    private static BigInteger powerOf5Cache[];
+
+    /**
+     * Determine the largest power of 5 needed (as BigInteger.)
+     * @param power Power of 5.
+     * @return BigInteger of power of 5.
+     */
+    private static BigInteger bigPowerOf5(final int power) {
+        if (powerOf5Cache == null) {
+            powerOf5Cache = new BigInteger[power + 1];
+        } else if (powerOf5Cache.length <= power) {
+            final BigInteger t[] = new BigInteger[ power+1 ];
+            System.arraycopy(powerOf5Cache, 0, t, 0, powerOf5Cache.length);
+            powerOf5Cache = t;
+        }
+
+        if (powerOf5Cache[power] != null) {
+            return powerOf5Cache[power];
+        } else if (power < powersOf5.length) {
+            return powerOf5Cache[power] = BigInteger.valueOf(powersOf5[power]);
+        } else {
+            // Construct the value recursively.
+            // in order to compute 5^p,
+            // compute its square root, 5^(p/2) and square.
+            // or, let q = p / 2, r = p -q, then
+            // 5^p = 5^(q+r) = 5^q * 5^r
+            final int q = power >> 1;
+            final int r = power - q;
+            BigInteger bigQ = powerOf5Cache[q];
+
+            if (bigQ == null) {
+                bigQ = bigPowerOf5(q);
+            }
+
+            if (r < powersOf5.length) {
+                return (powerOf5Cache[power] = bigQ.multiply(BigInteger.valueOf(powersOf5[r])));
+            }
+            BigInteger bigR = powerOf5Cache[ r ];
+
+            if (bigR == null) {
+                bigR = bigPowerOf5(r);
+            }
+
+            return (powerOf5Cache[power] = bigQ.multiply(bigR));
+        }
+    }
+
+    /**
+     * Multiply BigInteger by powers of 5 and 2 (i.e., 10)
+     * @param value Value to multiply.
+     * @param p5    Power of 5.
+     * @param p2    Power of 2.
+     * @return Result.
+     */
+    private static BigInteger multiplyPowerOf5And2(final BigInteger value, final int p5, final int p2) {
+        BigInteger returnValue = value;
+
+        if (p5 != 0) {
+            returnValue = returnValue.multiply(bigPowerOf5(p5));
+        }
+
+        if (p2 != 0) {
+            returnValue = returnValue.shiftLeft(p2);
+        }
+
+        return returnValue;
+    }
+
+    /**
+     * Construct a BigInteger power of 5 and 2 (i.e., 10)
+     * @param p5    Power of 5.
+     * @param p2    Power of 2.
+     * @return Result.
+     */
+    private static BigInteger constructPowerOf5And2(final int p5, final int p2) {
+        BigInteger v = bigPowerOf5(p5);
+
+        if (p2 != 0) {
+            v = v.shiftLeft(p2);
+        }
+
+        return v;
+    }
+
+    /**
+     * Round up last digit by adding one to the least significant digit.
+     * In the unlikely event there is a carry out, deal with it.
+     * assert that this will only happen where there
+     * is only one digit, e.g. (float)1e-44 seems to do it.
+     */
+    private void roundup() {
+        int i;
+        int q = digits[ i = (nDigits-1)];
+
+        while (q == '9' && i > 0) {
+            if (decimalExponent < 0) {
+                nDigits--;
+            } else {
+                digits[i] = '0';
+            }
+
+            q = digits[--i];
+        }
+
+        if (q == '9') {
+            // Carryout! High-order 1, rest 0s, larger exp.
+            decimalExponent += 1;
+            digits[0] = '1';
+
+            return;
+        }
+
+        digits[i] = (char)(q + 1);
+    }
+
+    /**
+     * Format final number string.
+     * @return Formatted string.
+     */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder(32);
+
+        if (isNegative) {
+            sb.append('-');
+        }
+
+        if (isNaN) {
+            sb.append(digits, 0, nDigits);
+        } else {
+            if (decimalExponent > 0 && decimalExponent <= 21) {
+                final int charLength = Math.min(nDigits, decimalExponent);
+                sb.append(digits, 0, charLength);
+
+                if (charLength < decimalExponent) {
+                    sb.append(zeroes, 0, decimalExponent - charLength);
+                } else if (charLength < nDigits) {
+                    sb.append('.');
+                    sb.append(digits, charLength, nDigits - charLength);
+                }
+            } else if (decimalExponent <=0 && decimalExponent > -6) {
+                sb.append('0');
+                sb.append('.');
+
+                if (decimalExponent != 0) {
+                    sb.append(zeroes, 0, -decimalExponent);
+                }
+
+                sb.append(digits, 0, nDigits);
+            } else {
+                sb.append(digits[0]);
+
+                if (nDigits > 1) {
+                    sb.append('.');
+                    sb.append(digits, 1, nDigits - 1);
+                }
+
+                sb.append('e');
+                final int exponent;
+                int e;
+
+                if (decimalExponent <= 0) {
+                    sb.append('-');
+                    exponent = e = -decimalExponent + 1;
+                } else {
+                    sb.append('+');
+                    exponent = e = decimalExponent - 1;
+                }
+
+                if (exponent > 99) {
+                    sb.append((char)(e / 100 + '0'));
+                    e %= 100;
+                }
+
+                if (exponent > 9) {
+                    sb.append((char)(e / 10 + '0'));
+                    e %= 10;
+                }
+
+                sb.append((char)(e + '0'));
+            }
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ParserException.java b/nashorn/src/jdk/nashorn/internal/runtime/ParserException.java
new file mode 100644
index 0000000..2424bc3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ParserException.java
@@ -0,0 +1,117 @@
+/*
+ * 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;
+
+import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.parser.Token;
+
+/**
+ * ECMAScript parser exceptions.
+ */
+@SuppressWarnings("serial")
+public final class ParserException extends NashornException {
+    // Source from which this ParserException originated
+    private final Source source;
+    // token responsible for this exception
+    private final long token;
+    // if this is traslated as ECMA error, which type should be used?
+    private final JSErrorType errorType;
+
+    /**
+     * Constructor
+     *
+     * @param msg exception message for this parser error.
+     */
+    public ParserException(final String msg) {
+        this(JSErrorType.SYNTAX_ERROR, msg, null, -1, -1, -1);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param errorType error type
+     * @param msg       exception message
+     * @param source    source from which this exception originates
+     * @param line      line number of exception
+     * @param column    column number of exception
+     * @param token     token from which this exception originates
+     *
+     */
+    public ParserException(final JSErrorType errorType, final String msg, final Source source, final int line, final int column, final long token) {
+        super(msg, source != null ? source.getName() : null, line, column);
+        this.source = source;
+        this.token = token;
+        this.errorType = errorType;
+    }
+
+    /**
+     * Get the {@code Source} of this {@code ParserException}
+     * @return source
+     */
+    public Source getSource() {
+        return source;
+    }
+
+    /**
+     * Get the token responsible for this {@code ParserException}
+     * @return token
+     */
+    public long getToken() {
+        return token;
+    }
+
+    /**
+     * Get token position within source where the error originated.
+     * @return token position if available, else -1
+     */
+    public int getPosition() {
+        return Token.descPosition(token);
+    }
+
+    /**
+     * Get the {@code JSErrorType} of this {@code ParserException}
+     * @return error type
+     */
+    public JSErrorType getErrorType() {
+        return errorType;
+    }
+
+    /**
+     * Throw this {@code ParserException} as one of the 7 native JavaScript errors
+     */
+    public void throwAsEcmaException() {
+        throw ECMAErrors.asEcmaException(this);
+    }
+
+    /**
+     * Throw this {@code ParserException} as one of the 7 native JavaScript errors
+     * @param global global scope object
+     */
+    public void throwAsEcmaException(final ScriptObject global) {
+        throw ECMAErrors.asEcmaException(global, this);
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Property.java b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
new file mode 100644
index 0000000..dfb8bf5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
@@ -0,0 +1,500 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
+
+import java.lang.invoke.MethodHandle;
+import java.util.Objects;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.types.Type;
+
+/**
+ * This is the abstract superclass representing a JavaScript Property.
+ * The {@link PropertyMap} map links keys to properties, and consequently
+ * instances of this class make up the values in the PropertyMap
+ *
+ * @see PropertyMap
+ * @see AccessorProperty
+ * @see SpillProperty
+ * @see UserAccessorProperty
+ */
+public abstract class Property {
+    /*
+     * ECMA 8.6.1 Property Attributes
+     *
+     * We use negative flags because most properties are expected to
+     * be 'writable', 'configurable' and 'enumerable'. With negative flags,
+     * we can use leave flag byte initialized with (the default) zero value.
+     */
+
+    /** ECMA 8.6.1 - Is this property not writable? */
+    public static final int NOT_WRITABLE     = 0b0000_0000_0001;
+
+    /** ECMA 8.6.1 - Is this property not enumerable? */
+    public static final int NOT_ENUMERABLE   = 0b0000_0000_0010;
+
+    /** ECMA 8.6.1 - Is this property not configurable? */
+    public static final int NOT_CONFIGURABLE = 0b0000_0000_0100;
+
+    private static final int MODIFY_MASK     = 0b0000_0000_1111;
+
+    /** Is this a spill property? See {@link SpillProperty} */
+    public static final int IS_SPILL         = 0b0000_0001_0000;
+
+    /** Is this a function parameter? */
+    public static final int IS_PARAMETER     = 0b0000_0010_0000;
+
+    /** Is parameter accessed thru arguments? */
+    public static final int HAS_ARGUMENTS    = 0b0000_0100_0000;
+
+    /** Is this property always represented as an Object? See {@link ObjectClassGenerator} and dual fields flag. */
+    public static final int IS_ALWAYS_OBJECT = 0b0000_1000_0000;
+
+    /** Can this property be primitive? */
+    public static final int CAN_BE_PRIMITIVE = 0b0001_0000_0000;
+
+    /** Can this property be undefined? */
+    public static final int CAN_BE_UNDEFINED = 0b0010_0000_0000;
+
+    /** Property key. */
+    private final String key;
+
+    /** Property flags. */
+    protected int flags;
+
+    /** Property field number or spill slot */
+    private final int slot;
+
+    /**
+     * Constructor
+     *
+     * @param key   property key
+     * @param flags property flags
+     * @param slot  property field number or spill slot
+     */
+    public Property(final String key, final int flags, final int slot) {
+        assert key != null;
+        this.key   = key;
+        this.flags = flags;
+        this.slot  = slot;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param property source property
+     */
+    protected Property(final Property property) {
+        this.key   = property.key;
+        this.flags = property.flags;
+        this.slot  = property.slot;
+    }
+
+    /**
+     * Copy function
+     *
+     * @return cloned property
+     */
+    protected abstract Property copy();
+
+    /**
+     * Property flag utility method for {@link PropertyDescriptor}s. Given two property descriptors,
+     * return the result of merging their flags.
+     *
+     * @param oldDesc  first property descriptor
+     * @param newDesc  second property descriptor
+     * @return merged flags.
+     */
+    static int mergeFlags(final PropertyDescriptor oldDesc, final PropertyDescriptor newDesc) {
+        int     propFlags = 0;
+        boolean value;
+
+        value = newDesc.has(CONFIGURABLE) ? newDesc.isConfigurable() : oldDesc.isConfigurable();
+        if (!value) {
+            propFlags |= NOT_CONFIGURABLE;
+        }
+
+        value = newDesc.has(ENUMERABLE) ? newDesc.isEnumerable() : oldDesc.isEnumerable();
+        if (!value) {
+            propFlags |= NOT_ENUMERABLE;
+        }
+
+        value = newDesc.has(WRITABLE) ? newDesc.isWritable() : oldDesc.isWritable();
+        if (!value) {
+            propFlags |= NOT_WRITABLE;
+        }
+
+        return propFlags;
+    }
+
+    /**
+     * Property flag utility method for {@link PropertyDescriptor}. Get the property flags
+     * conforming to any Property using this PropertyDescriptor
+     *
+     * @param desc property descriptor
+     * @return flags for properties that conform to property descriptor
+     */
+    static int toFlags(final PropertyDescriptor desc) {
+        int propFlags = 0;
+
+        if (!desc.isConfigurable()) {
+            propFlags |= NOT_CONFIGURABLE;
+        }
+        if (!desc.isEnumerable()) {
+            propFlags |= NOT_ENUMERABLE;
+        }
+        if (!desc.isWritable()) {
+            propFlags |= NOT_WRITABLE;
+        }
+
+        return propFlags;
+    }
+
+    /**
+     * Check whether this property has a user defined getter function. See {@link UserAccessorProperty}
+     * @return true if getter function exists, false is default
+     */
+    public boolean hasGetterFunction() {
+        return false;
+    }
+
+    /**
+     * Check whether this property has a user defined setter function. See {@link UserAccessorProperty}
+     * @return true if getter function exists, false is default
+     */
+    public boolean hasSetterFunction() {
+        return false;
+    }
+
+    /**
+     * Check whether this property is writable (see ECMA 8.6.1)
+     * @return true if writable
+     */
+    public boolean isWritable() {
+        return (flags & NOT_WRITABLE) == 0;
+    }
+
+    /**
+     * Check whether this property is writable (see ECMA 8.6.1)
+     * @return true if configurable
+     */
+    public boolean isConfigurable() {
+        return (flags & NOT_CONFIGURABLE) == 0;
+    }
+
+    /**
+     * Check whether this property is enumerable (see ECMA 8.6.1)
+     * @return true if enumerable
+     */
+    public boolean isEnumerable() {
+        return (flags & NOT_ENUMERABLE) == 0;
+    }
+
+    /**
+     * Check whether this property is used as a function parameter
+     * @return true if parameter
+     */
+    public boolean isParameter() {
+        return (flags & IS_PARAMETER) == IS_PARAMETER;
+    }
+
+    /**
+     * Check whether this property is in an object with arguments field
+     * @return true if has arguments
+     */
+    public boolean hasArguments() {
+        return (flags & HAS_ARGUMENTS) == HAS_ARGUMENTS;
+    }
+
+    /**
+     * Check whether this is a spill property, i.e. one that will not
+     * be stored in a specially generated field in the property class.
+     * The spill pool is maintained separately, as a growing Object array
+     * in the {@link ScriptObject}.
+     *
+     * @return true if spill property
+     */
+    public boolean isSpill() {
+        return (flags & IS_SPILL) == IS_SPILL;
+    }
+
+    /**
+     * Does this property use any slots in the spill array described in
+     * {@link Property#isSpill}? In that case how many. Currently a property
+     * only uses max one spill slot, but this may change in future representations
+     * Only {@link SpillProperty} instances use spill slots
+     *
+     * @return number of spill slots a property is using
+     */
+    public int getSpillCount() {
+        return isSpill() ? 1 : 0;
+    }
+
+    /**
+     * Add more property flags to the property. Properties are immutable here,
+     * so any property change that results in a larger flag set results in the
+     * property being cloned. Use only the return value
+     *
+     * @param propertyFlags flags to be OR:ed to the existing property flags
+     * @return new property if property set was changed, {@code this} otherwise
+     */
+    public Property addFlags(final int propertyFlags) {
+        if ((this.flags & propertyFlags) != propertyFlags) {
+            final Property cloned = this.copy();
+            cloned.flags |= propertyFlags;
+            return cloned;
+        }
+        return this;
+    }
+
+    /**
+     * Get the flags for this property
+     * @return property flags
+     */
+    public int getFlags() {
+        return flags;
+    }
+
+    /**
+     * Get the modify flags for this property. The modify flags are the ECMA 8.6.1
+     * flags that decide if the Property is writable, configurable and/or enumerable.
+     *
+     * @return modify flags for property
+     */
+    public int getModifyFlags() {
+        return flags & MODIFY_MASK;
+    }
+
+    /**
+     * Remove property flags from the property. Properties are immutable here,
+     * so any property change that results in a smaller flag set results in the
+     * property being cloned. Use only the return value
+     *
+     * @param propertyFlags flags to be subtracted from the existing property flags
+     * @return new property if property set was changed, {@code this} otherwise
+     */
+    public Property removeFlags(final int propertyFlags) {
+        if ((this.flags & propertyFlags) != 0) {
+            final Property cloned = this.copy();
+            cloned.flags &= ~propertyFlags;
+            return cloned;
+        }
+        return this;
+    }
+
+    /**
+     * Reset the property for this property. Properties are immutable here,
+     * so any property change that results in a different flag sets results in the
+     * property being cloned. Use only the return value
+     *
+     * @param propertyFlags flags that are replacing from the existing property flags
+     * @return new property if property set was changed, {@code this} otherwise
+     */
+    public Property setFlags(final int propertyFlags) {
+        if (this.flags != propertyFlags) {
+            final Property cloned = this.copy();
+            cloned.flags &= ~MODIFY_MASK;
+            cloned.flags |= propertyFlags & MODIFY_MASK;
+            return cloned;
+        }
+        return this;
+    }
+
+    /**
+     * Abstract method for retrieving the getter for the property. We do not know
+     * anything about the internal representation when we request the getter, we only
+     * know that the getter will return the property as the given type.
+     *
+     * @param type getter return value type
+     * @return a getter for this property as {@code type}
+     */
+    public abstract MethodHandle getGetter(final Class<?> type);
+
+    /**
+     * Get the key for this property. This key is an ordinary string. The "name".
+     * @return key for property
+     */
+    public String getKey() {
+        return key;
+    }
+
+    /**
+     * Abstract method for retrieving the setter for the property. We do not know
+     * anything about the internal representation when we request the setter, we only
+     * know that the setter will take the property as a parameter of the given type.
+     * <p>
+     * Note that we have to pass the current property map from which we retrieved
+     * the property here. This is necessary for map guards if, e.g. the internal
+     * representation of the field, and consequently also the setter, changes. Then
+     * we automatically get a map guard that relinks the call site so that the
+     * older setter will never be used again.
+     * <p>
+     * see {@link ObjectClassGenerator#createSetter(Class, Class, MethodHandle, MethodHandle)}
+     * if you are interested in the internal details of this. Note that if you
+     * are running in default mode, with {@code -Dnashorn.fields.dual=true}, disabled, the setters
+     * will currently never change, as all properties are represented as Object field,
+     * the Object fields are Initialized to {@code ScriptRuntime.UNDEFINED} and primitives are
+     * boxed/unboxed upon every access, which is not necessarily optimal
+     *
+     * @param type setter parameter type
+     * @param currentMap current property map for property
+     * @return a getter for this property as {@code type}
+     */
+    public abstract MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap);
+
+    /**
+     * Get the user defined getter function if one exists. Only {@link UserAccessorProperty} instances
+     * can have user defined getters
+     * @param obj the script object
+     * @return user defined getter function, or {@code null} if none exists
+     */
+    public ScriptFunction getGetterFunction(final ScriptObject obj) {
+        return null;
+    }
+
+    /**
+     * Get the user defined setter function if one exists. Only {@link UserAccessorProperty} instances
+     * can have user defined getters
+     * @param obj the script object
+     * @return user defined getter function, or {@code null} if none exists
+     */
+    public ScriptFunction getSetterFunction(final ScriptObject obj) {
+        return null;
+    }
+
+    /**
+     * Get the field number or spill slot
+     * @return number/slot, -1 if none exists
+     */
+    public int getSlot() {
+        return slot;
+    }
+
+    @Override
+    public int hashCode() {
+        final Class<?> type = getCurrentType();
+        return Objects.hashCode(this.key) ^ flags ^ getSlot() ^ (type == null ? 0 : type.hashCode());
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (this == other) {
+            return true;
+        }
+
+        if (other == null || this.getClass() != other.getClass()) {
+            return false;
+        }
+
+        final Property otherProperty = (Property)other;
+
+        return getFlags()       == otherProperty.getFlags() &&
+               getSlot()        == otherProperty.getSlot() &&
+               getCurrentType() == otherProperty.getCurrentType() &&
+               getKey().equals(otherProperty.getKey());
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb   = new StringBuilder();
+        final Class<?>      type = getCurrentType();
+
+        sb.append(getKey()).
+            append("(0x").
+            append(Integer.toHexString(flags)).
+            append(") ").
+            append(getClass().getSimpleName()).
+            append(" {").
+            append(type == null ? "UNDEFINED" : Type.typeFor(type).getDescriptor()).
+            append('}');
+
+        if (slot != -1) {
+            sb.append('[');
+            sb.append(slot);
+            sb.append(']');
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Get the current type of this field. If you are not running with dual fields enabled,
+     * this will always be Object.class. See the value representation explanation in
+     * {@link Property#getSetter(Class, PropertyMap)} and {@link ObjectClassGenerator}
+     * for more information.
+     *
+     * @return current type of property, null means undefined
+     */
+    public Class<?> getCurrentType() {
+        return Object.class;
+    }
+
+    /**
+     * Check whether this Property can ever change its type. The default is false, and if
+     * you are not running with dual fields, the type is always object and can never change
+     * @return true if this property can change types
+     */
+    public boolean canChangeType() {
+        return false;
+    }
+
+    /**
+     * Check whether this Property is ever used as anything but an Object. If this is used only
+     * as an object, dual fields mode need not even try to represent it as a primitive at any
+     * callsite, saving map rewrites for performance.
+     *
+     * @return true if representation should always be an object field
+     */
+    public boolean isAlwaysObject() {
+        return (flags & IS_ALWAYS_OBJECT) == IS_ALWAYS_OBJECT;
+    }
+
+    /**
+     * Check whether this property can be primitive. This is a conservative
+     * analysis result, so {@code false} might mean that it can still be
+     * primitive
+     *
+     * @return can be primitive status
+     */
+    public boolean canBePrimitive() {
+        return (flags & CAN_BE_PRIMITIVE) == CAN_BE_PRIMITIVE;
+    }
+
+    /**
+     * Check whether this property can be primitive. This is a conservative
+     * analysis result, so {@code true} might mean that it can still be
+     * defined, but it will never say that a property can not be undefined
+     * if it can
+     *
+     * @return can be undefined status
+     */
+    public boolean canBeUndefined() {
+        return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyAccess.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyAccess.java
new file mode 100644
index 0000000..165344c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyAccess.java
@@ -0,0 +1,365 @@
+/*
+ * 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;
+
+/**
+ * Interface for getting and setting properties from script objects
+ * This can be a plugin point for e.g. tagged values or alternative
+ * array property getters.
+ *
+ * The interface is engineered with the combinatorially exhaustive
+ * combination of types by purpose, for speed, as currently HotSpot is not
+ * good enough at removing boxing.
+ */
+public interface PropertyAccess {
+    /**
+     * Get the value for a given key and return it as an int
+     * @param key the key
+     * @return the value
+     */
+    public int getInt(Object key);
+
+    /**
+     * Get the value for a given key and return it as an int
+     * @param key the key
+     * @return the value
+     */
+    public int getInt(double key);
+
+    /**
+     * Get the value for a given key and return it as an int
+     * @param key the key
+     * @return the value
+     */
+    public int getInt(final long key);
+
+    /**
+     * Get the value for a given key and return it as an int
+     * @param key the key
+     * @return the value
+     */
+    public int getInt(int key);
+
+    /**
+     * Get the value for a given key and return it as a long
+     * @param key the key
+     * @return the value
+     */
+    public long getLong(Object key);
+
+    /**
+     * Get the value for a given key and return it as a long
+     * @param key the key
+     * @return the value
+     */
+    public long getLong(double key);
+
+    /**
+     * Get the value for a given key and return it as a long
+     * @param key the key
+     * @return the value
+     */
+    public long getLong(long key);
+
+    /**
+     * Get the value for a given key and return it as a long
+     * @param key the key
+     * @return the value
+     */
+    public long getLong(int key);
+
+    /**
+     * Get the value for a given key and return it as a double
+     * @param key the key
+     * @return the value
+     */
+    public double getDouble(Object key);
+
+    /**
+     * Get the value for a given key and return it as a double
+     * @param key the key
+     * @return the value
+     */
+    public double getDouble(double key);
+
+    /**
+     * Get the value for a given key and return it as a double
+     * @param key the key
+     * @return the value
+     */
+    public double getDouble(long key);
+
+    /**
+     * Get the value for a given key and return it as a double
+     * @param key the key
+     * @return the value
+     */
+    public double getDouble(int key);
+
+    /**
+     * Get the value for a given key and return it as an Object
+     * @param key the key
+     * @return the value
+     */
+    public Object get(Object key);
+
+    /**
+     * Get the value for a given key and return it as an Object
+     * @param key the key
+     * @return the value
+     */
+    public Object get(double key);
+
+    /**
+     * Get the value for a given key and return it as an Object
+     * @param key the key
+     * @return the value
+     */
+    public Object get(long key);
+
+    /**
+     * Get the value for a given key and return it as an Object
+     * @param key the key
+     * @return the value
+     */
+    public Object get(int key);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(Object key, int value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(Object key, long value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(Object key, double value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(Object key, Object value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(double key, int value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(double key, long value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(double key, double value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(double key, Object value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(long key, int value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(long key, long value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(long key, double value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(long key, Object value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(int key, int value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(int key, long value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(int key, double value, boolean strict);
+
+    /**
+     * Set the value of a given key
+     * @param key     the key
+     * @param value   the value
+     * @param strict  are we in strict mode
+     */
+    public void set(int key, Object value, boolean strict);
+
+    /**
+     * Check if the given key exists anywhere in the proto chain
+     * @param key the key
+     * @return true if key exists
+     */
+    public boolean has(Object key);
+
+    /**
+     * Check if the given key exists anywhere in the proto chain
+     * @param key the key
+     * @return true if key exists
+     */
+    public boolean has(int key);
+
+    /**
+     * Check if the given key exists anywhere in the proto chain
+     * @param key the key
+     * @return true if key exists
+     */
+    public boolean has(long key);
+
+    /**
+     * Check if the given key exists anywhere in the proto chain
+     * @param key the key
+     * @return true if key exists
+     */
+    public boolean has(double key);
+
+    /**
+     * Check if the given key exists directly in the implementor
+     * @param key the key
+     * @return true if key exists
+     */
+    public boolean hasOwnProperty(Object key);
+
+    /**
+     * Check if the given key exists directly in the implementor
+     * @param key the key
+     * @return true if key exists
+     */
+    public boolean hasOwnProperty(int key);
+
+    /**
+     * Check if the given key exists directly in the implementor
+     * @param key the key
+     * @return true if key exists
+     */
+    public boolean hasOwnProperty(long key);
+
+    /**
+     * Check if the given key exists directly in the implementor
+     * @param key the key
+     * @return true if key exists
+     */
+    public boolean hasOwnProperty(double key);
+
+    /**
+     * Delete a property with the given key from the implementor
+     * @param key    the key
+     * @param strict are we in strict mode
+     * @return true if deletion succeeded, false otherwise
+     */
+    public boolean delete(int key, boolean strict);
+
+    /**
+     * Delete a property with the given key from the implementor
+     * @param key    the key
+     * @param strict are we in strict mode
+     * @return true if deletion succeeded, false otherwise
+     */
+    public boolean delete(long key, boolean strict);
+
+    /**
+     * Delete a property with the given key from the implementor
+     * @param key    the key
+     * @param strict are we in strict mode
+     * @return true if deletion succeeded, false otherwise
+     */
+    public boolean delete(double key, boolean strict);
+
+    /**
+     * Delete a property with the given key from the implementor
+     * @param key    the key
+     * @param strict are we in strict mode
+     * @return true if deletion succeeded, false otherwise
+     */
+    public boolean delete(Object key, boolean strict);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyDescriptor.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyDescriptor.java
new file mode 100644
index 0000000..49a7a9d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyDescriptor.java
@@ -0,0 +1,155 @@
+/*
+ * 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;
+
+/**
+ * Describes attributes of a specific property of a script object.
+ */
+public interface PropertyDescriptor {
+
+    /** Type: generic property descriptor - TODO this should be an enum */
+    public static final int GENERIC  = 0;
+
+    /** Type: data property descriptor - TODO this should be an enum */
+    public static final int DATA     = 1;
+
+    /** Type: accessor property descriptor - TODO this should be an enum */
+    public static final int ACCESSOR = 2;
+
+    /** descriptor for configurable property */
+    public static final String CONFIGURABLE = "configurable";
+
+    /** descriptor for enumerable property */
+    public static final String ENUMERABLE = "enumerable";
+
+    /** descriptor for writable property */
+    public static final String WRITABLE = "writable";
+
+    /** descriptor for value */
+    public static final String VALUE = "value";
+
+    /** descriptor for getter */
+    public static final String GET = "get";
+
+    /** descriptor for setter */
+    public static final String SET = "set";
+
+    /**
+     * Check if this {@code PropertyDescriptor} describes a configurable property
+     * @return true if configurable
+     */
+    public boolean isConfigurable();
+
+    /**
+     * Check if this {@code PropertyDescriptor} describes an enumerable property
+     * @return true if enumerable
+     */
+    public boolean isEnumerable();
+
+    /**
+     * Check if this {@code PropertyDescriptor} describes a wriable property
+     * @return true if writable
+     */
+    public boolean isWritable();
+
+    /**
+     * Get the property value as given by this {@code PropertyDescriptor}
+     * @return property value
+     */
+    public Object getValue();
+
+    /**
+     * Get the {@link UserAccessorProperty} getter as given by this {@code PropertyDescriptor}
+     * @return getter, or null if not available
+     */
+    public ScriptFunction getGetter();
+
+    /**
+     * Get the {@link UserAccessorProperty} setter as given by this {@code PropertyDescriptor}
+     * @return setter, or null if not available
+     */
+    public ScriptFunction getSetter();
+
+    /**
+     * Set whether this {@code PropertyDescriptor} describes a configurable property
+     * @param flag true if configurable, false otherwise
+     */
+    public void setConfigurable(boolean flag);
+
+    /**
+     * Set whether this {@code PropertyDescriptor} describes an enumerable property
+     * @param flag true if enumerable, false otherwise
+     */
+    public void setEnumerable(boolean flag);
+
+    /**
+     * Set whether this {@code PropertyDescriptor} describes a writable property
+     * @param flag true if writable, false otherwise
+     */
+    public void setWritable(boolean flag);
+
+    /**
+     * Set the property value for this {@code PropertyDescriptor}
+     * @param value property value
+     */
+    public void setValue(Object value);
+
+    /**
+     * Assign a {@link UserAccessorProperty} getter as given to this {@code PropertyDescriptor}
+     * @param getter getter, or null if not available
+     */
+    public void setGetter(Object getter);
+
+    /**
+     * Assign a {@link UserAccessorProperty} setter as given to this {@code PropertyDescriptor}
+     * @param setter setter, or null if not available
+     */
+    public void setSetter(Object setter);
+
+    /**
+     * Fill in this {@code PropertyDescriptor} from the properties of a given {@link ScriptObject}
+     *
+     * @param obj the script object
+     * @return filled in {@code PropertyDescriptor}
+     *
+     */
+    public PropertyDescriptor fillFrom(ScriptObject obj);
+
+    /**
+     * Get the type of this property descriptor.
+     * @return property descriptor type, one of {@link PropertyDescriptor#GENERIC}, {@link PropertyDescriptor#DATA} and {@link PropertyDescriptor#ACCESSOR}
+     */
+    public int type();
+
+    /**
+     * Wrapper for {@link ScriptObject#has(Object)}
+     *
+     * @param key property key
+     * @return true if property exists in implementor
+     */
+    public boolean has(Object key);
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java
new file mode 100644
index 0000000..9759caa
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java
@@ -0,0 +1,649 @@
+/*
+ * 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;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Immutable hash map implementation for properties.  Properties are keyed on strings.
+ * Copying and cloning is avoided by relying on immutability.
+ * <p>
+ * When adding an element to a hash table, only the head of a bin list is updated, thus
+ * an add only requires the cloning of the bins array and adding an element to the head
+ * of the bin list.  Similarly for removal, only a portion of a bin list is updated.
+ * <p>
+ * A separate chronological list is kept for quick generation of keys and values, and,
+ * for rehashing.
+ * <p>
+ * Details:
+ * <p>
+ * The main goal is to be able to retrieve properties from a map quickly, keying on
+ * the property name (String.)  A secondary, but important goal, is to keep maps
+ * immutable, so that a map can be shared by multiple objects in a context.
+ * Sharing maps allows objects to be categorized as having similar properties, a
+ * fact that call site guards rely on.  In this discussion, immutability allows us
+ * to significantly reduce the amount of duplication we have in our maps.
+ * <p>
+ * The simplest of immutable maps is a basic singly linked list.  New properties
+ * are simply added to the head of the list.  Ancestor maps are not affected by the
+ * addition, since they continue to refer to their own head.  Searching is done by
+ * walking linearly though the elements until a match is found, O(N).
+ * <p>
+ * A hash map can be thought of as an optimization of a linked list map, where the
+ * linked list is broken into fragments based on hashCode(key) .  An array is use
+ * to quickly reference these fragments, indexing on hashCode(key) mod tableSize
+ * (tableSize is typically a power of 2 so that the mod is a fast masking
+ * operation.)  If the size of the table is sufficient large, then search time
+ * approaches O(1).  In fact, most bins in a hash table are typically empty or
+ * contain a one element list.
+ * <p>
+ * For immutable hash maps, we can think of the hash map as an array of the shorter
+ * linked list maps.  If we add an element to the head of one of those lists,  it
+ * doesn't affect any ancestor maps.  Thus adding an element to an immutable hash
+ * map only requires cloning the array and inserting an element at the head of one
+ * of the bins.
+ * <p>
+ * Using Java HashMaps we don't have enough control over the entries to allow us to
+ * implement this technique, so we are forced to clone the entire hash map.
+ * <p>
+ * Removing elements is done similarly.  We clone the array and then only modify
+ * the bin containing the removed element.  More often than not, the list contains
+ * only one element (or is very short), so this is not very costly.  When the list
+ * has several items, we need to clone the list portion prior to the removed item.
+ * <p>
+ * Another requirement of property maps is that we need to be able to gather all
+ * properties in chronological (add) order.  We have been using LinkedHashMap to
+ * provide this.  For the implementation of immutable hash map, we use a singly
+ * linked list that is linked in reverse chronological order.  This means we simply
+ * add new entries to the head of the list.  If we need to work with the list in
+ * forward order, it's simply a matter of allocating an array (size is known) and
+ * back filling in reverse order.  Removal of elements from the chronological list
+ * is trickier.  LinkedHashMap uses a doubly linked list to give constant time
+ * removal. Immutable hash maps can't do that and maintain immutability.  So we
+ * manage the chronological list the same way we manage the bins, cloning up to the
+ * point of removal.  Don't panic.  This cost is more than offset by the cost of
+ * cloning an entire LinkedHashMap.  Plus removal is far more rare than addition.
+ * <p>
+ * One more optimization.  Maps with a small number of entries don't use the hash
+ * map at all, the chronological list is used instead.
+ * <p>
+ * So the benefits from immutable arrays are; fewer objects and less copying.  For
+ * immutable hash map, when no removal is involved, the number of elements per
+ * property is two (bin + chronological elements).  For LinkedHashMap it is one
+ * (larger element) times the number of maps that refer to the property.  For
+ * immutable hash map, addition is constant time.  For LinkedHashMap it's O(N+C)
+ * since we have to clone the older map.
+ */
+public final class PropertyHashMap implements Map <String, Property> {
+    /** Number of initial bins. Power of 2. */
+    private static final int INITIAL_BINS = 16;
+
+    /** Threshold before using bins. */
+    private static final int LIST_THRESHOLD = 4;
+
+    /** Initial map. */
+    public static final PropertyHashMap EMPTY_MAP = new PropertyHashMap();
+
+    /** Number of properties in the map. */
+    private final int size;
+
+    /** Threshold before growing the bins. */
+    private final int threshold;
+
+    /** Reverse list of all properties. */
+    private final Element list;
+
+    /** Hash map bins. */
+    private final Element[] bins;
+
+    /** All properties as an array (lazy). */
+    private Property[] properties;
+
+    /**
+     * Empty map constructor.
+     */
+    private PropertyHashMap() {
+        this.size      = 0;
+        this.threshold = 0;
+        this.bins      = null;
+        this.list      = null;
+    }
+
+    /**
+     * Clone Constructor
+     *
+     * @param map Original {@link PropertyHashMap}.
+     */
+    private PropertyHashMap(final PropertyHashMap map) {
+        this.size      = map.size;
+        this.threshold = map.threshold;
+        this.bins      = map.bins;
+        this.list      = map.list;
+    }
+
+    /**
+     * Constructor used internally to extend a map
+     *
+     * @param size Size of the new {@link PropertyHashMap}.
+     * @param bins The hash bins.
+     * @param list The {@link Property} list.
+     */
+    private PropertyHashMap(final int size, final Element[] bins, final Element list) {
+        this.size      = size;
+        this.threshold = bins != null ? threeQuarters(bins.length) : 0;
+        this.bins      = bins;
+        this.list      = list;
+    }
+
+    /**
+     * Clone a {@link PropertyHashMap} and add a {@link Property}.
+     *
+     * @param property {@link Property} to add.
+     *
+     * @return New {@link PropertyHashMap}.
+     */
+    public PropertyHashMap immutableAdd(final Property property) {
+        final int newSize = size + 1;
+        PropertyHashMap newMap = cloneMap(newSize);
+        newMap = newMap.addNoClone(property);
+        return newMap;
+    }
+
+    /**
+     * Clone a {@link PropertyHashMap} and add an array of properties.
+     *
+     * @param newProperties Properties to add.
+     *
+     * @return New {@link PropertyHashMap}.
+     */
+    public PropertyHashMap immutableAdd(final Property... newProperties) {
+        final int newSize = size + newProperties.length;
+        PropertyHashMap newMap = cloneMap(newSize);
+        for (final Property property : newProperties) {
+            newMap = newMap.addNoClone(property);
+        }
+        return newMap;
+    }
+
+    /**
+     * Clone a {@link PropertyHashMap} and add a collection of properties.
+     *
+     * @param newProperties Properties to add.
+     *
+     * @return New {@link PropertyHashMap}.
+     */
+    public PropertyHashMap immutableAdd(final Collection<Property> newProperties) {
+        if (newProperties != null) {
+            final int newSize = size + newProperties.size();
+            PropertyHashMap newMap = cloneMap(newSize);
+            for (final Property property : newProperties) {
+                newMap = newMap.addNoClone(property);
+            }
+            return newMap;
+        }
+        return this;
+    }
+
+    /**
+     * Clone a {@link PropertyHashMap} and remove a {@link Property}.
+     *
+     * @param property {@link Property} to remove.
+     *
+     * @return New {@link PropertyHashMap}.
+     */
+    public PropertyHashMap immutableRemove(final Property property) {
+        return immutableRemove(property.getKey());
+    }
+
+    /**
+     * Clone a {@link PropertyHashMap} and remove a {@link Property} based on its key.
+     *
+     * @param key Key of {@link Property} to remove.
+     *
+     * @return New {@link PropertyHashMap}.
+     */
+    public PropertyHashMap immutableRemove(final String key) {
+        if (bins != null) {
+            final int binIndex = binIndex(bins, key);
+            final Element bin = bins[binIndex];
+            if (findElement(bin, key) != null) {
+                final int newSize = size - 1;
+                Element[] newBins = null;
+                if (newSize >= LIST_THRESHOLD) {
+                    newBins = bins.clone();
+                    newBins[binIndex] = removeFromList(bin, key);
+                }
+                final Element newList = removeFromList(list, key);
+                return new PropertyHashMap(newSize, newBins, newList);
+            }
+        } else if (findElement(list, key) != null) {
+            final int newSize = size - 1;
+            return newSize != 0 ? new PropertyHashMap(newSize, null, removeFromList(list, key)) : EMPTY_MAP;
+        }
+        return this;
+    }
+
+    /**
+     * Find a {@link Property} in the {@link PropertyHashMap}.
+     *
+     * @param key Key of {@link Property} to find.
+     *
+     * @return {@link Property} matching key or {@code null} if not found.
+     */
+    public Property find(final String key) {
+        final Element element = findElement(key);
+        return element != null ? element.getProperty() : null;
+    }
+
+    /**
+     * Return an array of properties in chronological order of adding.
+     *
+     * @return Array of all properties.
+     */
+    Property[] getProperties() {
+        if (properties == null) {
+            final Property[] array = new Property[size];
+            int i = size;
+            for (Element element = list; element != null; element = element.getLink()) {
+                array[--i] = element.getProperty();
+            }
+            properties = array;
+        }
+        return properties;
+    }
+
+    /**
+     * Returns the bin index from the key.
+     *
+     * @param bins     The bins array.
+     * @param key      {@link Property} key.
+     *
+     * @return The bin index.
+     */
+    private static int binIndex(final Element[] bins, final String key) {
+        return  key.hashCode() & (bins.length - 1);
+    }
+
+    /**
+     * Calculate the number of bins needed to contain n properties.
+     *
+     * @param n Number of elements.
+     *
+     * @return Number of bins required.
+     */
+    private static int binsNeeded(final int n) {
+        // Allow for 25% padding.
+        return 1 << (32 - Integer.numberOfLeadingZeros((n + oneQuarter(n)) | (INITIAL_BINS - 1)));
+    }
+
+    /**
+     * Used to calculate the current capacity of the bins.
+     *
+     * @param n Number of bin slots.
+     *
+     * @return 75% of n.
+     */
+    private static int threeQuarters(final int n) {
+        return (n >>> 1) + (n >>> 2);
+    }
+
+    /**
+     * Used to calculate the current capacity of the bins.
+     *
+     * @param n Number of bin slots.
+     *
+     * @return 25% of n.
+     */
+    private static int oneQuarter(final int n) {
+        return n >>> 2;
+    }
+
+    /**
+     * Regenerate the bin table after changing the number of bins.
+     *
+     * @param list    // List of all properties.
+     * @param newSize // New size of {@link PropertyHashMap}.
+     *
+     * @return Populated bins.
+     */
+    private static Element[] rehash(final Element list, final int newSize) {
+        final int binsNeeded = binsNeeded(newSize);
+        final Element[] newBins = new Element[binsNeeded];
+        for (Element element = list; element != null; element = element.getLink()) {
+            final Property property = element.getProperty();
+            final String key = property.getKey();
+            final int binIndex = binIndex(newBins, key);
+            newBins[binIndex] = new Element(newBins[binIndex], property);
+        }
+        return newBins;
+    }
+
+    /**
+     * Locate an element based on key.
+     *
+     * @param key {@link Element} key.
+     *
+     * @return {@link Element} matching key or {@code null} if not found.
+     */
+    private Element findElement(final String key) {
+        if (bins != null) {
+            final int binIndex = binIndex(bins, key);
+            return findElement(bins[binIndex], key);
+        }
+        return findElement(list, key);
+    }
+
+    /**
+     * Locate an {@link Element} based on key from a specific list.
+     *
+     * @param elementList Head of {@link Element} list
+     * @param key         {@link Element} key.
+     * @return {@link Element} matching key or {@code null} if not found.
+     */
+    private static Element findElement(final Element elementList, final String key) {
+        final int hashCode = key.hashCode();
+        for (Element element = elementList; element != null; element = element.getLink()) {
+            if (element.match(key, hashCode)) {
+                return element;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Clone {@link PropertyHashMap} to accommodate new size.
+     *
+     * @param newSize New size of {@link PropertyHashMap}.
+     *
+     * @return Cloned {@link PropertyHashMap} with new size.
+     */
+    private PropertyHashMap cloneMap(final int newSize) {
+        Element[] newBins;
+        if (bins == null && newSize <= LIST_THRESHOLD) {
+            newBins = null;
+        } else if (newSize > threshold) {
+            newBins = rehash(list, newSize);
+        } else {
+            newBins = bins.clone();
+        }
+        return new PropertyHashMap(newSize, newBins, list);
+    }
+
+    /**
+     * Add a {@link Property} to a temporary {@link PropertyHashMap}, that has
+     * been already cloned.  Removes duplicates if necessary.
+     *
+     * @param property {@link Property} to add.
+     *
+     * @return New {@link PropertyHashMap}.
+     */
+    private PropertyHashMap addNoClone(final Property property) {
+        int newSize = size;
+        final String key = property.getKey();
+        Element newList = list;
+        if (bins != null) {
+            final int binIndex = binIndex(bins, key);
+            Element bin = bins[binIndex];
+            if (findElement(bin, key) != null) {
+                newSize--;
+                bin = removeFromList(bin, key);
+                newList = removeFromList(list, key);
+            }
+            bins[binIndex] = new Element(bin, property);
+        } else {
+            if (findElement(list, key) != null) {
+                newSize--;
+                newList = removeFromList(list, key);
+            }
+        }
+        newList = new Element(newList, property);
+        return new PropertyHashMap(newSize, bins, newList);
+    }
+
+    /**
+     * Removes an {@link Element} from a specific list, avoiding duplication.
+     *
+     * @param list List to remove from.
+     * @param key  Key of {@link Element} to remove.
+     *
+     * @return New list with {@link Element} removed.
+     */
+    private static Element removeFromList(final Element list, final String key) {
+        if (list == null) {
+            return null;
+        }
+        final int hashCode = key.hashCode();
+        if (list.match(key, hashCode)) {
+            return list.getLink();
+        }
+        final Element head = new Element(null, list.getProperty());
+        Element previous = head;
+        for (Element element = list.getLink(); element != null; element = element.getLink()) {
+            if (element.match(key, hashCode)) {
+                previous.setLink(element.getLink());
+                return head;
+            }
+            final Element next = new Element(null, element.getProperty());
+            previous.setLink(next);
+            previous = next;
+        }
+        return list;
+    }
+
+    /*
+     * Map implementation
+     */
+
+    @Override
+    public int size() {
+        return size;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return size == 0;
+    }
+
+    @Override
+    public boolean containsKey(final Object key) {
+        if (key instanceof String) {
+            return findElement((String)key) != null;
+        }
+        assert key instanceof String;
+        return false;
+    }
+
+    /**
+     * Check if the map contains a key.
+     *
+     * @param key {@link Property} key.
+     *
+     * @return {@code true} of key is in {@link PropertyHashMap}.
+     */
+    public boolean containsKey(final String key) {
+        return findElement(key) != null;
+    }
+
+    @Override
+    public boolean containsValue(final Object value) {
+        if (value instanceof Property) {
+            final Property property = (Property) value;
+            final Element element = findElement(property.getKey());
+            return element != null && element.getProperty().equals(value);
+        }
+        return false;
+    }
+
+    @Override
+    public Property get(final Object key) {
+        if (key instanceof String) {
+            final Element element = findElement((String)key);
+            return element != null ? element.getProperty() : null;
+        }
+        assert key instanceof String;
+        return null;
+    }
+
+    /**
+     * Get the {@link Property} given a key that is an explicit {@link String}.
+     * See also {@link PropertyHashMap#get(Object)}
+     *
+     * @param key {@link Property} key.
+     *
+     * @return {@link Property}, or {@code null} if no property with that key was found.
+     */
+    public Property get(final String key) {
+        final Element element = findElement(key);
+        return element != null ? element.getProperty() : null;
+    }
+
+    @Override
+    public Property put(final String key, final Property value) {
+        throw new UnsupportedOperationException("Immutable map.");
+    }
+
+    @Override
+    public Property remove(final Object key) {
+        throw new UnsupportedOperationException("Immutable map.");
+    }
+
+    @Override
+    public void putAll(final Map<? extends String, ? extends Property> m) {
+        throw new UnsupportedOperationException("Immutable map.");
+    }
+
+    @Override
+    public void clear() {
+        throw new UnsupportedOperationException("Immutable map.");
+    }
+
+    @Override
+    public Set<String> keySet() {
+        final HashSet<String> set = new HashSet<>();
+        for (Element element = list; element != null; element = element.getLink()) {
+            set.add(element.getKey());
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    @Override
+    public Collection<Property> values() {
+        return Collections.unmodifiableList(Arrays.asList(getProperties()));
+    }
+
+    @Override
+    public Set<Entry<String, Property>> entrySet() {
+        final HashSet<Entry<String, Property>> set = new HashSet<>();
+        for (Element element = list; element != null; element = element.getLink()) {
+            set.add(element);
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * List map element.
+     */
+    static final class Element implements Entry<String, Property> {
+        /** Link for list construction. */
+        private Element link;
+
+        /** Element property. */
+        private final Property property;
+
+        /** Element key. Kept separate for performance.) */
+        private final String key;
+
+        /** Element key hash code. */
+        private final int hashCode;
+
+        /*
+         * Constructors
+         */
+
+        Element(final Element link, final Property property) {
+            this.link     = link;
+            this.property = property;
+            this.key      = property.getKey();
+            this.hashCode = this.key.hashCode();
+        }
+
+        boolean match(final String otherKey, final int otherHashCode) {
+            return this.hashCode == otherHashCode && this.key.equals(otherKey);
+        }
+
+        /*
+         * Entry implmentation.
+         */
+
+        @Override
+        public boolean equals(final Object other) {
+            assert property != null && other != null;
+            return other instanceof Element && property.equals(((Element)other).property);
+        }
+
+        @Override
+        public String getKey() {
+            return key;
+        }
+
+        @Override
+        public Property getValue() {
+            return property;
+        }
+
+        @Override
+        public int hashCode() {
+            return hashCode;
+        }
+
+        @Override
+        public Property setValue(final Property value) {
+            throw new UnsupportedOperationException("Immutable map.");
+        }
+
+        /*
+         * Accessors
+         */
+
+        Element getLink() {
+            return link;
+        }
+
+        void setLink(final Element link) {
+            this.link = link;
+        }
+
+        Property getProperty() {
+            return property;
+        }
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyListener.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyListener.java
new file mode 100644
index 0000000..867ac73
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyListener.java
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+/**
+ * Property change listener gets notified whenever properties are added/deleted/modified.
+ */
+public interface PropertyListener {
+    /**
+     * A new property is being added.
+     *
+     * @param object The ScriptObject to which property was added.
+     * @param prop The new Property added.
+     */
+    public void propertyAdded(ScriptObject object, Property prop);
+
+    /**
+     * An existing property is being deleted.
+     *
+     * @param object The ScriptObject whose property is being deleted.
+     * @param prop The property being deleted.
+     */
+    public void propertyDeleted(ScriptObject object, Property prop);
+
+    /**
+     * An existing Property is being replaced with a new Property.
+     *
+     * @param object The ScriptObject whose property is being modified.
+     * @param oldProp The old property that is being replaced.
+     * @param newProp The new property that replaces the old property.
+     *
+     */
+    public void propertyModified(ScriptObject object, Property oldProp, Property newProp);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java
new file mode 100644
index 0000000..970ccca
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java
@@ -0,0 +1,192 @@
+/*
+ * 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;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Helper class to manage property listeners and notification.
+ */
+public class PropertyListenerManager implements PropertyListener {
+
+    // These counters are updated in debug mode
+    private static int listenersAdded;
+    private static int listenersRemoved;
+    private static int listenersDead;
+
+    /**
+     * @return the listenersAdded
+     */
+    public static int getListenersAdded() {
+        return listenersAdded;
+    }
+
+    /**
+     * @return the listenersRemoved
+     */
+    public static int getListenersRemoved() {
+        return listenersRemoved;
+    }
+
+    /**
+     * @return the listenersDead
+     */
+    public static int getListenersDead() {
+        return listenersDead;
+    }
+
+    /** property listeners for this object. */
+    private List<WeakReference<PropertyListener>> listeners;
+
+    // Property listener management methods
+
+    /**
+     * Add a property listener to this object.
+     *
+     * @param listener The property listener that is added.
+     */
+    public final void addPropertyListener(final PropertyListener listener) {
+        if (listeners == null) {
+            listeners = new ArrayList<>();
+        }
+        if (Context.DEBUG) {
+            listenersAdded++;
+        }
+        listeners.add(new WeakReference<>(listener));
+    }
+
+    /**
+     * Remove a property listener from this object.
+     *
+     * @param listener The property listener that is removed.
+     */
+    public final void removePropertyListener(final PropertyListener listener) {
+        if (listeners != null) {
+            final Iterator<WeakReference<PropertyListener>> iter = listeners.iterator();
+            while (iter.hasNext()) {
+                if (iter.next().get() == listener) {
+                    if (Context.DEBUG) {
+                        listenersRemoved++;
+                    }
+                    iter.remove();
+                }
+            }
+        }
+    }
+
+    /**
+     * This method can be called to notify property addition to this object's listeners.
+     *
+     * @param object The ScriptObject to which property was added.
+     * @param prop The property being added.
+     */
+    protected final void notifyPropertyAdded(final ScriptObject object, final Property prop) {
+        if (listeners != null) {
+            final Iterator<WeakReference<PropertyListener>> iter = listeners.iterator();
+            while (iter.hasNext()) {
+                final WeakReference<PropertyListener> weakRef = iter.next();
+                final PropertyListener listener = weakRef.get();
+                if (listener == null) {
+                    if (Context.DEBUG) {
+                        listenersDead++;
+                    }
+                    iter.remove();
+                } else {
+                    listener.propertyAdded(object, prop);
+                }
+            }
+        }
+    }
+
+    /**
+     * This method can be called to notify property deletion to this object's listeners.
+     *
+     * @param object The ScriptObject from which property was deleted.
+     * @param prop The property being deleted.
+     */
+    protected final void notifyPropertyDeleted(final ScriptObject object, final Property prop) {
+        if (listeners != null) {
+            final Iterator<WeakReference<PropertyListener>> iter = listeners.iterator();
+            while (iter.hasNext()) {
+                final WeakReference<PropertyListener> weakRef = iter.next();
+                final PropertyListener listener = weakRef.get();
+                if (listener == null) {
+                    if (Context.DEBUG) {
+                        listenersDead++;
+                    }
+                    iter.remove();
+                } else {
+                    listener.propertyDeleted(object, prop);
+                }
+            }
+        }
+    }
+
+    /**
+     * This method can be called to notify property modification to this object's listeners.
+     *
+     * @param object The ScriptObject to which property was modified.
+     * @param oldProp The old property being replaced.
+     * @param newProp The new property that replaces the old property.
+     */
+    protected final void notifyPropertyModified(final ScriptObject object, final Property oldProp, final Property newProp) {
+        if (listeners != null) {
+            final Iterator<WeakReference<PropertyListener>> iter = listeners.iterator();
+            while (iter.hasNext()) {
+                final WeakReference<PropertyListener> weakRef = iter.next();
+                final PropertyListener listener = weakRef.get();
+                if (listener == null) {
+                    if (Context.DEBUG) {
+                        listenersDead++;
+                    }
+                    iter.remove();
+                } else {
+                    listener.propertyModified(object, oldProp, newProp);
+                }
+            }
+        }
+    }
+
+    // PropertyListener methods
+
+    @Override
+    public final void propertyAdded(final ScriptObject object, final Property prop) {
+        notifyPropertyAdded(object, prop);
+    }
+
+    @Override
+    public final void propertyDeleted(final ScriptObject object, final Property prop) {
+        notifyPropertyDeleted(object, prop);
+    }
+
+    @Override
+    public final void propertyModified(final ScriptObject object, final Property oldProp, final Property newProp) {
+        notifyPropertyModified(object, oldProp, newProp);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
new file mode 100644
index 0000000..19c12b7
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
@@ -0,0 +1,928 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_MAP;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.SwitchPoint;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.WeakHashMap;
+
+/**
+ * Map of object properties. The PropertyMap is the "template" for JavaScript object
+ * layouts. It contains a map with prototype names as keys and {@link Property} instances
+ * as values. A PropertyMap is typically passed to the {@link ScriptObject} constructor
+ * to form the seed map for the ScriptObject.
+ * <p>
+ * All property maps are immutable. If a property is added, modified or removed, the mutator
+ * will return a new map.
+ */
+public final class PropertyMap implements Iterable<Object>, PropertyListener {
+    /** Is this a prototype PropertyMap? */
+    public static final int IS_PROTOTYPE          = 0b0000_0001;
+    /** Used for non extensible PropertyMaps, negative logic as the normal case is extensible. See {@link ScriptObject#preventExtensions()} */
+    public static final int NOT_EXTENSIBLE        = 0b0000_0010;
+    /** This mask is used to preserve certain flags when cloning the PropertyMap. Others should not be copied */
+    private static final int CLONEABLE_FLAGS_MASK = 0b0000_1111;
+    /** Has a listener been added to this property map. This flag is not copied when cloning a map. See {@link PropertyListener} */
+    public static final int IS_LISTENER_ADDED     = 0b0001_0000;
+
+    /** Map status flags. */
+    private int flags;
+
+    /** Class of object referenced.*/
+    private final Class<?> structure;
+
+    /** Context associated with this {@link PropertyMap}. */
+    private final Context context;
+
+    /** Map of properties. */
+    private final PropertyHashMap properties;
+
+    /** objects proto. */
+    private ScriptObject proto;
+
+    /** Length of spill in use. */
+    private int spillLength;
+
+    /** {@link SwitchPoint}s for gets on inherited properties. */
+    private Map<String, SwitchPoint> protoGetSwitches;
+
+    /** History of maps, used to limit map duplication. */
+    private HashMap<Property, PropertyMap> history;
+
+    /** History of prototypes, used to limit map duplication. */
+    private WeakHashMap<ScriptObject, WeakReference<PropertyMap>> protoHistory;
+
+    /** Cache for hashCode */
+    private int hashCode;
+
+    /**
+     * Constructor.
+     *
+     * @param structure  Class the map's {@link AccessorProperty}s apply to.
+     * @param context    Context associated with this {@link PropertyMap}.
+     * @param properties A {@link PropertyHashMap} with initial contents.
+     */
+    PropertyMap(final Class<?> structure, final Context context, final PropertyHashMap properties) {
+        this.structure  = structure;
+        this.context    = context;
+        this.properties = properties;
+        this.hashCode   = computeHashCode();
+
+        if (Context.DEBUG) {
+            count++;
+        }
+    }
+
+    /**
+     * Cloning constructor.
+     *
+     * @param propertyMap Existing property map.
+     * @param properties  A {@link PropertyHashMap} with a new set of properties.
+     */
+    private PropertyMap(final PropertyMap propertyMap, final PropertyHashMap properties) {
+        this.structure   = propertyMap.structure;
+        this.context     = propertyMap.context;
+        this.properties  = properties;
+        this.flags       = propertyMap.getClonedFlags();
+        this.proto       = propertyMap.proto;
+        this.spillLength = propertyMap.spillLength;
+        this.hashCode    = computeHashCode();
+
+        if (Context.DEBUG) {
+            count++;
+            clonedCount++;
+        }
+    }
+
+    /**
+     * Duplicates this PropertyMap instance. This is used by nasgen generated
+     * prototype and constructor classes. {@link PropertyMap} used for singletons
+     * like these (and global instance) are duplicated using this method and used.
+     * The original filled map referenced by static fields of prototype and
+     * constructor classes are not touched. This allows multiple independent global
+     * instances to be used within a single context instance.
+     *
+     * @return Duplicated {@link PropertyMap}.
+     */
+    public PropertyMap duplicate() {
+        return new PropertyMap(this.structure, this.context, this.properties);
+    }
+
+    /**
+     * Public property map allocator.
+     *
+     * @param structure  Class the map's {@link AccessorProperty}s apply to.
+     * @param properties Collection of initial properties.
+     *
+     * @return New {@link PropertyMap}.
+     */
+    public static PropertyMap newMap(final Class<?> structure, final Collection<Property> properties) {
+        final Context context = Context.fromClass(structure);
+
+        // Reduce the number of empty maps in the context.
+        if (structure == jdk.nashorn.internal.scripts.JO.class) {
+            return context.emptyMap;
+        }
+
+        PropertyHashMap newProperties = EMPTY_MAP.immutableAdd(properties);
+
+        return new PropertyMap(structure, context, newProperties);
+    }
+
+    /**
+     * Public property map factory allocator
+     *
+     * @param structure  Class the map's {@link AccessorProperty}s apply to.
+     *
+     * @return New {@link PropertyMap}.
+     */
+    public static PropertyMap newMap(final Class<?> structure) {
+        return newMap(structure, null);
+    }
+
+    /**
+     * Return a sharable empty map.
+     *
+     * @param  context the context
+     * @return New empty {@link PropertyMap}.
+     */
+    public static PropertyMap newEmptyMap(final Context context) {
+        return new PropertyMap(jdk.nashorn.internal.scripts.JO.class, context, EMPTY_MAP);
+    }
+
+    /**
+     * Return number of properties in the map.
+     *
+     * @return Number of properties.
+     */
+    public int size() {
+        return properties.size();
+    }
+
+    /**
+     * Return a SwitchPoint used to track changes of a property in a prototype.
+     *
+     * @param key {@link Property} key.
+     *
+     * @return A shared {@link SwitchPoint} for the property.
+     */
+    public SwitchPoint getProtoGetSwitchPoint(final String key) {
+        if (proto == null) {
+            return null;
+        }
+
+        if (protoGetSwitches == null) {
+            protoGetSwitches = new HashMap<>();
+            if (! isListenerAdded()) {
+                proto.addPropertyListener(this);
+                setIsListenerAdded();
+            }
+        }
+
+        if (protoGetSwitches.containsKey(key)) {
+            return protoGetSwitches.get(key);
+        }
+
+        final SwitchPoint switchPoint = new SwitchPoint();
+        protoGetSwitches.put(key, switchPoint);
+
+        return switchPoint;
+    }
+
+    /**
+     * Indicate that a prototype property hash changed.
+     *
+     * @param property {@link Property} to invalidate.
+     */
+    private void invalidateProtoGetSwitchPoint(final Property property) {
+        if (protoGetSwitches != null) {
+            final String key = property.getKey();
+            final SwitchPoint sp = protoGetSwitches.get(key);
+            if (sp != null) {
+                protoGetSwitches.put(key, new SwitchPoint());
+                if (Context.DEBUG) {
+                    protoInvalidations++;
+                }
+                SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
+            }
+        }
+    }
+
+    /**
+     * Add a property to the map.
+     *
+     * @param property {@link Property} being added.
+     *
+     * @return New {@link PropertyMap} with {@link Property} added.
+     */
+    public PropertyMap newProperty(final Property property) {
+        return addProperty(property);
+    }
+
+    /**
+     * Add a property to the map, re-binding its getters and setters,
+     * if available, to a given receiver. This is typically the global scope. See
+     * {@link ScriptObject#addBoundProperties(ScriptObject)}
+     *
+     * @param property {@link Property} being added.
+     * @param bindTo   Object to bind to.
+     *
+     * @return New {@link PropertyMap} with {@link Property} added.
+     */
+    PropertyMap newPropertyBind(final AccessorProperty property, final ScriptObject bindTo) {
+        return newProperty(new AccessorProperty(property, bindTo));
+    }
+
+    /**
+     * Add a new accessor property to the map.
+     *
+     * @param key           {@link Property} key.
+     * @param propertyFlags {@link Property} flags.
+     * @param slot          {@link Property} slot.
+     * @param getter        {@link Property} get accessor method.
+     * @param setter        {@link Property} set accessor method.
+     *
+     * @return  New {@link PropertyMap} with {@link AccessorProperty} added.
+     */
+    public PropertyMap newProperty(final String key, final int propertyFlags, final int slot, final MethodHandle getter, final MethodHandle setter) {
+        return newProperty(new AccessorProperty(key, propertyFlags, slot, getter, setter));
+    }
+
+    /**
+     * Add a property to the map.  Cloning or using an existing map if available.
+     *
+     * @param property {@link Property} being added.
+     *
+     * @return New {@link PropertyMap} with {@link Property} added.
+     */
+    PropertyMap addProperty(final Property property) {
+        PropertyMap newMap = checkHistory(property);
+
+        if (newMap == null) {
+            final PropertyHashMap newProperties = properties.immutableAdd(property);
+            newMap = new PropertyMap(this, newProperties);
+            addToHistory(property, newMap);
+            newMap.spillLength += property.getSpillCount();
+        }
+
+        return newMap;
+    }
+
+    /**
+     * Remove a property from a map. Cloning or using an existing map if available.
+     *
+     * @param property {@link Property} being removed.
+     *
+     * @return New {@link PropertyMap} with {@link Property} removed or {@code null} if not found.
+     */
+    public PropertyMap deleteProperty(final Property property) {
+        PropertyMap newMap = checkHistory(property);
+        final String key = property.getKey();
+
+        if (newMap == null && properties.containsKey(key)) {
+            final PropertyHashMap newProperties = properties.immutableRemove(key);
+            newMap = new PropertyMap(this, newProperties);
+            addToHistory(property, newMap);
+        }
+
+        return newMap;
+    }
+
+    /**
+     * Replace an existing property with a new one.
+     *
+     * @param oldProperty Property to replace.
+     * @param newProperty New {@link Property}.
+     *
+     * @return New {@link PropertyMap} with {@link Property} replaced.
+     */
+    PropertyMap replaceProperty(final Property oldProperty, final Property newProperty) {
+        // Add replaces existing property.
+        final PropertyHashMap newProperties = properties.immutableAdd(newProperty);
+        final PropertyMap newMap = new PropertyMap(this, newProperties);
+
+        /*
+         * See ScriptObject.modifyProperty and ScriptObject.setUserAccessors methods.
+         *
+         * This replaceProperty method is called only for the following three cases:
+         *
+         *   1. To change flags OR TYPE of an old (cloned) property. We use the same spill slots.
+         *   2. To change one UserAccessor property with another - user getter or setter changed via
+         *      Object.defineProperty function. Again, same spill slots are re-used.
+         *   3. Via ScriptObject.setUserAccessors method to set user getter and setter functions
+         *      replacing the dummy AccessorProperty with null method handles (added during map init).
+         *
+         * In case (1) and case(2), the property type of old and new property is same. For case (3),
+         * the old property is an AccessorProperty and the new one is a UserAccessorProperty property.
+         */
+
+        final boolean sameType = (oldProperty.getClass() == newProperty.getClass());
+        assert sameType ||
+                (oldProperty instanceof AccessorProperty &&
+                newProperty instanceof UserAccessorProperty) : "arbitrary replaceProperty attempted";
+
+        newMap.flags = getClonedFlags();
+        newMap.proto = proto;
+
+        /*
+         * spillLength remains same in case (1) and (2) because of slot reuse. Only for case (3), we need
+         * to add spill count of the newly added UserAccessorProperty property.
+         */
+        newMap.spillLength = spillLength + (sameType? 0 : newProperty.getSpillCount());
+        return newMap;
+    }
+
+    /**
+     * Find a property in the map.
+     *
+     * @param key Key to search for.
+     *
+     * @return {@link Property} matching key.
+     */
+    public Property findProperty(final String key) {
+        return properties.find(key);
+    }
+
+    /**
+     * Adds all map properties from another map.
+     *
+     * @param other The source of properties.
+     *
+     * @return New {@link PropertyMap} with added properties.
+     */
+    public PropertyMap addAll(final PropertyMap other) {
+        assert this != other : "adding property map to itself";
+        final Property[] otherProperties = other.properties.getProperties();
+        final PropertyHashMap newProperties = properties.immutableAdd(otherProperties);
+
+        final PropertyMap newMap = new PropertyMap(this, newProperties);
+        for (final Property property : otherProperties) {
+            newMap.spillLength += property.getSpillCount();
+        }
+
+        return newMap;
+    }
+
+    /**
+     * Return an array of all properties.
+     *
+     * @return Properties as an array.
+     */
+    public Property[] getProperties() {
+        return properties.getProperties();
+    }
+
+    /**
+     * Prevents the map from having additional properties.
+     *
+     * @return New map with {@link #NOT_EXTENSIBLE} flag set.
+     */
+    PropertyMap preventExtensions() {
+        final PropertyMap newMap = new PropertyMap(this, this.properties);
+        newMap.flags |= NOT_EXTENSIBLE;
+        return newMap;
+    }
+
+    /**
+     * Prevents properties in map from being modified.
+     *
+     * @return New map with {@link #NOT_EXTENSIBLE} flag set and properties with
+     * {@link Property#NOT_CONFIGURABLE} set.
+     */
+    PropertyMap seal() {
+        PropertyHashMap newProperties = EMPTY_MAP;
+
+        for (final Property oldProperty :  properties.getProperties()) {
+            newProperties = newProperties.immutableAdd(oldProperty.addFlags(Property.NOT_CONFIGURABLE));
+        }
+
+        final PropertyMap newMap = new PropertyMap(this, newProperties);
+        newMap.flags |= NOT_EXTENSIBLE;
+
+        return newMap;
+    }
+
+    /**
+     * Prevents properties in map from being modified or written to.
+     *
+     * @return New map with {@link #NOT_EXTENSIBLE} flag set and properties with
+     * {@link Property#NOT_CONFIGURABLE} and {@link Property#NOT_WRITABLE} set.
+     */
+    PropertyMap freeze() {
+        PropertyHashMap newProperties = EMPTY_MAP;
+
+        for (Property oldProperty : properties.getProperties()) {
+            int propertyFlags = Property.NOT_CONFIGURABLE;
+
+            if (!(oldProperty instanceof UserAccessorProperty)) {
+                propertyFlags |= Property.NOT_WRITABLE;
+            }
+
+            newProperties = newProperties.immutableAdd(oldProperty.addFlags(propertyFlags));
+        }
+
+        final PropertyMap newMap = new PropertyMap(this, newProperties);
+        newMap.flags |= NOT_EXTENSIBLE;
+
+        return newMap;
+    }
+
+    /**
+     * Check for any configurable properties.
+     *
+     * @return {@code true} if any configurable.
+     */
+    private boolean anyConfigurable() {
+        for (final Property property : properties.getProperties()) {
+            if (property.isConfigurable()) {
+               return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Check if all properties are frozen.
+     *
+     * @return {@code true} if all are frozen.
+     */
+    private boolean allFrozen() {
+        for (final Property property : properties.getProperties()) {
+            // check if it is a data descriptor
+            if (!(property instanceof UserAccessorProperty)) {
+                if (property.isWritable()) {
+                    return false;
+                }
+            }
+            if (property.isConfigurable()) {
+               return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Check prototype history for an existing property map with specified prototype.
+     *
+     * @param newProto New prototype object.
+     *
+     * @return Existing {@link PropertyMap} or {@code null} if not found.
+     */
+    private PropertyMap checkProtoHistory(final ScriptObject newProto) {
+        final PropertyMap cachedMap;
+        if (protoHistory != null) {
+            final WeakReference<PropertyMap> weakMap = protoHistory.get(newProto);
+            cachedMap = (weakMap != null ? weakMap.get() : null);
+        } else {
+            cachedMap = null;
+        }
+
+        if (Context.DEBUG && cachedMap != null) {
+            protoHistoryHit++;
+        }
+
+        return cachedMap;
+    }
+
+    /**
+     * Add a map to the prototype history.
+     *
+     * @param newProto Prototype to add (key.)
+     * @param newMap   {@link PropertyMap} associated with prototype.
+     */
+    private void addToProtoHistory(final ScriptObject newProto, final PropertyMap newMap) {
+        if (protoHistory == null) {
+            protoHistory = new WeakHashMap<>();
+        }
+
+        protoHistory.put(newProto, new WeakReference<>(newMap));
+    }
+
+    /**
+     * Track the modification of the map.
+     *
+     * @param property Mapping property.
+     * @param newMap   Modified {@link PropertyMap}.
+     */
+    private void addToHistory(final Property property, final PropertyMap newMap) {
+        if (history == null) {
+            history = new LinkedHashMap<>();
+        }
+
+        history.put(property, newMap);
+    }
+
+    /**
+     * Check the history for a map that already has the given property added.
+     *
+     * @param property {@link Property} to add.
+     *
+     * @return Existing map or {@code null} if not found.
+     */
+    private PropertyMap checkHistory(final Property property) {
+        if (history != null) {
+            PropertyMap historicMap = history.get(property);
+
+            if (historicMap != null) {
+                if (Context.DEBUG) {
+                    historyHit++;
+                }
+
+                return historicMap;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Calculate the hash code for the map.
+     *
+     * @return Computed hash code.
+     */
+    private int computeHashCode() {
+        int hash = structure.hashCode();
+
+        if (proto != null) {
+            hash ^= proto.hashCode();
+        }
+
+        for (final Property property : getProperties()) {
+            hash = hash << 7 ^ hash >> 7;
+            hash ^= property.hashCode();
+        }
+
+        return hash;
+    }
+
+    @Override
+    public int hashCode() {
+        return hashCode;
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!(other instanceof PropertyMap)) {
+            return false;
+        }
+
+        final PropertyMap otherMap = (PropertyMap)other;
+
+        if (structure != otherMap.structure ||
+            proto != otherMap.proto ||
+            properties.size() != otherMap.properties.size()) {
+            return false;
+        }
+
+        final Iterator<Property> iter      = properties.values().iterator();
+        final Iterator<Property> otherIter = otherMap.properties.values().iterator();
+
+        while (iter.hasNext() && otherIter.hasNext()) {
+            if (!iter.next().equals(otherIter.next())) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+
+        sb.append(" [");
+        boolean isFirst = true;
+
+        for (final Property property : properties.values()) {
+            if (!isFirst) {
+                sb.append(", ");
+            }
+
+            isFirst = false;
+
+            sb.append(ScriptRuntime.safeToString(property.getKey()));
+            final Class<?> ctype = property.getCurrentType();
+            sb.append(" <").
+                append(property.getClass().getSimpleName()).
+                append(':').
+                append(ctype == null ?
+                    "undefined" :
+                    ctype.getSimpleName()).
+                append('>');
+        }
+
+        sb.append(']');
+
+        return sb.toString();
+    }
+
+    @Override
+    public Iterator<Object> iterator() {
+        return new PropertyMapIterator(this);
+    }
+
+    /**
+     * Return map's {@link Context}.
+     *
+     * @return The {@link Context} where the map originated.
+     */
+    Context getContext() {
+        return context;
+    }
+
+    /**
+     * Check if this map is a prototype
+     *
+     * @return {@code true} if is prototype
+     */
+    public boolean isPrototype() {
+        return (flags & IS_PROTOTYPE) != 0;
+    }
+
+    /**
+     * Flag this map as having a prototype.
+     */
+    private void setIsPrototype() {
+        flags |= IS_PROTOTYPE;
+    }
+
+    /**
+     * Check whether a {@link PropertyListener} has been added to this map.
+     *
+     * @return {@code true} if {@link PropertyListener} exists
+     */
+    public boolean isListenerAdded() {
+        return (flags & IS_LISTENER_ADDED) != 0;
+    }
+
+    /**
+     * Test to see if {@link PropertyMap} is extensible.
+     *
+     * @return {@code true} if {@link PropertyMap} can be added to.
+     */
+    boolean isExtensible() {
+        return (flags & NOT_EXTENSIBLE) == 0;
+    }
+
+    /**
+     * Test to see if {@link PropertyMap} is not extensible or any properties
+     * can not be modified.
+     *
+     * @return {@code true} if {@link PropertyMap} is sealed.
+     */
+    boolean isSealed() {
+        return !isExtensible() && !anyConfigurable();
+    }
+
+    /**
+     * Test to see if {@link PropertyMap} is not extensible or all properties
+     * can not be modified.
+     *
+     * @return {@code true} if {@link PropertyMap} is frozen.
+     */
+    boolean isFrozen() {
+        return !isExtensible() && allFrozen();
+    }
+
+    /**
+     * Get length of spill area associated with this {@link PropertyMap}.
+     *
+     * @return Length of spill area.
+     */
+    int getSpillLength() {
+        return spillLength;
+    }
+
+    /**
+     * Return the prototype of objects associated with this {@link PropertyMap}.
+     *
+     * @return Prototype object.
+     */
+    ScriptObject getProto() {
+        return proto;
+    }
+
+    /**
+     * Set the prototype of objects associated with this {@link PropertyMap}.
+     *
+     * @param newProto Prototype object to use.
+     *
+     * @return New {@link PropertyMap} with prototype changed.
+     */
+    PropertyMap setProto(final ScriptObject newProto) {
+        final ScriptObject oldProto = this.proto;
+
+        if (oldProto == newProto) {
+            return this;
+        }
+
+        final PropertyMap nextMap = checkProtoHistory(newProto);
+        if (nextMap != null) {
+            return nextMap;
+        }
+
+        if (Context.DEBUG) {
+            incrementSetProtoNewMapCount();
+        }
+        final PropertyMap newMap = new PropertyMap(this, this.properties);
+        addToProtoHistory(newProto, newMap);
+
+        newMap.proto = newProto;
+
+        if (oldProto != null && newMap.isListenerAdded()) {
+            oldProto.removePropertyListener(newMap);
+        }
+
+        if (newProto != null) {
+            newProto.getMap().setIsPrototype();
+        }
+
+        return newMap;
+    }
+
+    /**
+     * Indicate that the map has listeners.
+     */
+    private void setIsListenerAdded() {
+        flags |= IS_LISTENER_ADDED;
+    }
+
+    /**
+     * Return only the flags that should be copied during cloning.
+     *
+     * @return Subset of flags that should be copied.
+     */
+    private int getClonedFlags() {
+        return flags & CLONEABLE_FLAGS_MASK;
+    }
+
+    /**
+     * {@link PropertyMap} iterator.
+     */
+    private static class PropertyMapIterator implements Iterator<Object> {
+        /** Property iterator. */
+        final Iterator<Property> iter;
+
+        /** Current Property. */
+        Property property;
+
+        /**
+         * Constructor.
+         *
+         * @param propertyMap {@link PropertyMap} to iterate over.
+         */
+        PropertyMapIterator(final PropertyMap propertyMap) {
+            iter = Arrays.asList(propertyMap.properties.getProperties()).iterator();
+            property = iter.hasNext() ? iter.next() : null;
+            skipNotEnumerable();
+        }
+
+        /**
+         * Ignore properties that are not enumerable.
+         */
+        private void skipNotEnumerable() {
+            while (property != null && !property.isEnumerable()) {
+                property = iter.hasNext() ? iter.next() : null;
+            }
+        }
+
+        @Override
+        public boolean hasNext() {
+            return property != null;
+        }
+
+        @Override
+        public Object next() {
+            if (property == null) {
+                throw new NoSuchElementException();
+            }
+
+            final Object key = property.getKey();
+            property = iter.next();
+            skipNotEnumerable();
+
+            return key;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /*
+     * PropertyListener implementation.
+     */
+
+    @Override
+    public void propertyAdded(final ScriptObject object, final Property prop) {
+        invalidateProtoGetSwitchPoint(prop);
+    }
+
+    @Override
+    public void propertyDeleted(final ScriptObject object, final Property prop) {
+        invalidateProtoGetSwitchPoint(prop);
+    }
+
+    @Override
+    public void propertyModified(final ScriptObject object, final Property oldProp, final Property newProp) {
+        invalidateProtoGetSwitchPoint(oldProp);
+    }
+
+    /*
+     * Debugging and statistics.
+     */
+
+    // counters updated only in debug mode
+    private static int count;
+    private static int clonedCount;
+    private static int historyHit;
+    private static int protoInvalidations;
+    private static int protoHistoryHit;
+    private static int setProtoNewMapCount;
+
+    /**
+     * @return Total number of maps.
+     */
+    public static int getCount() {
+        return count;
+    }
+
+    /**
+     * @return The number of maps that were cloned.
+     */
+    public static int getClonedCount() {
+        return clonedCount;
+    }
+
+    /**
+     * @return The number of times history was successfully used.
+     */
+    public static int getHistoryHit() {
+        return historyHit;
+    }
+
+    /**
+     * @return The number of times prototype changes caused invalidation.
+     */
+    public static int getProtoInvalidations() {
+        return protoInvalidations;
+    }
+
+    /**
+     * @return The number of times proto history was successfully used.
+     */
+    public static int getProtoHistoryHit() {
+        return protoHistoryHit;
+    }
+
+    /**
+     * @return The number of times prototypes were modified.
+     */
+    public static int getSetProtoNewMapCount() {
+        return setProtoNewMapCount;
+    }
+
+    /**
+     * Increment the prototype set count.
+     */
+    private static void incrementSetProtoNewMapCount() {
+        setProtoNewMapCount++;
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/QuotedStringTokenizer.java b/nashorn/src/jdk/nashorn/internal/runtime/QuotedStringTokenizer.java
new file mode 100644
index 0000000..3aae7fd
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/QuotedStringTokenizer.java
@@ -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.
+ */
+
+package jdk.nashorn.internal.runtime;
+
+import java.util.LinkedList;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+/**
+ * A string tokenizer that supports entries with quotes and nested quotes. If
+ * the separators are quoted either by ' and ", or whatever quotes the user
+ * supplies they will be ignored and considered part of another token
+ */
+public final class QuotedStringTokenizer {
+    private final LinkedList<String> tokens;
+
+    private final char quotes[];
+
+    /**
+     * Constructor
+     *
+     * @param str string to tokenize
+     */
+    public QuotedStringTokenizer(final String str) {
+        this(str, " ");
+    }
+
+    /**
+     * Create a quoted string tokenizer
+     *
+     * @param str
+     *            a string to tokenize
+     * @param delim
+     *            delimiters between tokens
+     *
+     */
+    public QuotedStringTokenizer(final String str, final String delim) {
+        this(str, delim, new char[] { '"', '\'' });
+    }
+
+    /**
+     * Create a quoted string tokenizer
+     *
+     * @param str
+     *            a string to tokenize
+     * @param delim
+     *            delimiters between tokens
+     * @param quotes
+     *            all the characters that should be accepted as quotes, default
+     *            is ' or "
+     */
+    private QuotedStringTokenizer(final String str, final String delim, final char[] quotes) {
+        this.quotes = quotes;
+
+        boolean delimIsWhitespace = true;
+        for (int i = 0; i < delim.length(); i++) {
+            if (!Character.isWhitespace(delim.charAt(i))) {
+                delimIsWhitespace = false;
+                break;
+            }
+        }
+
+        final StringTokenizer st = new StringTokenizer(str, delim);
+        tokens = new LinkedList<>();
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+
+            while (unmatchedQuotesIn(token)) {
+                if (!st.hasMoreTokens()) {
+                    throw new IndexOutOfBoundsException(token);
+                }
+                token += (delimIsWhitespace ? " " : delim) + st.nextToken();
+            }
+            tokens.add(stripQuotes(token));
+        }
+    }
+
+    /**
+     * @return the number of tokens in the tokenizer
+     */
+    public int countTokens() {
+        return tokens.size();
+    }
+
+    /**
+     * @return true if there are tokens left
+     */
+    public boolean hasMoreTokens() {
+        return countTokens() > 0;
+    }
+
+    /**
+     * @return the next token in the tokenizer
+     */
+    public String nextToken() {
+        return tokens.removeFirst();
+    }
+
+    private String stripQuotes(final String value0) {
+        String value = value0.trim();
+        for (final char q : quotes) {
+            if (value.length() >= 2 && value.startsWith("" + q) && value.endsWith("" + q)) {
+                // also go over the value and remove \q sequences. they are just
+                // plain q now
+                value = value.substring(1, value.length() - 1);
+                value = value.replace("\\" + q, "" + q);
+            }
+        }
+        return value;
+    }
+
+    private boolean unmatchedQuotesIn(final String str) {
+        final Stack<Character> quoteStack = new Stack<>();
+        for (int i = 0; i < str.length(); i++) {
+            final char c = str.charAt(i);
+            for (final char q : this.quotes) {
+                if (c == q) {
+                    if (quoteStack.isEmpty()) {
+                        quoteStack.push(c);
+                    } else {
+                        final char top = quoteStack.pop();
+                        if (top != c) {
+                            quoteStack.push(top);
+                            quoteStack.push(c);
+                        }
+                    }
+                }
+            }
+        }
+
+        return !quoteStack.isEmpty();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Scope.java b/nashorn/src/jdk/nashorn/internal/runtime/Scope.java
new file mode 100644
index 0000000..eb7eb1f
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Scope.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.runtime;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
+
+import jdk.nashorn.internal.codegen.CompilerConstants;
+
+/**
+ * Interface implemented by {@link ScriptObject}s that act as scope.
+ */
+public interface Scope {
+
+    /** Method handle that points to {@link Scope#getSplitState}. */
+    public static final CompilerConstants.Call GET_SPLIT_STATE = interfaceCallNoLookup(Scope.class, "getSplitState", int.class);
+
+    /** Method handle that points to {@link Scope#setSplitState(int)}. */
+    public static final CompilerConstants.Call SET_SPLIT_STATE = interfaceCallNoLookup(Scope.class, "setSplitState", void.class, int.class);
+
+    /**
+     * Get the scope's split method state.
+     * @return the current state
+     */
+    public int getSplitState();
+
+    /**
+     * Set the scope's split method state.
+     * @param state the new state.
+     */
+    public void setSplitState(int state);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
new file mode 100644
index 0000000..def0313
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
@@ -0,0 +1,249 @@
+/*
+ * 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;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+import jdk.nashorn.internal.codegen.Namespace;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+import jdk.nashorn.internal.runtime.options.KeyValueOption;
+import jdk.nashorn.internal.runtime.options.Option;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Script environment consists of command line options, arguments, script files
+ * and output and error writers, top level Namespace etc.
+ */
+public final class ScriptEnvironment {
+    /** Output writer for this environment */
+    private final PrintWriter out;
+
+    /** Error writer for this environment */
+    private final PrintWriter err;
+
+    /** Top level namespace. */
+    private final Namespace namespace;
+
+    /** Current Options object. */
+    private Options options;
+
+    /** Always allow functions as statements */
+    public final boolean _anon_functions;
+
+    /** Size of the per-global Class cache size */
+    public final int     _class_cache_size;
+
+    /** Only compile script, do not run it or generate other ScriptObjects */
+    public final boolean _compile_only;
+
+    /** Accumulated callsite flags that will be used when bootstrapping script callsites */
+    public final int     _callsite_flags;
+
+    /** Generate line number table in class files */
+    public final boolean _debug_lines;
+
+    /** Package to which generated class files are added */
+    public final String  _dest_dir;
+
+    /** Display stack trace upon error, default is false */
+    public final boolean _dump_on_error;
+
+    /** Invalid lvalue expressions should be reported as early errors */
+    public final boolean _early_lvalue_error;
+
+    /** Empty statements should be preserved in the AST */
+    public final boolean _empty_statements;
+
+    /** Show full Nashorn version */
+    public final boolean _fullversion;
+
+    /** Create a new class loaded for each compilation */
+    public final boolean _loader_per_compile;
+
+    /** Do not support non-standard syntax extensions. */
+    public final boolean _no_syntax_extensions;
+
+    /** Package to which generated class files are added */
+    public final String  _package;
+
+    /** Only parse the source code, do not compile */
+    public final boolean _parse_only;
+
+    /** Print the AST before lowering */
+    public final boolean _print_ast;
+
+    /** Print the AST after lowering */
+    public final boolean _print_lower_ast;
+
+    /** Print resulting bytecode for script */
+    public final boolean _print_code;
+
+    /** Print function will no print newline characters */
+    public final boolean _print_no_newline;
+
+    /** Print AST in more human readable form */
+    public final boolean _print_parse;
+
+    /** Print AST in more human readable form after Lowering */
+    public final boolean _print_lower_parse;
+
+    /** print symbols and their contents for the script */
+    public final boolean _print_symbols;
+
+    /** is this environment in scripting mode? */
+    public final boolean _scripting;
+
+    /** is this environment in strict mode? */
+    public final boolean _strict;
+
+    /** print version info of Nashorn */
+    public final boolean _version;
+
+    /** should code verification be done of generated bytecode */
+    public final boolean _verify_code;
+
+    /** time zone for this environment */
+    public final TimeZone _timezone;
+
+    /** Local for error messages */
+    public final Locale _locale;
+
+    /**
+     * Constructor
+     *
+     * @param options a Options object
+     * @param out output print writer
+     * @param err error print writer
+     */
+    ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) {
+        this.out = out;
+        this.err = err;
+        this.namespace = new Namespace();
+        this.options = options;
+
+        _anon_functions       = options.getBoolean("anon.functions");
+        _class_cache_size     = options.getInteger("class.cache.size");
+        _compile_only         = options.getBoolean("compile.only");
+        _debug_lines          = options.getBoolean("debug.lines");
+        _dest_dir             = options.getString("d");
+        _dump_on_error        = options.getBoolean("doe");
+        _early_lvalue_error   = options.getBoolean("early.lvalue.error");
+        _empty_statements     = options.getBoolean("empty.statements");
+        _fullversion          = options.getBoolean("fullversion");
+        _loader_per_compile   = options.getBoolean("loader.per.compile");
+        _no_syntax_extensions = options.getBoolean("no.syntax.extensions");
+        _package              = options.getString("package");
+        _parse_only           = options.getBoolean("parse.only");
+        _print_ast            = options.getBoolean("print.ast");
+        _print_lower_ast      = options.getBoolean("print.lower.ast");
+        _print_code           = options.getBoolean("print.code");
+        _print_no_newline     = options.getBoolean("print.no.newline");
+        _print_parse          = options.getBoolean("print.parse");
+        _print_lower_parse    = options.getBoolean("print.lower.parse");
+        _print_symbols        = options.getBoolean("print.symbols");
+        _scripting            = options.getBoolean("scripting");
+        _strict               = options.getBoolean("strict");
+        _version              = options.getBoolean("version");
+        _verify_code          = options.getBoolean("verify.code");
+
+        int callSiteFlags = 0;
+        if (options.getBoolean("profile.callsites")) {
+            callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_PROFILE;
+        }
+
+        if (options.get("trace.callsites") instanceof KeyValueOption) {
+            callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE;
+            final KeyValueOption kv = (KeyValueOption)options.get("trace.callsites");
+            if (kv.hasValue("miss")) {
+                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES;
+            }
+            if (kv.hasValue("enterexit") || (callSiteFlags & NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES) == 0) {
+                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT;
+            }
+            if (kv.hasValue("objects")) {
+                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES;
+            }
+            if (kv.hasValue("scope")) {
+                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_SCOPE;
+            }
+        }
+        this._callsite_flags = callSiteFlags;
+
+        final Option<?> option = options.get("timezone");
+        if (option != null) {
+            this._timezone = (TimeZone)option.getValue();
+        } else {
+            this._timezone  = TimeZone.getDefault();
+        }
+
+        this._locale = Locale.getDefault();
+    }
+
+    /**
+     * Get the output stream for this environment
+     * @return output print writer
+     */
+    public PrintWriter getOut() {
+        return out;
+    }
+
+    /**
+     * Get the error stream for this environment
+     * @return error print writer
+     */
+    public PrintWriter getErr() {
+        return err;
+    }
+
+    /**
+     * Get the namespace for this environment
+     * @return namespace
+     */
+    public Namespace getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * Return the JavaScript files passed to the program
+     *
+     * @return a list of files
+     */
+    public List<String> getFiles() {
+        return options.getFiles();
+    }
+
+    /**
+     * Return the user arguments to the program, i.e. those trailing "--" after
+     * the filename
+     *
+     * @return a list of user arguments
+     */
+    public List<String> getArguments() {
+        return options.getArguments();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
new file mode 100644
index 0000000..2d28f91
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
@@ -0,0 +1,574 @@
+/*
+ * 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;
+
+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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+import jdk.nashorn.internal.runtime.linker.NashornGuards;
+
+/**
+ * Runtime representation of a JavaScript function.
+ */
+public abstract class ScriptFunction extends ScriptObject {
+
+    /** Method handle for prototype getter for this ScriptFunction */
+    public static final MethodHandle G$PROTOTYPE  = findOwnMH("G$prototype",  Object.class, Object.class);
+
+    /** Method handle for prototype setter for this ScriptFunction */
+    public static final MethodHandle S$PROTOTYPE  = findOwnMH("S$prototype",  void.class, Object.class, Object.class);
+
+    /** Method handle for length getter for this ScriptFunction */
+    public static final MethodHandle G$LENGTH     = findOwnMH("G$length",     int.class, Object.class);
+
+    /** Method handle for name getter for this ScriptFunction */
+    public static final MethodHandle G$NAME       = findOwnMH("G$name",       Object.class, Object.class);
+
+    /** Method handle for allocate function for this ScriptFunction */
+    static final MethodHandle ALLOCATE = findOwnMH("allocate", Object.class);
+
+    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", Object.class, Object.class);
+
+    /** method handle to scope getter for this ScriptFunction */
+    public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
+
+    private final ScriptFunctionData data;
+
+    /** Reference to constructor prototype. */
+    protected Object prototype;
+
+    /** The parent scope. */
+    private final ScriptObject scope;
+
+    /**
+     * Constructor
+     *
+     * @param name          function name
+     * @param methodHandle  method handle to function (if specializations are present, assumed to be most generic)
+     * @param map           property map
+     * @param scope         scope
+     * @param specs         specialized version of this function - other method handles
+     * @param strict        is this a strict mode function?
+     * @param builtin       is this a built in function?
+     * @param isConstructor is this a constructor?
+     */
+    protected ScriptFunction(
+            final String name,
+            final MethodHandle methodHandle,
+            final PropertyMap map,
+            final ScriptObject scope,
+            final MethodHandle[] specs,
+            final boolean strict,
+            final boolean builtin,
+            final boolean isConstructor) {
+
+        this (new ScriptFunctionData(name, methodHandle, specs, strict, builtin, isConstructor), map, scope);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param data          static function data
+     * @param map           property map
+     * @param scope         scope
+     */
+    protected ScriptFunction(
+            final ScriptFunctionData data,
+            final PropertyMap map,
+            final ScriptObject scope) {
+
+        super(map);
+
+        if (Context.DEBUG) {
+            constructorCount++;
+        }
+
+        this.data = data;
+        this.scope  = scope;
+    }
+
+    @Override
+    public String getClassName() {
+        return "Function";
+    }
+
+    /**
+     * ECMA 15.3.5.3 [[HasInstance]] (V)
+     * Step 3 if "prototype" value is not an Object, throw TypeError
+     */
+    @Override
+    public boolean isInstance(final ScriptObject instance) {
+        final Object basePrototype = getTargetFunction().getPrototype();
+        if (!(basePrototype instanceof ScriptObject)) {
+            throw typeError("prototype.not.an.object", ScriptRuntime.safeToString(getTargetFunction()), ScriptRuntime.safeToString(basePrototype));
+        }
+
+        for (ScriptObject proto = instance.getProto(); proto != null; proto = proto.getProto()) {
+            if (proto == basePrototype) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the target function for this function. If the function was not created using
+     * {@link #makeBoundFunction(Object, Object[])}, its target function is itself. If it is bound, its target function
+     * is the target function of the function it was made from (therefore, the target function is always the final,
+     * unbound recipient of the calls).
+     * @return the target function for this function.
+     */
+    protected ScriptFunction getTargetFunction() {
+        return this;
+    }
+
+    boolean isBoundFunction() {
+        return getTargetFunction() != this;
+    }
+
+    /**
+     * Set the arity of this ScriptFunction
+     * @param arity arity
+     */
+    public final void setArity(final int arity) {
+        data.setArity(arity);
+    }
+
+    /**
+     * Is this a ECMAScript 'use strict' function?
+     * @return true if function is in strict mode
+     */
+    public boolean isStrict() {
+        return data.isStrict();
+    }
+
+    /**
+     * Returns true if this is a non-strict, non-built-in function that requires non-primitive this argument
+     * according to ECMA 10.4.3.
+     * @return true if this argument must be an object
+     */
+    public boolean needsWrappedThis() {
+        return data.needsWrappedThis();
+    }
+
+    /**
+     * Execute this script function.
+     * @param self  Target object.
+     * @param arguments  Call arguments.
+     * @return ScriptFunction result.
+     * @throws Throwable if there is an exception/error with the invocation or thrown from it
+     */
+    Object invoke(final Object self, final Object... arguments) throws Throwable {
+        if (Context.DEBUG) {
+            invokes++;
+        }
+        return data.invoke(this, self, arguments);
+    }
+
+    /**
+     * Allocate function. Called from generated {@link ScriptObject} code
+     * for allocation as a factory method
+     *
+     * @return a new instance of the {@link ScriptObject} whose allocator this is
+     */
+    @SuppressWarnings("unused")
+    private Object allocate() {
+        if (Context.DEBUG) {
+            allocations++;
+        }
+        assert !isBoundFunction(); // allocate never invoked on bound functions
+
+        final ScriptObject object = data.allocate();
+
+        if (object != null) {
+            if (prototype instanceof ScriptObject) {
+                object.setProto((ScriptObject)prototype);
+            }
+
+            if (object.getProto() == null) {
+                object.setProto(getObjectPrototype());
+            }
+        }
+
+        return object;
+    }
+
+    /**
+     * Return Object.prototype - used by "allocate"
+     * @return Object.prototype
+     */
+    protected abstract ScriptObject getObjectPrototype();
+
+    /**
+     * Creates a version of this function bound to a specific "self" and other arguments, as per
+     * {@code Function.prototype.bind} functionality in ECMAScript 5.1 section 15.3.4.5.
+     * @param self the self to bind to this function. Can be null (in which case, null is bound as this).
+     * @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments.
+     * @return a function with the specified self and parameters bound.
+     */
+    protected ScriptFunction makeBoundFunction(final Object self, final Object[] args) {
+        return makeBoundFunction(data.makeBoundFunctionData(this, self, args));
+    }
+
+    /**
+     * Create a version of this function as in {@link ScriptFunction#makeBoundFunction(Object, Object[])},
+     * but using a {@link ScriptFunctionData} for the bound data.
+     *
+     * @param boundData ScriptFuntionData for the bound function
+     * @return a function with the bindings performed according to the given data
+     */
+    protected abstract ScriptFunction makeBoundFunction(ScriptFunctionData boundData);
+
+    @Override
+    public final String safeToString() {
+        return toSource();
+    }
+
+    @Override
+    public String toString() {
+        return data.toString();
+    }
+
+    /**
+     * Get this function as a String containing its source code. If no source code
+     * exists in this ScriptFunction, its contents will be displayed as {@code [native code]}
+     * @return string representation of this function's source
+     */
+    public final String toSource() {
+        return data.toSource();
+    }
+
+    /**
+     * Get the prototype object for this function
+     * @return prototype
+     */
+    public final Object getPrototype() {
+        return prototype;
+    }
+
+    /**
+     * Set the prototype object for this function
+     * @param prototype new prototype object
+     * @return the prototype parameter
+     */
+    public final Object setPrototype(final Object prototype) {
+        this.prototype = prototype;
+        return prototype;
+    }
+
+    /**
+     * Return the most appropriate invoke handle if there are specializations
+     * @param type most specific method type to look for invocation with
+     * @return invoke method handle
+     */
+    private final MethodHandle getBestInvoker(final MethodType type) {
+        return data.getBestInvoker(type);
+    }
+
+    /**
+     * Get the invoke handle - the most generic (and if no specializations are in place, only) invocation
+     * method handle for this ScriptFunction
+     * @see SpecializedFunction
+     * @return invokeHandle
+     */
+    public final MethodHandle getInvokeHandle() {
+        return data.getInvoker();
+    }
+
+    /**
+     * Return the invoke handle bound to a given ScriptObject self reference.
+     * If callee parameter is required result is rebound to this.
+     *
+     * @param self self reference
+     * @return bound invoke handle
+     */
+    public final MethodHandle getBoundInvokeHandle(final ScriptObject self) {
+        return MH.bindTo(bindToCalleeIfNeeded(getInvokeHandle()), self);
+    }
+
+    /**
+     * Bind the method handle to this {@code ScriptFunction} instance if it needs a callee parameter. If this function's
+     * method handles don't have a callee parameter, the handle is returned unchanged.
+     * @param methodHandle the method handle to potentially bind to this function instance.
+     * @return the potentially bound method handle
+     */
+    private MethodHandle bindToCalleeIfNeeded(final MethodHandle methodHandle) {
+        return data.needsCallee() ? MH.bindTo(methodHandle, this) : methodHandle;
+    }
+
+    /**
+     * Get the name for this function
+     * @return the name
+     */
+    public final String getName() {
+        return data.getName();
+    }
+
+    /**
+     * Does this script function need to be compiled. This determined by
+     * null checking invokeHandle
+     *
+     * @return true if this needs compilation
+     */
+    public final boolean needsCompilation() {
+        return data.getInvoker() == null;
+    }
+
+    /**
+     * Get the scope for this function
+     * @return the scope
+     */
+    public final ScriptObject getScope() {
+        return scope;
+    }
+
+    /**
+     * Reset the invoker handle. This is used by trampolines for
+     * lazy code generation
+     * @param invoker new invoker
+     */
+    protected void resetInvoker(final MethodHandle invoker) {
+        data.resetInvoker(invoker);
+    }
+
+    /**
+     * Prototype getter for this ScriptFunction - follows the naming convention
+     * used by Nasgen and the code generator
+     *
+     * @param self  self reference
+     * @return self's prototype
+     */
+    public static Object G$prototype(final Object self) {
+        return (self instanceof ScriptFunction) ?
+            ((ScriptFunction)self).getPrototype() :
+            UNDEFINED;
+    }
+
+    /**
+     * Prototype setter for this ScriptFunction - follows the naming convention
+     * used by Nasgen and the code generator
+     *
+     * @param self  self reference
+     * @param prototype prototype to set
+     */
+    public static void S$prototype(final Object self, final Object prototype) {
+        if (self instanceof ScriptFunction) {
+            ((ScriptFunction)self).setPrototype(prototype);
+        }
+    }
+
+    /**
+     * Length getter - ECMA 15.3.3.2: Function.length
+     * @param self self reference
+     * @return length
+     */
+    public static int G$length(final Object self) {
+        if (self instanceof ScriptFunction) {
+            return ((ScriptFunction)self).data.getArity();
+        }
+
+        return 0;
+    }
+
+    /**
+     * Name getter - ECMA Function.name
+     * @param self self refence
+     * @return the name, or undefined if none
+     */
+    public static Object G$name(final Object self) {
+        if (self instanceof ScriptFunction) {
+            return ((ScriptFunction)self).getName();
+        }
+
+        return UNDEFINED;
+    }
+
+    /**
+     * Get the prototype for this ScriptFunction
+     * @param constructor constructor
+     * @return prototype, or null if given constructor is not a ScriptFunction
+     */
+    public static ScriptObject getPrototype(final Object constructor) {
+        if (constructor instanceof ScriptFunction) {
+            final Object proto = ((ScriptFunction)constructor).getPrototype();
+            if (proto instanceof ScriptObject) {
+                return (ScriptObject)proto;
+            }
+        }
+
+        return null;
+    }
+
+    // These counters are updated only in debug mode.
+    private static int constructorCount;
+    private static int invokes;
+    private static int allocations;
+
+    /**
+     * @return the constructorCount
+     */
+    public static int getConstructorCount() {
+        return constructorCount;
+    }
+
+    /**
+     * @return the invokes
+     */
+    public static int getInvokes() {
+        return invokes;
+    }
+
+    /**
+     * @return the allocations
+     */
+    public static int getAllocations() {
+        return allocations;
+    }
+
+    @Override
+    protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
+        final MethodType type = desc.getMethodType();
+        return new GuardedInvocation(pairArguments(data.getBestConstructor(type), type), null, NashornGuards.getFunctionGuard(this));
+    }
+
+    @SuppressWarnings("unused")
+    private static Object wrapFilter(final Object obj) {
+        if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) {
+            return obj;
+        }
+        return ((GlobalObject) Context.getGlobalTrusted()).wrapAsObject(obj);
+    }
+
+    /**
+     * dyn:call call site signature: (callee, thiz, [args...])
+     * generated method signature:   (callee, thiz, [args...])
+     *
+     * cases:
+     * (a) method has callee parameter
+     *   (1) for local/scope calls, we just bind thiz and drop the second argument.
+     *   (2) for normal this-calls, we have to swap thiz and callee to get matching signatures.
+     * (b) method doesn't have callee parameter (builtin functions)
+     *   (3) for local/scope calls, bind thiz and drop both callee and thiz.
+     *   (4) for normal this-calls, drop callee.
+     */
+    @Override
+    protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        final MethodType type = desc.getMethodType();
+
+        if (request.isCallSiteUnstable()) {
+            // (this, callee, args...) => (this, callee, args[])
+            final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class,
+                    type.parameterCount() - 2);
+
+            // If call site is statically typed to take a ScriptFunction, we don't need a guard, otherwise we need a
+            // generic "is this a ScriptFunction?" guard.
+            return new GuardedInvocation(collector, ScriptFunction.class.isAssignableFrom(desc.getMethodType().parameterType(0))
+                    ? null : NashornGuards.getScriptFunctionGuard());
+        }
+
+        MethodHandle boundHandle;
+        MethodHandle guard = null;
+
+        if (data.needsCallee()) {
+            final MethodHandle callHandle = getBestInvoker(type);
+
+            if (NashornCallSiteDescriptor.isScope(desc)) {
+                // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
+                // (callee, this, args...) => (callee, args...)
+                boundHandle = MH.insertArguments(callHandle, 1, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
+                // (callee, args...) => (callee, [this], args...)
+                boundHandle = MH.dropArguments(boundHandle, 1, Object.class);
+            } else {
+                // It's already (callee, this, args...), just what we need
+                boundHandle = callHandle;
+
+                // For non-strict functions, check whether this-object is primitive type.
+                // If so add a to-object-wrapper argument filter.
+                // Else install a guard that will trigger a relink when the argument becomes primitive.
+                if (needsWrappedThis()) {
+                    if (ScriptFunctionData.isPrimitiveThis(request.getArguments()[1])) {
+                        boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER);
+                    } else {
+                        guard = NashornGuards.getNonStrictFunctionGuard(this);
+                    }
+                }
+            }
+        } else {
+            final MethodHandle callHandle = getBestInvoker(type.dropParameterTypes(0, 1));
+
+            if (NashornCallSiteDescriptor.isScope(desc)) {
+                // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
+                // (this, args...) => (args...)
+                boundHandle = MH.bindTo(callHandle, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
+                // (args...) => ([callee], [this], args...)
+                boundHandle = MH.dropArguments(boundHandle, 0, Object.class, Object.class);
+            } else {
+                // (this, args...) => ([callee], this, args...)
+                boundHandle = MH.dropArguments(callHandle, 0, Object.class);
+            }
+        }
+
+        boundHandle = pairArguments(boundHandle, type);
+        return new GuardedInvocation(boundHandle, guard == null ? NashornGuards.getFunctionGuard(this) : guard);
+   }
+
+    /**
+     * Used for noSuchMethod/noSuchProperty and JSAdapter hooks.
+     *
+     * These don't want a callee parameter, so bind that. Name binding is optional.
+     */
+    MethodHandle getCallMethodHandle(final MethodType type, final String bindName) {
+        return pairArguments(bindToNameIfNeeded(bindToCalleeIfNeeded(getBestInvoker(type)), bindName), type);
+    }
+
+    private static MethodHandle bindToNameIfNeeded(final MethodHandle methodHandle, final String bindName) {
+        return bindName == null ? methodHandle : MH.insertArguments(methodHandle, 1, bindName);
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        final Class<?>   own = ScriptFunction.class;
+        final MethodType mt  = MH.type(rtype, types);
+        try {
+            return MH.findStatic(MethodHandles.lookup(), own, name, mt);
+        } catch (final MethodHandleFactory.LookupException e) {
+            return MH.findVirtual(MethodHandles.lookup(), own, name, mt);
+        }
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
new file mode 100644
index 0000000..8f8193e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
@@ -0,0 +1,824 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.parser.TokenType;
+
+/**
+ * A container for data needed to instantiate a specific {@link ScriptFunction} at runtime.
+ * Instances of this class are created during codegen and stored in script classes'
+ * constants array to reduce function instantiation overhead during runtime.
+ */
+public final class ScriptFunctionData {
+    private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class);
+    private static final MethodHandle NEWFILTER     = findOwnMH("newFilter", Object.class, Object.class, Object.class);
+
+    // per-function object flags
+    private static final int IS_STRICT      = 0b0000_0001;
+    private static final int IS_BUILTIN     = 0b0000_0010;
+    private static final int HAS_CALLEE     = 0b0000_0100;
+    private static final int IS_VARARGS     = 0b0000_1000;
+    private static final int IS_CONSTRUCTOR = 0b0001_0000;
+
+    /** Name of the function or "" */
+    private final String name;
+    /** Source of this function, or null */
+    private final Source source;
+    /** Map for new instance constructor */
+    private PropertyMap  allocatorMap;
+    /** Start position and length in source */
+    private final long   token;
+    /** Number of expected arguments, either taken from FunctionNode or calculated from method handle signature*/
+    private int          arity;
+    private final int    flags;
+
+    /** Reference to code for this method. */
+    private MethodHandle invoker;
+    /** Reference to code for this method when called to create "new" object. This must always be populated with a
+     * result of calling {@link #composeConstructor(MethodHandle)} on the value of the {@link #invoker} field. */
+    private MethodHandle constructor;
+    /** Constructor to create a new instance. */
+    private MethodHandle allocator;
+    /** Generic invoker to used in {@link ScriptFunction#invoke(Object, Object...)}. */
+    private MethodHandle genericInvoker;
+    /** Specializations - see @SpecializedFunction */
+    private MethodHandle[] invokeSpecializations;
+    /** Specializations - see @SpecializedFunction. Same restrictions as for {@link #constructor} apply; only populate
+     * with method handles returned from {@link #composeConstructor(MethodHandle)}. */
+    private MethodHandle[] constructSpecializations;
+
+    /**
+     * Constructor
+     * @param fn the function node
+     * @param allocatorMap the allocator property map
+     */
+    public ScriptFunctionData(final FunctionNode fn, final PropertyMap allocatorMap) {
+
+        final long firstToken = fn.getFirstToken();
+        final long lastToken  = fn.getLastToken();
+        final int  position   = Token.descPosition(firstToken);
+        final int  length     = Token.descPosition(lastToken) - position + Token.descLength(lastToken);
+
+        this.name         = fn.isAnonymous() ? "" : fn.getIdent().getName();
+        this.source       = fn.getSource();
+        this.allocatorMap = allocatorMap;
+        this.token        = Token.toDesc(TokenType.FUNCTION, position, length);
+        this.arity        = fn.getParameters().size();
+        this.flags        = makeFlags(fn.needsCallee(), fn.isVarArg(), fn.isStrictMode(), false, true);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param name the function name
+     * @param methodHandle the method handle
+     * @param specs array of specialized method handles
+     * @param strict strict flag
+     * @param builtin builtin flag
+     * @param isConstructor constructor flags
+     */
+    public ScriptFunctionData(final String name, final MethodHandle methodHandle, final MethodHandle[] specs, final boolean strict, final boolean builtin, final boolean isConstructor) {
+        this(name, null, 0L, methodHandle, specs, strict, builtin, isConstructor);
+    }
+
+    private ScriptFunctionData(final String name, final Source source, final long token, final MethodHandle methodHandle, final MethodHandle[] specs, final boolean strict, final boolean builtin, final boolean isConstructor) {
+        this.name   = name;
+        this.source = source;
+        this.token  = token;
+
+        final boolean isVarArg = isVarArg(methodHandle);
+        final boolean needsCallee = needsCallee(methodHandle);
+
+        this.flags = makeFlags(needsCallee, isVarArg, strict, builtin, isConstructor);
+        int lArity = isVarArg ? -1 : methodHandle.type().parameterCount() - 1; //drop the self param for arity
+
+        if (needsCallee && !isVarArg) {
+            lArity--;
+        }
+
+        if (isConstructor(methodHandle)) {
+            assert isConstructor;
+            if (!isVarArg) {
+                lArity--;    // drop the boolean flag for arity
+            }
+            /*
+             * We insert a boolean argument to tell if the method was invoked as constructor or not if the method
+             * handle's first argument is boolean.
+             */
+            this.invoker     = MH.insertArguments(methodHandle, 0, false);
+            this.constructor = composeConstructor(MH.insertArguments(methodHandle, 0, true));
+
+            if (specs != null) {
+                this.invokeSpecializations    = new MethodHandle[specs.length];
+                this.constructSpecializations = new MethodHandle[specs.length];
+                for (int i = 0; i < specs.length; i++) {
+                    this.invokeSpecializations[i]    = MH.insertArguments(specs[i], 0, false);
+                    this.constructSpecializations[i] = composeConstructor(MH.insertArguments(specs[i], 0, true));
+                }
+            }
+        } else {
+            this.invoker                  = methodHandle;
+            this.constructor              = null; // delay composition of the constructor
+            this.invokeSpecializations    = specs;
+            this.constructSpecializations = null; // delay composition of the constructors
+        }
+        this.arity = lArity;
+    }
+
+    /**
+     * Get the arity of the function.
+     * @return the arity
+     */
+    int getArity() {
+        return arity;
+    }
+
+    /**
+     * Set the arity of the function.
+     * @param arity the arity
+     */
+    void setArity(int arity) {
+        this.arity = arity;
+    }
+
+    /**
+     * Get the function name.
+     * @return function name
+     */
+    String getName() {
+        return name;
+    }
+
+    /**
+     * Get this function as a String containing its source code. If no source code
+     * exists in this ScriptFunction, its contents will be displayed as {@code [native code]}
+     * @return string representation of this function's source
+     */
+    String toSource() {
+        if (source != null && token != 0) {
+            return source.getString(Token.descPosition(token), Token.descLength(token));
+        }
+
+        return "function " + (name == null ? "" : name) + "() { [native code] }";
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+
+        sb.append(super.toString())
+                .append(" [ ")
+                .append(invoker)
+                .append(", ")
+                .append((name == null || name.isEmpty()) ? "<anonymous>" : name);
+
+        if (source != null) {
+            sb.append(" @ ")
+                    .append(source.getName())
+                    .append(':')
+                    .append(source.getLine(Token.descPosition(token)));
+        }
+        sb.append(" ]");
+
+        return sb.toString();
+    }
+
+    /**
+     * Returns true if the function needs a callee argument.
+     * @return the needsCallee flag
+     */
+    boolean needsCallee() {
+        return (flags & HAS_CALLEE) != 0;
+    }
+
+    /**
+     * Returns true if this is a strict-mode function.
+     * @return the strict flag
+     */
+    public boolean isStrict() {
+        return (flags & IS_STRICT) != 0;
+    }
+
+    /**
+     * Returns true if this is a built-in function.
+     * @return the built-in flag
+     */
+    private boolean isBuiltin() {
+        return (flags & IS_BUILTIN) != 0;
+    }
+
+    /**
+     * Returns true if this function can be used as a constructor.
+     * @return the constructor flag
+     */
+    private boolean isConstructor() {
+        return (flags & IS_CONSTRUCTOR) != 0;
+    }
+
+    /**
+     * Returns true if this is a var-arg function.
+     * @return the var-arg flag
+     */
+    private boolean isVarArg() {
+        return (flags & IS_VARARGS) != 0;
+    }
+
+    /**
+     * Returns true if this is a non-strict, non-built-in function that requires non-primitive this argument
+     * according to ECMA 10.4.3.
+     * @return true if this argument must be an object
+     */
+    boolean needsWrappedThis() {
+        return (flags & (IS_STRICT | IS_BUILTIN)) == 0;
+    }
+
+    /**
+     * Get the method handle used to invoke this function.
+     * @return the invoke handle
+     */
+    MethodHandle getInvoker() {
+        return invoker;
+    }
+
+    MethodHandle getBestInvoker(final MethodType type) {
+        return SpecializedMethodChooser.candidateWithLowestWeight(type, invoker, invokeSpecializations);
+    }
+
+    /**
+     * Get the method handle used to invoke this function as a constructor.
+     * @return the constructor handle
+     */
+    private MethodHandle getConstructor() {
+        if (constructor == null) {
+            constructor = composeConstructor(invoker);
+        }
+
+        return constructor;
+    }
+
+    MethodHandle getBestConstructor(MethodType descType) {
+        if (!isConstructor()) {
+            throw typeError("not.a.constructor", toSource());
+        }
+        return SpecializedMethodChooser.candidateWithLowestWeight(descType, getConstructor(), getConstructSpecializations());
+    }
+
+    private MethodHandle composeConstructor(MethodHandle ctor) {
+        // If it was (callee, this, args...), permute it to (this, callee, args...). We're doing this because having
+        // "this" in the first argument position is what allows the elegant folded composition of
+        // (newFilter x constructor x allocator) further down below in the code. Also, ensure the composite constructor
+        // always returns Object.
+        MethodHandle composedCtor = changeReturnTypeToObject(swapCalleeAndThis(ctor));
+
+        final MethodType ctorType = composedCtor.type();
+        // Construct a dropping type list for NEWFILTER, but don't include constructor "this" into it, so it's actually
+        // captured as "allocation" parameter of NEWFILTER after we fold the constructor into it.
+        // (this, [callee, ]args...) => ([callee, ]args...)
+        final Class<?>[] ctorArgs = ctorType.dropParameterTypes(0, 1).parameterArray();
+        // Fold constructor into newFilter that replaces the return value from the constructor with the originally
+        // allocated value when the originally allocated value is a primitive.
+        // (result, this, [callee, ]args...) x (this, [callee, ]args...) => (this, [callee, ]args...)
+        composedCtor = MH.foldArguments(MH.dropArguments(NEWFILTER, 2, ctorArgs), composedCtor);
+
+        // allocate() takes a ScriptFunction and returns a newly allocated ScriptObject...
+        if (needsCallee()) {
+            // ...we either fold it into the previous composition, if we need both the ScriptFunction callee object and
+            // the newly allocated object in the arguments, so (this, callee, args...) x (callee) => (callee, args...),
+            // or...
+            return MH.foldArguments(composedCtor, ScriptFunction.ALLOCATE);
+        }
+        // ...replace the ScriptFunction argument with the newly allocated object, if it doesn't need the callee
+        // (this, args...) filter (callee) => (callee, args...)
+        return MH.filterArguments(composedCtor, 0, ScriptFunction.ALLOCATE);
+    }
+
+    /**
+     * Get an adapted version of the invoker handle that only uses {@code Object} as parameter and return types.
+     * @return the generic invoke handle
+     */
+    private MethodHandle getGenericInvoker() {
+        if (genericInvoker == null) {
+            assert invoker != null : "invoker is null";
+            genericInvoker = makeGenericMethod(invoker);
+        }
+        return genericInvoker;
+    }
+
+    /**
+     * Execute this script function.
+     * @param self  Target object.
+     * @param arguments  Call arguments.
+     * @return ScriptFunction result.
+     * @throws Throwable if there is an exception/error with the invocation or thrown from it
+     */
+    Object invoke(final ScriptFunction fn, final Object self, final Object... arguments) throws Throwable {
+        final MethodHandle genInvoker = getGenericInvoker();
+        final Object selfObj = convertThisObject(self);
+        final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments;
+
+        if (isVarArg()) {
+            if (needsCallee()) {
+                return genInvoker.invokeExact(fn, selfObj, args);
+            }
+            return genInvoker.invokeExact(selfObj, args);
+        }
+
+        final int paramCount = genInvoker.type().parameterCount();
+        if (needsCallee()) {
+            switch (paramCount) {
+            case 2:
+                return genInvoker.invokeExact(fn, selfObj);
+            case 3:
+                return genInvoker.invokeExact(fn, selfObj, getArg(args, 0));
+            case 4:
+                return genInvoker.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1));
+            case 5:
+                return genInvoker.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2));
+            default:
+                return genInvoker.invokeWithArguments(withArguments(fn, selfObj, paramCount, args));
+            }
+        }
+
+        switch (paramCount) {
+        case 1:
+            return genInvoker.invokeExact(selfObj);
+        case 2:
+            return genInvoker.invokeExact(selfObj, getArg(args, 0));
+        case 3:
+            return genInvoker.invokeExact(selfObj, getArg(args, 0), getArg(args, 1));
+        case 4:
+            return genInvoker.invokeExact(selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2));
+        default:
+            return genInvoker.invokeWithArguments(withArguments(null, selfObj, paramCount, args));
+        }
+    }
+
+    private static Object getArg(final Object[] args, final int i) {
+        return i < args.length ? args[i] : UNDEFINED;
+    }
+
+    private Object[] withArguments(final ScriptFunction fn, final Object self, final int argCount, final Object[] args) {
+        final Object[] finalArgs = new Object[argCount];
+
+        int nextArg = 0;
+        if (needsCallee()) {
+            assert fn != null;
+            finalArgs[nextArg++] = fn;
+        } else {
+            assert fn == null;
+        }
+        finalArgs[nextArg++] = self;
+
+        // Don't add more args that there is argCount in the handle (including self and callee).
+        for (int i = 0; i < args.length && nextArg < argCount;) {
+            finalArgs[nextArg++] = args[i++];
+        }
+
+        // If we have fewer args than argCount, pad with undefined.
+        while (nextArg < argCount) {
+            finalArgs[nextArg++] = UNDEFINED;
+        }
+
+        return finalArgs;
+    }
+
+    /**
+     * Get the specialized construct handles for this function.
+     * @return array of specialized construct handles
+     */
+    private MethodHandle[] getConstructSpecializations() {
+        if(constructSpecializations == null && invokeSpecializations != null) {
+            final MethodHandle[] ctors = new MethodHandle[invokeSpecializations.length];
+            for(int i = 0; i < ctors.length; ++i) {
+                ctors[i] = composeConstructor(invokeSpecializations[i]);
+            }
+            constructSpecializations = ctors;
+        }
+        return constructSpecializations;
+    }
+
+    /**
+     * Set the method handles for this function.
+     * @param invoker the invoker handle
+     * @param allocator the allocator handle
+     */
+    public void setMethodHandles(final MethodHandle invoker, final MethodHandle allocator) {
+        // We can't make method handle fields final because they're not available during codegen
+        // and they're set when first called, so we enforce set-once here.
+        if (this.invoker == null) {
+            this.invoker     = invoker;
+            this.constructor = null; // delay constructor composition
+            this.allocator   = allocator;
+        }
+    }
+
+    /**
+     * Used by the trampoline. Must not be any wider than package
+     * private
+     * @param invoker new invoker
+     */
+    void resetInvoker(final MethodHandle invoker) {
+        this.invoker     = invoker;
+        this.constructor = null; //delay constructor composition
+    }
+
+    /**
+     * Allocates an object using this function's allocator.
+     * @return the object allocated using this function's allocator, or null if the function doesn't have an allocator.
+     */
+    ScriptObject allocate() {
+        if (allocator == null) {
+            return null;
+        }
+
+        try {
+            return (ScriptObject)allocator.invokeExact(allocatorMap);
+        } catch (final RuntimeException | Error e) {
+            throw e;
+        } catch (final Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    /**
+     * This method is used to create the immutable portion of a bound function.
+     * See {@link ScriptFunction#makeBoundFunction(Object, Object[])}
+     *
+     * @param fn the original function being bound
+     * @param self this reference to bind. Can be null.
+     * @param args additional arguments to bind. Can be null.
+     */
+    ScriptFunctionData makeBoundFunctionData(final ScriptFunction fn, final Object self, final Object[] args) {
+        final Object[] allArgs = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
+
+        final boolean isConstructor = isConstructor();
+        // Note that the new ScriptFunctionData's method handle will not need a callee regardless of whether the
+        // original did.
+        final ScriptFunctionData boundData = new ScriptFunctionData(name, source, token,
+                bindInvokeHandle(invoker, fn, self, allArgs), bindInvokeSpecializations(fn, self, allArgs), isStrict(), isBuiltin(), isConstructor);
+        if(isConstructor) {
+            // Can't just rely on bound invoke as a basis for constructor, as it ignores the passed "this" in favor of the
+            // bound "this"; constructor on the other hand must see the actual "this" received from the allocator.
+
+            // Binding a function will force constructor composition in getConstructor(); not really any way around that
+            // as it's the composed constructor that has to be bound to the function.
+            boundData.constructor = bindConstructHandle(getConstructor(), fn, allArgs);
+            boundData.constructSpecializations = bindConstructorSpecializations(fn, allArgs);
+        }
+        assert boundData.allocator == null;
+        final int thisArity = getArity();
+        if(thisArity != -1) {
+            boundData.setArity(Math.max(0, thisArity - args.length));
+        } else {
+            assert boundData.getArity() == -1;
+        }
+        return boundData;
+    }
+
+    /**
+     * Convert this argument for non-strict functions according to ES 10.4.3
+     *
+     * @param thiz the this argument
+     *
+     * @return the converted this object
+     */
+    Object convertThisObject(final Object thiz) {
+        if (!(thiz instanceof ScriptObject) && needsWrappedThis()) {
+            if (JSType.nullOrUndefined(thiz)) {
+                return Context.getGlobalTrusted();
+            }
+
+            if (isPrimitiveThis(thiz)) {
+                return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(thiz);
+            }
+        }
+
+        return thiz;
+    }
+
+    static boolean isPrimitiveThis(Object obj) {
+        return obj instanceof String || obj instanceof ConsString ||
+               obj instanceof Number || obj instanceof Boolean;
+    }
+
+    /**
+     * Creates an invoker method handle for a bound function.
+     * @param targetFn the function being bound
+     * @param originalInvoker an original invoker method handle for the function. This can be its generic invoker or
+     * any of its specializations.
+     * @param self the "this" value being bound
+     * @param args additional arguments being bound
+     * @return a bound invoker method handle that will bind the self value and the specified arguments. The resulting
+     * invoker never needs a callee; if the original invoker needed it, it will be bound to {@code fn}. The resulting
+     * invoker still takes an initial {@code this} parameter, but it is always dropped and the bound {@code self} passed
+     * to the original invoker on invocation.
+     */
+    private MethodHandle bindInvokeHandle(final MethodHandle originalInvoker, final ScriptFunction targetFn, final Object self, final Object[] args) {
+        // Is the target already bound? If it is, we won't bother binding either callee or self as they're already bound
+        // in the target and will be ignored anyway.
+        final boolean isTargetBound = targetFn.isBoundFunction();
+        assert !(isTargetBound && needsCallee()); // already bound functions don't need a callee
+        final Object boundSelf = isTargetBound ? null : convertThisObject(self);
+        final MethodHandle boundInvoker;
+        if(isVarArg(originalInvoker)) {
+            // First, bind callee and this without arguments
+            final MethodHandle noArgBoundInvoker;
+            if(isTargetBound) {
+                // Don't bind either callee or this
+                noArgBoundInvoker = originalInvoker;
+            } else if(needsCallee()) {
+                // Bind callee and this
+                noArgBoundInvoker = MH.insertArguments(originalInvoker, 0, targetFn, boundSelf);
+            } else {
+                // Only bind this
+                noArgBoundInvoker = MH.bindTo(originalInvoker, boundSelf);
+            }
+            // Now bind arguments
+            if(args.length > 0) {
+                boundInvoker = varArgBinder(noArgBoundInvoker, args);
+            } else {
+                boundInvoker = noArgBoundInvoker;
+            }
+        } else {
+            final Object[] boundArgs = new Object[Math.min(originalInvoker.type().parameterCount(),
+                    args.length + (isTargetBound ? 0 : (needsCallee() ? 2 : 1)))];
+            int next = 0;
+            if(!isTargetBound) {
+                if(needsCallee()) {
+                    boundArgs[next++] = targetFn;
+                }
+                boundArgs[next++] = boundSelf;
+            }
+            // If more bound args were specified than the function can take, we'll just drop those.
+            System.arraycopy(args, 0, boundArgs, next, boundArgs.length - next);
+            // If target is already bound, insert additional bound arguments after "this" argument, at position 1;
+            // "this" will get dropped anyway by the target invoker. We previously asserted that already bound functions
+            // don't take a callee parameter, so we can know that the signature is (this[, args...]) therefore args
+            // start at position 1. If the function is not bound, we start inserting arguments at position 0.
+            boundInvoker = MH.insertArguments(originalInvoker, isTargetBound ? 1 : 0, boundArgs);
+        }
+        if(isTargetBound) {
+            return boundInvoker;
+        }
+        // If the target is not already bound, add a dropArguments that'll throw away the passed this
+        return MH.dropArguments(boundInvoker, 0, Object.class);
+    }
+
+    private MethodHandle[] bindInvokeSpecializations(final ScriptFunction fn, final Object self, final Object[] args) {
+        if(invokeSpecializations == null) {
+            return null;
+        }
+        final MethodHandle[] boundSpecializations = new MethodHandle[invokeSpecializations.length];
+        for(int i = 0; i < invokeSpecializations.length; ++i) {
+            boundSpecializations[i] = bindInvokeHandle(invokeSpecializations[i], fn, self, args);
+        }
+        return boundSpecializations;
+    }
+
+    /**
+     * Creates a constructor method handle for a bound function using the passed constructor handle.
+     * @param originalConstructor the constructor handle to bind. It must be a composed constructor.
+     * @param fn the function being bound
+     * @param args arguments being bound
+     * @return a bound constructor method handle that will bind the specified arguments. The resulting constructor never
+     * needs a callee; if the original constructor needed it, it will be bound to {@code fn}. The resulting constructor
+     * still takes an initial {@code this} parameter and passes it to the underlying original constructor. Finally, if
+     * this script function data object has no constructor handle, null is returned.
+     */
+    private static MethodHandle bindConstructHandle(final MethodHandle originalConstructor, final ScriptFunction fn, final Object[] args) {
+        if(originalConstructor == null) {
+            return null;
+        }
+
+        // If target function is already bound, don't bother binding the callee.
+        final MethodHandle calleeBoundConstructor = fn.isBoundFunction() ? originalConstructor :
+            MH.dropArguments(MH.bindTo(originalConstructor, fn), 0, ScriptFunction.class);
+        if(args.length == 0) {
+            return calleeBoundConstructor;
+        }
+
+        if(isVarArg(calleeBoundConstructor)) {
+            return varArgBinder(calleeBoundConstructor, args);
+        }
+
+        final Object[] boundArgs;
+        final int maxArgCount = calleeBoundConstructor.type().parameterCount() - 1;
+        if (args.length <= maxArgCount) {
+            boundArgs = args;
+        } else {
+            boundArgs = new Object[maxArgCount];
+            System.arraycopy(args, 0, boundArgs, 0, maxArgCount);
+        }
+        return MH.insertArguments(calleeBoundConstructor, 1, boundArgs);
+    }
+
+    private MethodHandle[] bindConstructorSpecializations(final ScriptFunction fn, final Object[] args) {
+        final MethodHandle[] ctorSpecs = getConstructSpecializations();
+        if(ctorSpecs == null) {
+            return null;
+        }
+        final MethodHandle[] boundSpecializations = new MethodHandle[ctorSpecs.length];
+        for(int i = 0; i < ctorSpecs.length; ++i) {
+            boundSpecializations[i] = bindConstructHandle(ctorSpecs[i], fn, args);
+        }
+        return boundSpecializations;
+    }
+
+    /**
+     * Takes a variable-arity method and binds a variable number of arguments in it. The returned method will filter the
+     * vararg array and pass a different array that prepends the bound arguments in front of the arguments passed on
+     * invocation
+     * @param mh the handle
+     * @param args the bound arguments
+     * @return the bound method handle
+     */
+    private static MethodHandle varArgBinder(final MethodHandle mh, final Object[] args) {
+        assert args != null;
+        assert args.length > 0;
+        return MH.filterArguments(mh, mh.type().parameterCount() - 1, MH.bindTo(BIND_VAR_ARGS, args));
+    }
+
+    /**
+     * Convert boolean flags to int.
+     * @param needsCallee needs-callee flag
+     * @param isVarArg var-arg flag
+     * @param isStrict strict flag
+     * @param isBuiltin builtin flag
+     * @return int flags
+     */
+    private static int makeFlags(final boolean needsCallee, final boolean isVarArg, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
+        int flags = 0;
+        if (needsCallee) {
+            flags |= HAS_CALLEE;
+        }
+        if (isVarArg) {
+            flags |= IS_VARARGS;
+        }
+        if (isStrict) {
+            flags |= IS_STRICT;
+        }
+        if (isBuiltin) {
+            flags |= IS_BUILTIN;
+        }
+        if (isConstructor) {
+            flags |= IS_CONSTRUCTOR;
+        }
+
+        return flags;
+    }
+
+    /**
+     * Test if a methodHandle refers to a constructor.
+     * @param methodHandle MethodHandle to test.
+     * @return True if method is a constructor.
+     */
+    private static boolean isConstructor(final MethodHandle methodHandle) {
+        return methodHandle.type().parameterCount() >= 1 && methodHandle.type().parameterType(0) == boolean.class;
+    }
+
+    /**
+     * Heuristic to figure out if the method handle has a callee argument. If it's type is either
+     * {@code (boolean, Object, ScriptFunction, ...)} or {@code (Object, ScriptFunction, ...)}, then we'll assume it has
+     * a callee argument. We need this as the constructor above is not passed this information, and can't just blindly
+     * assume it's false (notably, it's being invoked for creation of new scripts, and scripts have scopes, therefore
+     * they also always receive a callee.
+     * @param methodHandle the examined method handle
+     * @return true if the method handle expects a callee, false otherwise
+     */
+    private static boolean needsCallee(MethodHandle methodHandle) {
+        final MethodType type = methodHandle.type();
+        final int len = type.parameterCount();
+        if(len == 0) {
+            return false;
+        }
+        if(type.parameterType(0) == boolean.class) {
+            return len > 1 && type.parameterType(1) == ScriptFunction.class;
+        }
+        return type.parameterType(0) == ScriptFunction.class;
+    }
+
+    private static boolean isVarArg(MethodHandle methodHandle) {
+        final MethodType type = methodHandle.type();
+        return type.parameterType(type.parameterCount() - 1).isArray();
+    }
+
+    /**
+     * Takes a method handle, and returns a potentially different method handle that can be used in
+     * {@link ScriptFunction#invoke(Object, Object...)} or {@link ScriptFunction#construct(Object, Object...)}.
+     * The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
+     * {@code Object} as well, except for the following ones:
+     * <ul>
+     *   <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
+     *   <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
+     *   (callee) as an argument.</li>
+     * </ul>
+     *
+     * @param handle the original method handle
+     * @return the new handle, conforming to the rules above.
+     */
+    private MethodHandle makeGenericMethod(final MethodHandle handle) {
+        final MethodType type = handle.type();
+        MethodType newType = type.generic();
+        if (isVarArg()) {
+            newType = newType.changeParameterType(type.parameterCount() - 1, Object[].class);
+        }
+        if (needsCallee()) {
+            newType = newType.changeParameterType(0, ScriptFunction.class);
+        }
+        return type.equals(newType) ? handle : handle.asType(newType);
+    }
+
+    /**
+     * Adapts the method handle so its return type is {@code Object}. If the handle's return type is already
+     * {@code Object}, the handle is returned unchanged.
+     * @param mh the handle to adapt
+     * @return the adapted handle
+     */
+    private static MethodHandle changeReturnTypeToObject(final MethodHandle mh) {
+        return MH.asType(mh, mh.type().changeReturnType(Object.class));
+    }
+
+
+    /**
+     * If this function's method handles need a callee parameter, swap the order of first two arguments for the passed
+     * method handle. If this function's method handles don't need a callee parameter, returns the original method
+     * handle unchanged.
+     * @param mh a method handle with order of arguments {@code (callee, this, args...)}
+     * @return a method handle with order of arguments {@code (this, callee, args...)}
+     */
+    private MethodHandle swapCalleeAndThis(final MethodHandle mh) {
+        if (!needsCallee()) {
+            return mh;
+        }
+        final MethodType type = mh.type();
+        assert type.parameterType(0) == ScriptFunction.class;
+        assert type.parameterType(1) == Object.class;
+        final MethodType newType = type.changeParameterType(0, Object.class).changeParameterType(1, ScriptFunction.class);
+        final int[] reorder = new int[type.parameterCount()];
+        reorder[0] = 1;
+        assert reorder[1] == 0;
+        for (int i = 2; i < reorder.length; ++i) {
+            reorder[i] = i;
+        }
+        return MethodHandles.permuteArguments(mh, newType, reorder);
+    }
+
+    @SuppressWarnings("unused")
+    private static Object[] bindVarArgs(final Object[] array1, final Object[] array2) {
+        if(array2 == null) {
+            // Must clone it, as we can't allow the receiving method to alter the array
+            return array1.clone();
+        }
+        final int l2 = array2.length;
+        if(l2 == 0) {
+            return array1.clone();
+        }
+        final int l1 = array1.length;
+        final Object[] concat = new Object[l1 + l2];
+        System.arraycopy(array1, 0, concat, 0, l1);
+        System.arraycopy(array2, 0, concat, l1, l2);
+        return concat;
+    }
+
+    @SuppressWarnings("unused")
+    private static Object newFilter(final Object result, final Object allocation) {
+        return (result instanceof ScriptObject || !JSType.isPrimitive(result))? result : allocation;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), ScriptFunctionData.class, name, MH.type(rtype, types));
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java
new file mode 100644
index 0000000..d632166
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+import java.security.CodeSource;
+
+/**
+ * Responsible for loading script generated classes.
+ *
+ */
+final class ScriptLoader extends NashornLoader {
+    /**
+     * Constructor.
+     */
+    ScriptLoader(final StructureLoader parent, final Context context) {
+        super(parent, context);
+    }
+
+    @Override
+    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        checkPackageAccess(name);
+        return super.loadClassTrusted(name, resolve);
+    }
+
+    // package-private and private stuff below this point
+
+    /**
+     * Install a class for use by the Nashorn runtime
+     *
+     * @param name Binary name of class.
+     * @param data Class data bytes.
+     * @param cs CodeSource code source of the class bytes.
+     *
+     * @return Installed class.
+     */
+    synchronized Class<?> installClass(final String name, final byte[] data, final CodeSource cs) {
+        return defineClass(name, data, 0, data.length, cs);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
new file mode 100644
index 0000000..1942ec2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
@@ -0,0 +1,3353 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall;
+import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
+import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.GET;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.SET;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE;
+import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
+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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.objects.AccessorPropertyDescriptor;
+import jdk.nashorn.internal.objects.DataPropertyDescriptor;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+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;
+
+/**
+ * Base class for generic JavaScript objects.
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>The map is used to identify properties in the object.</li>
+ * <li>If the map is modified then it must be cloned and replaced.  This notifies
+ *     any code that made assumptions about the object that things have changed.
+ *     Ex. CallSites that have been validated must check to see if the map has
+ *     changed (or a map from a different object type) and hence relink the method
+ *     to call.</li>
+ * <li>Modifications of the map include adding/deleting attributes or changing a
+ *     function field value.</li>
+ * </ul>
+ */
+
+public abstract class ScriptObject extends PropertyListenerManager implements PropertyAccess {
+
+    /** Search fall back routine name for "no such method" */
+    static final String NO_SUCH_METHOD_NAME   = "__noSuchMethod__";
+
+    /** Search fall back routine name for "no such property" */
+    static final String NO_SUCH_PROPERTY_NAME = "__noSuchProperty__";
+
+    /** Per ScriptObject flag - is this a scope object? */
+    public static final int IS_SCOPE       = 0b0000_0001;
+
+    /** Per ScriptObject flag - is this an array object? */
+    public static final int IS_ARRAY       = 0b0000_0010;
+
+    /** Per ScriptObject flag - is this an arguments object? */
+    public static final int IS_ARGUMENTS   = 0b0000_0100;
+
+    /** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */
+    public static final int SPILL_RATE = 8;
+
+    /** Map to property information and accessor functions. Ordered by insertion. */
+    private PropertyMap map;
+
+    /** Object flags. */
+    private int flags;
+
+    /** Area for properties added to object after instantiation, see {@link SpillProperty} */
+    public Object[] spill;
+
+    /** Local embed area position 0 - used for {@link SpillProperty} before {@link ScriptObject#spill} */
+    public Object embed0;
+
+    /** Local embed area position 1 - used for {@link SpillProperty} before {@link ScriptObject#spill} */
+    public Object embed1;
+
+    /** Local embed area position 2 - used for {@link SpillProperty} before {@link ScriptObject#spill} */
+    public Object embed2;
+
+    /** Local embed area position 3 - used for {@link SpillProperty} before {@link ScriptObject#spill} */
+    public Object embed3;
+
+    /** Indexed array data. */
+    private ArrayData arrayData;
+
+    static final MethodHandle SETEMBED           = findOwnMH("setEmbed",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, int.class, Object.class, Object.class);
+    static final MethodHandle SETSPILL           = findOwnMH("setSpill",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
+    static final MethodHandle SETSPILLWITHNEW    = findOwnMH("setSpillWithNew",  void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
+    static final MethodHandle SETSPILLWITHGROW   = findOwnMH("setSpillWithGrow", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, int.class, Object.class, Object.class);
+
+    private static final MethodHandle TRUNCATINGFILTER   = findOwnMH("truncatingFilter", Object[].class, int.class, Object[].class);
+    private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
+
+    /** Method handle for getting a function argument at a given index. Used from MapCreator */
+    public static final Call GET_ARGUMENT       = virtualCall(ScriptObject.class, "getArgument", Object.class, int.class);
+
+    /** Method handle for setting a function argument at a given index. Used from MapCreator */
+    public static final Call SET_ARGUMENT       = virtualCall(ScriptObject.class, "setArgument", void.class, int.class, Object.class);
+
+    /** Method handle for getting the proto of a ScriptObject */
+    public static final Call GET_PROTO          = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);
+
+    /** Method handle for setting the proto of a ScriptObject */
+    public static final Call SET_PROTO          = virtualCallNoLookup(ScriptObject.class, "setProto", void.class, ScriptObject.class);
+
+    /** Method handle for setting the user accessors of a ScriptObject */
+    public static final Call SET_USER_ACCESSORS = virtualCall(ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
+
+    /** Method handle for getter for {@link UserAccessorProperty}, given a slot */
+    static final Call USER_ACCESSOR_GETTER = staticCall(MethodHandles.lookup(), ScriptObject.class, "userAccessorGetter", Object.class, ScriptObject.class, int.class, Object.class);
+
+    /** Method handle for setter for {@link UserAccessorProperty}, given a slot */
+    static final Call USER_ACCESSOR_SETTER = staticCall(MethodHandles.lookup(), ScriptObject.class, "userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
+
+    private static final MethodHandle INVOKE_UA_GETTER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
+            Object.class, Object.class);
+    private static final MethodHandle INVOKE_UA_SETTER = Bootstrap.createDynamicInvoker("dyn:call", void.class,
+            Object.class, Object.class, Object.class);
+
+    /**
+     * Constructor
+     */
+    public ScriptObject() {
+        this(null);
+    }
+
+    /**
+    * Constructor
+    *
+    * @param map {@link PropertyMap} used to create the initial object
+    */
+    public ScriptObject(final PropertyMap map) {
+        if (Context.DEBUG) {
+            ScriptObject.count++;
+        }
+
+        this.arrayData = ArrayData.EMPTY_ARRAY;
+
+        if (map == null) {
+            this.setMap(PropertyMap.newMap(getClass()));
+            return;
+        }
+
+        this.setMap(map);
+    }
+
+    /**
+     * Copy all properties from the source object with their receiver bound to the source.
+     * This function was known as mergeMap
+     *
+     * @param source The source object to copy from.
+     */
+    public void addBoundProperties(final ScriptObject source) {
+        PropertyMap newMap = this.getMap();
+
+        for (final Property property : source.getMap().getProperties()) {
+            final String key = property.getKey();
+
+            if (newMap.findProperty(key) == null) {
+                if (property instanceof UserAccessorProperty) {
+                    final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
+                    newMap = newMap.addProperty(prop);
+                } else {
+                    newMap = newMap.newPropertyBind((AccessorProperty)property, source);
+                }
+            }
+        }
+
+        this.setMap(newMap);
+    }
+
+    /**
+     * Bind the method handle to the specified receiver, while preserving its original type (it will just ignore the
+     * first argument in lieu of the bound argument).
+     * @param methodHandle Method handle to bind to.
+     * @param receiver     Object to bind.
+     * @return Bound method handle.
+     */
+    static MethodHandle bindTo(final MethodHandle methodHandle, final Object receiver) {
+        return MH.dropArguments(MH.bindTo(methodHandle, receiver), 0, methodHandle.type().parameterType(0));
+    }
+
+    /**
+     * Return a property iterator.
+     * @return Property iterator.
+     */
+    public Iterator<String> propertyIterator() {
+        return new KeyIterator(this);
+    }
+
+    /**
+     * Return a property value iterator.
+     * @return Property value iterator.
+     */
+    public Iterator<Object> valueIterator() {
+        return new ValueIterator(this);
+    }
+
+    /**
+     * ECMA 8.10.1 IsAccessorDescriptor ( Desc )
+     * @return true if this has a {@link AccessorPropertyDescriptor} with a getter or a setter
+     */
+    public final boolean isAccessorDescriptor() {
+        return has(GET) || has(SET);
+    }
+
+    /**
+     * ECMA 8.10.2 IsDataDescriptor ( Desc )
+     * @return true if this has a {@link DataPropertyDescriptor}, i.e. the object has a property value and is writable
+     */
+    public final boolean isDataDescriptor() {
+        return has(VALUE) || has(WRITABLE);
+    }
+
+    /**
+     * ECMA 8.10.3 IsGenericDescriptor ( Desc )
+     * @return true if this has a descriptor describing an {@link AccessorPropertyDescriptor} or {@link DataPropertyDescriptor}
+     */
+    public final boolean isGenericDescriptor() {
+        return isAccessorDescriptor() || isDataDescriptor();
+    }
+
+    /**
+      * ECMA 8.10.5 ToPropertyDescriptor ( Obj )
+      *
+      * @return property descriptor
+      */
+    public final PropertyDescriptor toPropertyDescriptor() {
+        final GlobalObject global = (GlobalObject) Context.getGlobalTrusted();
+
+        final PropertyDescriptor desc;
+        if (isDataDescriptor()) {
+            if (has(SET) || has(GET)) {
+                throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
+            }
+
+            desc = global.newDataDescriptor(UNDEFINED, false, false, false);
+        } else if (isAccessorDescriptor()) {
+            if (has(VALUE) || has(WRITABLE)) {
+                throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
+            }
+
+            desc = global.newAccessorDescriptor(UNDEFINED, UNDEFINED, false, false);
+        } else {
+            desc = global.newGenericDescriptor(false, false);
+        }
+
+        return desc.fillFrom(this);
+    }
+
+    /**
+     * ECMA 8.10.5 ToPropertyDescriptor ( Obj )
+     *
+     * @param global  global scope object
+     * @param obj object to create property descriptor from
+     *
+     * @return property descriptor
+     */
+    public static PropertyDescriptor toPropertyDescriptor(final ScriptObject global, final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).toPropertyDescriptor();
+        }
+
+        throw typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
+    }
+
+    /**
+     * ECMA 8.12.1 [[GetOwnProperty]] (P)
+     *
+     * @param key property key
+     *
+     * @return Returns the Property Descriptor of the named own property of this
+     * object, or undefined if absent.
+     */
+    public Object getOwnPropertyDescriptor(final String key) {
+        final Property property = getMap().findProperty(key);
+
+        final GlobalObject global = (GlobalObject)Context.getGlobalTrusted();
+
+        if (property != null) {
+            final ScriptFunction get   = property.getGetterFunction(this);
+            final ScriptFunction set   = property.getSetterFunction(this);
+
+            final boolean configurable = property.isConfigurable();
+            final boolean enumerable   = property.isEnumerable();
+            final boolean writable     = property.isWritable();
+
+            if (property instanceof UserAccessorProperty) {
+                return global.newAccessorDescriptor(
+                    (get != null) ?
+                        get :
+                        UNDEFINED,
+                    (set != null) ?
+                        set :
+                        UNDEFINED,
+                    configurable,
+                    enumerable);
+            }
+
+            return global.newDataDescriptor(getWithProperty(property), configurable, enumerable, writable);
+        }
+
+        final int index = getArrayIndexNoThrow(key);
+        final ArrayData array = getArray();
+
+        if (array.has(index)) {
+            return array.getDescriptor(global, index);
+        }
+
+        return UNDEFINED;
+    }
+
+    /**
+     * ECMA 8.12.2 [[GetProperty]] (P)
+     *
+     * @param key property key
+     *
+     * @return Returns the fully populated Property Descriptor of the named property
+     * of this object, or undefined if absent.
+     */
+    public Object getPropertyDescriptor(final String key) {
+        final Object res = getOwnPropertyDescriptor(key);
+
+        if (res != UNDEFINED) {
+            return res;
+        } else if (getProto() != null) {
+            return getProto().getOwnPropertyDescriptor(key);
+        } else {
+            return UNDEFINED;
+        }
+    }
+
+    /**
+     * ECMA 8.12.9 [[DefineOwnProperty]] (P, Desc, Throw)
+     *
+     * @param key the property key
+     * @param propertyDesc the property descriptor
+     * @param reject is the property extensible - true means new definitions are rejected
+     *
+     * @return true if property was successfully defined
+     */
+    public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
+        final ScriptObject       global  = Context.getGlobalTrusted();
+        final PropertyDescriptor desc    = toPropertyDescriptor(global, propertyDesc);
+        final Object             current = getOwnPropertyDescriptor(key);
+        final String             name    = JSType.toString(key);
+
+        if (current == UNDEFINED) {
+            if (isExtensible()) {
+                // add a new own property
+                addOwnProperty(key, desc);
+                return true;
+            }
+            // new property added to non-extensible object
+            if (reject) {
+                throw typeError(global, "object.non.extensible", name, ScriptRuntime.safeToString(this));
+            }
+            return false;
+        }
+        // modifying an existing property
+        final PropertyDescriptor currentDesc = (PropertyDescriptor) current;
+        final PropertyDescriptor newDesc     = desc;
+
+        if (newDesc.type() == PropertyDescriptor.GENERIC &&
+            ! newDesc.has(CONFIGURABLE) && ! newDesc.has(ENUMERABLE)) {
+            // every descriptor field is absent
+            return true;
+        }
+
+        if (currentDesc.equals(newDesc)) {
+            // every descriptor field of the new is same as the current
+            return true;
+        }
+
+        if (! currentDesc.isConfigurable()) {
+            if (newDesc.has(CONFIGURABLE) && newDesc.isConfigurable()) {
+                // not configurable can not be made configurable
+                if (reject) {
+                    throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                }
+                return false;
+            }
+
+            if (newDesc.has(ENUMERABLE) &&
+                currentDesc.isEnumerable() != newDesc.isEnumerable()) {
+                // cannot make non-enumerable as enumerable or vice-versa
+                if (reject) {
+                    throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                }
+                return false;
+            }
+        }
+
+        int propFlags = Property.mergeFlags(currentDesc, newDesc);
+        Property property = getMap().findProperty(key);
+
+        if (currentDesc.type() == PropertyDescriptor.DATA &&
+            (newDesc.type() == PropertyDescriptor.DATA || newDesc.type() == PropertyDescriptor.GENERIC)) {
+            if (! currentDesc.isConfigurable() && ! currentDesc.isWritable()) {
+                if (newDesc.has(WRITABLE) && newDesc.isWritable() ||
+                    newDesc.has(VALUE) && ! ScriptRuntime.sameValue(currentDesc.getValue(), newDesc.getValue())) {
+                    if (reject) {
+                        throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                    }
+                    return false;
+                }
+            }
+
+            final boolean newValue = newDesc.has(VALUE);
+            final Object value     = newValue? newDesc.getValue() : currentDesc.getValue();
+            if (newValue && property != null) {
+                // Temporarily clear flags.
+                property = modifyOwnProperty(property, 0);
+                set(key, value, getContext()._strict);
+            }
+
+            if (property == null) {
+                // promoting an arrayData value to actual property
+                addOwnProperty(key, propFlags, value);
+                removeArraySlot(key);
+            } else {
+                // Now set the new flags
+                modifyOwnProperty(property, propFlags);
+            }
+        } else if (currentDesc.type() == PropertyDescriptor.ACCESSOR &&
+                   (newDesc.type() == PropertyDescriptor.ACCESSOR ||
+                    newDesc.type() == PropertyDescriptor.GENERIC)) {
+            if (! currentDesc.isConfigurable()) {
+                if (newDesc.has(PropertyDescriptor.GET) && ! ScriptRuntime.sameValue(currentDesc.getGetter(), newDesc.getGetter()) ||
+                    newDesc.has(PropertyDescriptor.SET) && ! ScriptRuntime.sameValue(currentDesc.getSetter(), newDesc.getSetter())) {
+                    if (reject) {
+                        throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                    }
+                    return false;
+                }
+            }
+
+            // New set the new features.
+            modifyOwnProperty(property, propFlags,
+                                      newDesc.has(GET) ? newDesc.getGetter() : currentDesc.getGetter(),
+                                      newDesc.has(SET) ? newDesc.getSetter() : currentDesc.getSetter());
+        } else {
+            // changing descriptor type
+            if (! currentDesc.isConfigurable()) {
+                // not configurable can not be made configurable
+                if (reject) {
+                    throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+                }
+                return false;
+            }
+
+            propFlags = 0;
+
+            // Preserve only configurable and enumerable from current desc
+            // if those are not overridden in the new property descriptor.
+            boolean value = newDesc.has(CONFIGURABLE)? newDesc.isConfigurable() : currentDesc.isConfigurable();
+            if (!value) {
+                propFlags |= Property.NOT_CONFIGURABLE;
+            }
+            value = newDesc.has(ENUMERABLE)? newDesc.isEnumerable() : currentDesc.isEnumerable();
+            if (!value) {
+                propFlags |= Property.NOT_ENUMERABLE;
+            }
+
+            final int type = newDesc.type();
+            if (type == PropertyDescriptor.DATA) {
+                // get writable from the new descriptor
+                value = newDesc.has(WRITABLE) && newDesc.isWritable();
+                if (! value) {
+                    propFlags |= Property.NOT_WRITABLE;
+                }
+
+                // delete the old property
+                deleteOwnProperty(property);
+                // add new data property
+                addOwnProperty(key, propFlags, newDesc.getValue());
+            } else if (type == PropertyDescriptor.ACCESSOR) {
+                if (property == null) {
+                    addOwnProperty(key, propFlags,
+                                     newDesc.has(GET) ? newDesc.getGetter() : null,
+                                     newDesc.has(SET) ? newDesc.getSetter() : null);
+                } else {
+                    // Modify old property with the new features.
+                    modifyOwnProperty(property, propFlags,
+                                        newDesc.has(GET) ? newDesc.getGetter() : null,
+                                        newDesc.has(SET) ? newDesc.getSetter() : null);
+                }
+            }
+        }
+
+        checkIntegerKey(key);
+
+        return true;
+    }
+
+    /**
+     * Spec. mentions use of [[DefineOwnProperty]] for indexed properties in
+     * certain places (eg. Array.prototype.map, filter). We can not use ScriptObject.set
+     * method in such cases. This is because set method uses inherited setters (if any)
+     * from any object in proto chain such as Array.prototype, Object.prototype.
+     * This method directly sets a particular element value in the current object.
+     *
+     * @param index index key for property
+     * @param value value to define
+     */
+    protected final void defineOwnProperty(final int index, final Object value) {
+        if (index >= getArray().length()) {
+            // make array big enough to hold..
+            setArray(getArray().ensure(index));
+        }
+        setArray(getArray().set(index, value, false));
+    }
+
+    private void checkIntegerKey(final String key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            final ArrayData data = getArray();
+
+            if (data.has(index)) {
+                setArray(data.delete(index));
+            }
+        }
+    }
+
+    private void removeArraySlot(final String key) {
+        final int index = getArrayIndexNoThrow(key);
+        final ArrayData array = getArray();
+
+        if (array.has(index)) {
+            setArray(array.delete(index));
+        }
+    }
+
+    /**
+      * Add a new property to the object.
+      *
+      * @param key          property key
+      * @param propertyDesc property descriptor for property
+      */
+    public final void addOwnProperty(final String key, final PropertyDescriptor propertyDesc) {
+        // Already checked that there is no own property with that key.
+        PropertyDescriptor pdesc = propertyDesc;
+
+        final int propFlags = Property.toFlags(pdesc);
+
+        if (pdesc.type() == PropertyDescriptor.GENERIC) {
+            final GlobalObject global = (GlobalObject) Context.getGlobalTrusted();
+            final PropertyDescriptor dDesc = global.newDataDescriptor(UNDEFINED, false, false, false);
+
+            dDesc.fillFrom((ScriptObject)pdesc);
+            pdesc = dDesc;
+        }
+
+        final int type = pdesc.type();
+        if (type == PropertyDescriptor.DATA) {
+            addOwnProperty(key, propFlags, pdesc.getValue());
+        } else if (type == PropertyDescriptor.ACCESSOR) {
+            addOwnProperty(key, propFlags,
+                    pdesc.has(GET) ? pdesc.getGetter() : null,
+                    pdesc.has(SET) ? pdesc.getSetter() : null);
+        }
+
+        checkIntegerKey(key);
+    }
+
+    /**
+     * Low level property API (not using property descriptors)
+     * <p>
+     * Find a property in the prototype hierarchy. Note: this is final and not
+     * a good idea to override. If you have to, use
+     * {jdk.nashorn.internal.objects.NativeArray{@link #getProperty(String)} or
+     * {jdk.nashorn.internal.objects.NativeArray{@link #getPropertyDescriptor(String)} as the
+     * overriding way to find array properties
+     *
+     * @see jdk.nashorn.internal.objects.NativeArray
+     *
+     * @param key  Property key.
+     * @param deep Whether the search should look up proto chain.
+     *
+     * @return FindPropertyData or null if not found.
+     */
+    public final FindProperty findProperty(final String key, final boolean deep) {
+        return findProperty(key, deep, false, this);
+    }
+
+    /**
+     * Low level property API (not using property descriptors)
+     * <p>
+     * Find a property in the prototype hierarchy. Note: this is not a good idea
+     * to override except as it was done in {@link WithObject}.
+     * If you have to, use
+     * {jdk.nashorn.internal.objects.NativeArray{@link #getProperty(String)} or
+     * {jdk.nashorn.internal.objects.NativeArray{@link #getPropertyDescriptor(String)} as the
+     * overriding way to find array properties
+     *
+     * @see jdk.nashorn.internal.objects.NativeArray
+     *
+     * @param key  Property key.
+     * @param deep Whether the search should look up proto chain.
+     * @param stopOnNonScope should a deep search stop on the first non-scope object?
+     * @param start the object on which the lookup was originally initiated
+     *
+     * @return FindPropertyData or null if not found.
+     */
+    FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) {
+        // if doing deep search, stop search on the first non-scope object if asked to do so
+        if (stopOnNonScope && start != this && !isScope()) {
+            return null;
+        }
+
+        final PropertyMap selfMap  = getMap();
+        final Property    property = selfMap.findProperty(key);
+
+        if (property != null) {
+            return new FindProperty(start, this, property);
+        }
+
+        if (deep) {
+            final ScriptObject proto = getProto();
+            if(proto != null) {
+                return proto.findProperty(key, deep, stopOnNonScope, start);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Add a new property to the object.
+     * <p>
+     * This a more "low level" way that doesn't involve {@link PropertyDescriptor}s
+     *
+     * @param key             Property key.
+     * @param propertyFlags   Property flags.
+     * @param getter          Property getter, or null if not defined
+     * @param setter          Property setter, or null if not defined
+     *
+     * @return New property.
+     */
+    public final Property addOwnProperty(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
+        return addOwnProperty(newUserAccessors(key, propertyFlags, getter, setter));
+    }
+
+    /**
+     * Add a new property to the object.
+     * <p>
+     * This a more "low level" way that doesn't involve {@link PropertyDescriptor}s
+     *
+     * @param key             Property key.
+     * @param propertyFlags   Property flags.
+     * @param value           Value of property
+     *
+     * @return New property.
+     */
+    public final Property addOwnProperty(final String key, final int propertyFlags, final Object value) {
+        final MethodHandle setter = addSpill(key, propertyFlags);
+
+        try {
+            setter.invokeExact((Object)this, value);
+        } catch (final Error|RuntimeException e) {
+            throw e;
+        } catch (final Throwable e) {
+            throw new RuntimeException(e);
+        }
+
+        return getMap().findProperty(key);
+    }
+
+    /**
+     * Add a new property to the object.
+     * <p>
+     * This a more "low level" way that doesn't involve {@link PropertyDescriptor}s
+     *
+     * @param newProperty property to add
+     *
+     * @return New property.
+     */
+    public final Property addOwnProperty(final Property newProperty) {
+        PropertyMap oldMap = getMap();
+
+        while (true) {
+            final PropertyMap newMap = oldMap.addProperty(newProperty);
+
+            if (!compareAndSetMap(oldMap, newMap)) {
+                oldMap = getMap();
+                final Property oldProperty = oldMap.findProperty(newProperty.getKey());
+
+                if (oldProperty != null) {
+                    return oldProperty;
+                }
+            } else {
+                return newProperty;
+            }
+        }
+    }
+
+    private void erasePropertyValue(final Property property) {
+        // Erase the property field value with undefined. If the property is defined
+        // by user-defined accessors, we don't want to call the setter!!
+        if (!(property instanceof UserAccessorProperty)) {
+            try {
+                // make the property value to be undefined
+                //TODO specproperties
+                property.getSetter(Object.class, getMap()).invokeExact((Object)this, (Object)UNDEFINED);
+            } catch (final RuntimeException | Error e) {
+                throw e;
+            } catch (final Throwable t) {
+                throw new RuntimeException(t);
+            }
+        }
+    }
+
+    /**
+     * Delete a property from the object.
+     *
+     * @param property Property to delete.
+     *
+     * @return true if deleted.
+     */
+    public final boolean deleteOwnProperty(final Property property) {
+        erasePropertyValue(property);
+        PropertyMap oldMap = getMap();
+
+        while (true) {
+            final PropertyMap newMap = oldMap.deleteProperty(property);
+
+            if (newMap == null) {
+                return false;
+            }
+
+            if (!compareAndSetMap(oldMap, newMap)) {
+                oldMap = getMap();
+            } else {
+                // delete getter and setter function references so that we don't leak
+                if (property instanceof UserAccessorProperty) {
+                    final UserAccessorProperty uc = (UserAccessorProperty) property;
+                    setEmbedOrSpill(uc.getGetterSlot(), null);
+                    setEmbedOrSpill(uc.getSetterSlot(), null);
+                }
+                return true;
+            }
+        }
+    }
+
+    /**
+     * Modify a property in the object
+     *
+     * @param oldProperty    property to modify
+     * @param propertyFlags  new property flags
+     * @param getter         getter for {@link UserAccessorProperty}, null if not present or N/A
+     * @param setter         setter for {@link UserAccessorProperty}, null if not present or N/A
+     *
+     * @return new property
+     */
+    public final Property modifyOwnProperty(final Property oldProperty, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
+        Property newProperty;
+        if (oldProperty instanceof UserAccessorProperty) {
+            // re-use the slots of the old user accessor property.
+            final UserAccessorProperty uc = (UserAccessorProperty) oldProperty;
+
+            int getterSlot = uc.getGetterSlot();
+            // clear the old getter and set the new getter
+            setEmbedOrSpill(getterSlot, getter);
+            // if getter function is null, flag the slot to be negative (less by 1)
+            if (getter == null) {
+                getterSlot = -getterSlot - 1;
+            }
+
+            int setterSlot = uc.getSetterSlot();
+            // clear the old setter and set the new setter
+            setEmbedOrSpill(setterSlot, setter);
+            // if setter function is null, flag the slot to be negative (less by 1)
+            if (setter == null) {
+                setterSlot = -setterSlot - 1;
+            }
+
+            newProperty = new UserAccessorProperty(oldProperty.getKey(), propertyFlags, getterSlot, setterSlot);
+            // if just flipping getter and setter with new functions, no need to change property or map
+            if (oldProperty.equals(newProperty)) {
+                return oldProperty;
+            }
+        } else {
+            // erase old property value and create new user accessor property
+            erasePropertyValue(oldProperty);
+            newProperty = newUserAccessors(oldProperty.getKey(), propertyFlags, getter, setter);
+        }
+
+        notifyPropertyModified(this, oldProperty, newProperty);
+
+        return modifyOwnProperty(oldProperty, newProperty);
+    }
+
+    /**
+      * Modify a property in the object
+      *
+      * @param oldProperty    property to modify
+      * @param propertyFlags  new property flags
+      *
+      * @return new property
+      */
+    public final Property modifyOwnProperty(final Property oldProperty, final int propertyFlags) {
+        return modifyOwnProperty(oldProperty, oldProperty.setFlags(propertyFlags));
+    }
+
+    /**
+     * Modify a property in the object, replacing a property with a new one
+     *
+     * @param oldProperty   property to replace
+     * @param newProperty   property to replace it with
+     *
+     * @return new property
+     */
+    private Property modifyOwnProperty(final Property oldProperty, final Property newProperty) {
+        assert newProperty.getKey().equals(oldProperty.getKey()) : "replacing property with different key";
+
+        PropertyMap oldMap = getMap();
+
+        while (true) {
+            final PropertyMap newMap = oldMap.replaceProperty(oldProperty, newProperty);
+
+            if (!compareAndSetMap(oldMap, newMap)) {
+                oldMap = getMap();
+                final Property oldPropertyLookup = oldMap.findProperty(oldProperty.getKey());
+
+                if (oldPropertyLookup != null && oldPropertyLookup.equals(newProperty)) {
+                    return oldPropertyLookup;
+                }
+            } else {
+                return newProperty;
+            }
+        }
+    }
+
+    /**
+     * Update getter and setter in an object literal.
+     *
+     * @param key    Property key.
+     * @param getter {@link UserAccessorProperty} defined getter, or null if none
+     * @param setter {@link UserAccessorProperty} defined setter, or null if none
+     */
+    public final void setUserAccessors(final String key, final ScriptFunction getter, final ScriptFunction setter) {
+        final Property oldProperty = getMap().findProperty(key);
+        if (oldProperty != null) {
+            final UserAccessorProperty newProperty = newUserAccessors(oldProperty.getKey(), oldProperty.getFlags(), getter, setter);
+            modifyOwnProperty(oldProperty, newProperty);
+        } else {
+            final UserAccessorProperty newProperty = newUserAccessors(key, 0, getter, setter);
+            addOwnProperty(newProperty);
+        }
+    }
+
+    private static int getIntValue(final FindProperty find) {
+        final MethodHandle getter = find.getGetter(int.class);
+        if (getter != null) {
+            try {
+                return (int)getter.invokeExact((Object)find.getOwner());
+            } catch (final Error|RuntimeException e) {
+                throw e;
+            } catch (final Throwable e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        return ObjectClassGenerator.UNDEFINED_INT;
+    }
+
+    private static long getLongValue(final FindProperty find) {
+        final MethodHandle getter = find.getGetter(long.class);
+        if (getter != null) {
+            try {
+                return (long)getter.invokeExact((Object)find.getOwner());
+            } catch (final Error|RuntimeException e) {
+                throw e;
+            } catch (final Throwable e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        return ObjectClassGenerator.UNDEFINED_LONG;
+    }
+
+    private static double getDoubleValue(final FindProperty find) {
+        final MethodHandle getter = find.getGetter(double.class);
+        if (getter != null) {
+            try {
+                return (double)getter.invokeExact((Object)find.getOwner());
+            } catch (final Error|RuntimeException e) {
+                throw e;
+            } catch (final Throwable e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        return ObjectClassGenerator.UNDEFINED_DOUBLE;
+    }
+
+    /**
+      * Get the object value of a property
+      *
+      * @param find {@link FindProperty} lookup result
+      *
+      * @return the value of the property
+      */
+    protected static Object getObjectValue(final FindProperty find) {
+        final MethodHandle getter = find.getGetter(Object.class);
+        if (getter != null) {
+            try {
+                return getter.invokeExact((Object)find.getOwner());
+            } catch (final Error|RuntimeException e) {
+                throw e;
+            } catch (final Throwable e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        return UNDEFINED;
+    }
+
+    /**
+     * Return methodHandle of value function for call.
+     *
+     * @param find      data from find property.
+     * @param type      method type of function.
+     * @param bindName  null or name to bind to second argument (property not found method.)
+     *
+     * @return value of property as a MethodHandle or null.
+     *
+     */
+    @SuppressWarnings("static-method")
+    protected MethodHandle getCallMethodHandle(final FindProperty find, final MethodType type, final String bindName) {
+        return getCallMethodHandle(getObjectValue(find), type, bindName);
+    }
+
+    /**
+     * Return methodHandle of value function for call.
+     *
+     * @param value     value of receiver, it not a {@link ScriptFunction} this will return null.
+     * @param type      method type of function.
+     * @param bindName  null or name to bind to second argument (property not found method.)
+     *
+     * @return value of property as a MethodHandle or null.
+     */
+    protected static MethodHandle getCallMethodHandle(final Object value, final MethodType type, final String bindName) {
+        return value instanceof ScriptFunction ? ((ScriptFunction)value).getCallMethodHandle(type, bindName) : null;
+    }
+
+    /**
+     * Get value using found property.
+     *
+     * @param property Found property.
+     *
+     * @return Value of property.
+     */
+    public final Object getWithProperty(final Property property) {
+        return getObjectValue(new FindProperty(this, this, property));
+    }
+
+    /**
+     * Get a property given a key
+     *
+     * @param key property key
+     *
+     * @return property for key
+     */
+    public final Property getProperty(final String key) {
+        return getMap().findProperty(key);
+    }
+
+    static String convertKey(final Object key) {
+        return (key instanceof String) ? (String)key : JSType.toString(key);
+    }
+
+    /**
+     * Overridden by {@link jdk.nashorn.internal.objects.NativeArguments} class (internal use.)
+     * Used for argument access in a vararg function using parameter name.
+     * Returns the argument at a given key (index)
+     *
+     * @param key argument index
+     *
+     * @return the argument at the given position, or undefined if not present
+     */
+    public Object getArgument(final int key) {
+        return get(key);
+    }
+
+    /**
+     * Overridden by {@link jdk.nashorn.internal.objects.NativeArguments} class (internal use.)
+     * Used for argument access in a vararg function using parameter name.
+     * Returns the argument at a given key (index)
+     *
+     * @param key   argument index
+     * @param value the value to write at the given index
+     */
+    public void setArgument(final int key, final Object value) {
+        set(key, value, getContext()._strict);
+    }
+
+    /**
+     * Return true if the script object context is strict
+     * @return true if strict context
+     */
+    public final boolean isStrictContext() {
+        return getContext()._strict;
+    }
+
+    /**
+     * Return the current context from the object's map.
+     * @return Current context.
+     */
+    final Context getContext() {
+        return getMap().getContext();
+    }
+
+    /**
+     * Return the map of an object.
+     * @return PropertyMap object.
+     */
+    public final PropertyMap getMap() {
+        return map;
+    }
+
+    /**
+     * Set the initial map.
+     * @param map Initial map.
+     */
+    public final void setMap(final PropertyMap map) {
+        this.map = map;
+    }
+
+    /**
+     * Conditionally set the new map if the old map is the same.
+     * @param oldMap Map prior to manipulation.
+     * @param newMap Replacement map.
+     * @return true if the operation succeeded.
+     */
+    protected synchronized final boolean compareAndSetMap(final PropertyMap oldMap, final PropertyMap newMap) {
+        final boolean update = oldMap == this.map;
+
+        if (update) {
+            this.map = newMap;
+        }
+
+        return update;
+     }
+
+    /**
+     * Return the __proto__ of an object.
+     * @return __proto__ object.
+     */
+    public final ScriptObject getProto() {
+        return getMap().getProto();
+    }
+
+    /**
+     * Check if this is a prototype
+     * @return true if {@link PropertyMap#isPrototype()} is true for this ScriptObject
+     */
+    public final boolean isPrototype() {
+        return getMap().isPrototype();
+    }
+
+    /**
+     * Set the __proto__ of an object.
+     * @param newProto new __proto__ to set.
+     */
+    public final void setProto(final ScriptObject newProto) {
+        PropertyMap  oldMap   = getMap();
+        ScriptObject oldProto = getProto();
+
+        while (oldProto != newProto) {
+            final PropertyMap newMap = oldMap.setProto(newProto);
+
+            if (!compareAndSetMap(oldMap, newMap)) {
+                oldMap = getMap();
+                oldProto = getProto();
+            } else {
+                if (isPrototype()) {
+
+                    if (oldProto != null) {
+                        oldProto.removePropertyListener(this);
+                    }
+
+                    if (newProto != null) {
+                        newProto.addPropertyListener(this);
+                    }
+                }
+
+                return;
+            }
+        }
+    }
+
+    /**
+     * Set the __proto__ of an object with checks.
+     * @param newProto Prototype to set.
+     */
+    public final void setProtoCheck(final Object newProto) {
+        if (newProto == null || newProto instanceof ScriptObject) {
+            setProto((ScriptObject)newProto);
+        } else {
+            final ScriptObject global = Context.getGlobalTrusted();
+            final Object  newProtoObject = JSType.toScriptObject(global, newProto);
+
+            if (newProtoObject instanceof ScriptObject) {
+                setProto((ScriptObject)newProtoObject);
+            } else {
+                throw typeError(global, "cant.set.proto.to.non.object", ScriptRuntime.safeToString(this), ScriptRuntime.safeToString(newProto));
+            }
+        }
+    }
+
+    /**
+     * return a List of own keys associated with the object.
+     * @param all True if to include non-enumerable keys.
+     * @return Array of keys.
+     */
+    public String[] getOwnKeys(final boolean all) {
+        final List<Object> keys    = new ArrayList<>();
+        final PropertyMap  selfMap = this.getMap();
+
+        final ArrayData array  = getArray();
+        final long length      = array.length();
+
+        for (long i = 0; i < length; i = array.nextIndex(i)) {
+            if (array.has((int)i)) {
+                keys.add(JSType.toString(i));
+            }
+        }
+
+        for (final Property property : selfMap.getProperties()) {
+            if (all || property.isEnumerable()) {
+                keys.add(property.getKey());
+            }
+        }
+
+        return keys.toArray(new String[keys.size()]);
+    }
+
+    /**
+     * Check if this ScriptObject has array entries. This means that someone has
+     * set values with numeric keys in the object.
+     *
+     * Note: this can be O(n) up to the array length
+     *
+     * @return true if array entries exists.
+     */
+    public boolean hasArrayEntries() {
+        final ArrayData array = getArray();
+        final long length = array.length();
+
+        for (long i = 0; i < length; i++) {
+            if (array.has((int)i)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Return the valid JavaScript type name descriptor
+     *
+     * @return "Object"
+     */
+    public String getClassName() {
+        return "Object";
+    }
+
+    /**
+     * {@code length} is a well known property. This is its getter.
+     * Note that this *may* be optimized by other classes
+     *
+     * @return length property value for this ScriptObject
+     */
+    public Object getLength() {
+        return get("length");
+    }
+
+    /**
+     * Stateless toString for ScriptObjects.
+     *
+     * @return string description of this object, e.g. {@code [object Object]}
+     */
+    public String safeToString() {
+        return "[object " + getClassName() + "]";
+    }
+
+    /**
+     * Return the default value of the object with a given preferred type hint.
+     * The preferred type hints are String.class for type String, Number.class
+     * for type Number. <p>
+     *
+     * A <code>hint</code> of null means "no hint".
+     *
+     * ECMA 8.12.8 [[DefaultValue]](hint)
+     *
+     * @param typeHint the preferred type hint
+     * @return the default value
+     */
+    public Object getDefaultValue(final Class<?> typeHint) {
+        // We delegate to GlobalObject, as the implementation uses dynamic call sites to invoke object's "toString" and
+        // "valueOf" methods, and in order to avoid those call sites from becoming megamorphic when multiple contexts
+        // are being executed in a long-running program, we move the code and their associated dynamic call sites
+        // (Global.TO_STRING and Global.VALUE_OF) into per-context code.
+        return ((GlobalObject)Context.getGlobalTrusted()).getDefaultValue(this, typeHint);
+    }
+
+    /**
+     * Checking whether a script object is an instance of another. Used
+     * in {@link ScriptFunction} for hasInstance implementation, walks
+     * the proto chain
+     *
+     * @param instance instace to check
+     * @return true if instance of instance
+     */
+    public boolean isInstance(final ScriptObject instance) {
+        return false;
+    }
+
+    /**
+     * Flag this ScriptObject as non extensible
+     *
+     * @return the object after being made non extensible
+     */
+    public ScriptObject preventExtensions() {
+        PropertyMap oldMap = getMap();
+
+        while (true) {
+            final PropertyMap newMap = getMap().preventExtensions();
+
+            if (!compareAndSetMap(oldMap, newMap)) {
+                oldMap = getMap();
+            } else {
+                return this;
+            }
+        }
+    }
+
+    /**
+     * Check whether if an Object (not just a ScriptObject) represents JavaScript array
+     *
+     * @param obj object to check
+     *
+     * @return true if array
+     */
+    public static boolean isArray(final Object obj) {
+        return (obj instanceof ScriptObject) && ((ScriptObject)obj).isArray();
+    }
+
+    /**
+     * Check if this ScriptObject is an array
+     * @return true if array
+     */
+    public final boolean isArray() {
+        return (flags & IS_ARRAY) != 0;
+    }
+
+    /**
+     * Flag this ScriptObject as being an array
+     */
+    public final void setIsArray() {
+        flags |= IS_ARRAY;
+    }
+
+    /**
+     * Check if this ScriptObject is an {@code arguments} vector
+     * @return true if arguments vector
+     */
+    public final boolean isArguments() {
+        return (flags & IS_ARGUMENTS) != 0;
+    }
+
+    /**
+     * Flag this ScriptObject as being an {@code arguments} vector
+     */
+    public final void setIsArguments() {
+        flags |= IS_ARGUMENTS;
+    }
+
+    /**
+     * Get the {@link ArrayData} for this ScriptObject if it is an array
+     * @return array data
+     */
+    public final ArrayData getArray() {
+        return arrayData;
+    }
+
+    /**
+     * Set the {@link ArrayData} for this ScriptObject if it is to be an array
+     * @param arrayData the array data
+     */
+    public final void setArray(final ArrayData arrayData) {
+        this.arrayData = arrayData;
+    }
+
+    /**
+     * Check if this ScriptObject is extensible
+     * @return true if extensible
+     */
+    public boolean isExtensible() {
+        return getMap().isExtensible();
+    }
+
+    /**
+     * ECMAScript 15.2.3.8 - seal implementation
+     * @return the sealed ScriptObject
+     */
+    public ScriptObject seal() {
+        PropertyMap oldMap = getMap();
+
+        while (true) {
+            final PropertyMap newMap = getMap().seal();
+
+            if (!compareAndSetMap(oldMap, newMap)) {
+                oldMap = getMap();
+            } else {
+                setArray(ArrayData.seal(getArray()));
+                return this;
+            }
+        }
+    }
+
+    /**
+     * Check whether this ScriptObject is sealed
+     * @return true if sealed
+     */
+    public boolean isSealed() {
+        return getMap().isSealed();
+    }
+
+    /**
+     * ECMA 15.2.39 - freeze implementation. Freeze this ScriptObject
+     * @return the frozen ScriptObject
+     */
+    public ScriptObject freeze() {
+        PropertyMap oldMap = getMap();
+
+        while (true) {
+            final PropertyMap newMap = getMap().freeze();
+
+            if (!compareAndSetMap(oldMap, newMap)) {
+                oldMap = getMap();
+            } else {
+                setArray(ArrayData.freeze(getArray()));
+                return this;
+            }
+        }
+    }
+
+    /**
+     * Check whether this ScriptObject is frozen
+     * @return true if frozed
+     */
+    public boolean isFrozen() {
+        return getMap().isFrozen();
+    }
+
+
+    /**
+     * Flag this ScriptObject as scope
+     */
+    public final void setIsScope() {
+        if (Context.DEBUG) {
+            scopeCount++;
+        }
+        flags |= IS_SCOPE;
+    }
+
+    /**
+     * Check whether this ScriptObject is scope
+     * @return true if scope
+     */
+    public final boolean isScope() {
+        return (flags & IS_SCOPE) != 0;
+    }
+
+    /**
+     * Clears the properties from a ScriptObject
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     */
+    public void clear() {
+        final boolean strict = getContext()._strict;
+        final Iterator<String> iter = propertyIterator();
+        while (iter.hasNext()) {
+            delete(iter.next(), strict);
+        }
+    }
+
+    /**
+     * Checks if a property with a given key is present in a ScriptObject
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @param key the key to check for
+     * @return true if a property with the given key exists, false otherwise
+     */
+    public boolean containsKey(final Object key) {
+        return has(key);
+    }
+
+    /**
+     * Checks if a property with a given value is present in a ScriptObject
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @param value value to check for
+     * @return true if a property with the given value exists, false otherwise
+     */
+    public boolean containsValue(final Object value) {
+        final Iterator<Object> iter = valueIterator();
+        while (iter.hasNext()) {
+            if (iter.next().equals(value)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the set of {@literal <property, value>} entries that make up this
+     * ScriptObject's properties
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @return an entry set of all the properties in this object
+     */
+    public Set<Map.Entry<Object, Object>> entrySet() {
+        final Iterator<String> iter = propertyIterator();
+        final Set<Map.Entry<Object, Object>> entries = new HashSet<>();
+        while (iter.hasNext()) {
+            final Object key = iter.next();
+            entries.add(new AbstractMap.SimpleImmutableEntry<>(key, get(key)));
+        }
+        return Collections.unmodifiableSet(entries);
+    }
+
+    /**
+     * Check whether a ScriptObject contains no properties
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @return true if object has no properties
+     */
+    public boolean isEmpty() {
+        return !propertyIterator().hasNext();
+    }
+
+    /**
+     * Return the set of keys (property names) for all properties
+     * in this ScriptObject
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @return keySet of this ScriptObject
+     */
+    public Set<Object> keySet() {
+        final Iterator<String> iter = propertyIterator();
+        final Set<Object> keySet = new HashSet<>();
+        while (iter.hasNext()) {
+            keySet.add(iter.next());
+        }
+        return Collections.unmodifiableSet(keySet);
+    }
+
+    /**
+     * Put a property in the ScriptObject
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @param key property key
+     * @param value property value
+     * @return oldValue if property with same key existed already
+     */
+    public Object put(final Object key, final Object value) {
+        final Object oldValue = get(key);
+        set(key, value, getContext()._strict);
+        return oldValue;
+    }
+
+    /**
+     * Put several properties in the ScriptObject given a mapping
+     * of their keys to their values
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @param otherMap a {@literal <key,value>} map of properties to add
+     */
+    public void putAll(final Map<?, ?> otherMap) {
+        final boolean strict = getContext()._strict;
+        for (final Map.Entry<?, ?> entry : otherMap.entrySet()) {
+            set(entry.getKey(), entry.getValue(), strict);
+        }
+    }
+
+    /**
+     * Remove a property from the ScriptObject.
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @param key the key of the property
+     * @return the oldValue of the removed property
+     */
+    public Object remove(final Object key) {
+        final Object oldValue = get(key);
+        delete(key, getContext()._strict);
+        return oldValue;
+    }
+
+    /**
+     * Return the size of the ScriptObject - i.e. the number of properties
+     * it contains
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @return number of properties in ScriptObject
+     */
+    public int size() {
+        int n = 0;
+        for (final Iterator<String> iter = propertyIterator(); iter.hasNext(); iter.next()) {
+            n++;
+        }
+        return n;
+    }
+
+    /**
+     * Return the values of the properties in the ScriptObject
+     * (java.util.Map-like method to help ScriptObjectMirror implementation)
+     *
+     * @return collection of values for the properties in this ScriptObject
+     */
+    public Collection<Object> values() {
+        final List<Object>     values = new ArrayList<>(size());
+        final Iterator<Object> iter   = valueIterator();
+        while (iter.hasNext()) {
+            values.add(iter.next());
+        }
+        return Collections.unmodifiableList(values);
+    }
+
+    /**
+     * Lookup method that, given a CallSiteDescriptor, looks up the target
+     * MethodHandle and creates a GuardedInvocation
+     * with the appropriate guard(s).
+     *
+     * @param desc call site descriptor
+     * @param request the link request
+     *
+     * @return GuardedInvocation for the callsite
+     */
+    public GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request) {
+        final int c = desc.getNameTokenCount();
+        // JavaScript is "immune" to all currently defined Dynalink composite operation - getProp is the same as getElem
+        // is the same as getMethod as JavaScript objects have a single namespace for all three. Therefore, we don't
+        // care about them, and just link to whatever is the first operation.
+        final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
+        // NOTE: we support getElem and setItem as JavaScript doesn't distinguish items from properties. Nashorn itself
+        // emits "dyn:getProp:identifier" for "<expr>.<identifier>" and "dyn:getElem" for "<expr>[<expr>]", but we are
+        // more flexible here and dispatch not on operation name (getProp vs. getElem), but rather on whether the
+        // operation has an associated name or not.
+        switch (operator) {
+        case "getProp":
+        case "getElem":
+        case "getMethod":
+            return c > 2 ? findGetMethod(desc, request, operator) : findGetIndexMethod(desc, request);
+        case "setProp":
+        case "setElem":
+            return c > 2 ? findSetMethod(desc, request) : findSetIndexMethod(desc);
+        case "call":
+            return findCallMethod(desc, request);
+        case "new":
+            return findNewMethod(desc);
+        case "callMethod":
+            return findCallMethodMethod(desc, request);
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Find the appropriate New method for an invoke dynamic call.
+     *
+     * @param desc The invoke dynamic call site descriptor.
+     *
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
+        return notAFunction();
+    }
+
+    /**
+     * Find the appropriate CALL method for an invoke dynamic call.
+     * This generates "not a function" always
+     *
+     * @param desc    the call site descriptor.
+     * @param request the link request
+     *
+     * @return GuardedInvocation to be invoed at call site.
+     */
+    protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        return notAFunction();
+    }
+
+    private GuardedInvocation notAFunction() {
+        throw typeError("not.a.function", ScriptRuntime.safeToString(this));
+    }
+
+    /**
+     * Find an implementation for a "dyn:callMethod" operation. Note that Nashorn internally never uses
+     * "dyn:callMethod", but instead always emits two call sites in bytecode, one for "dyn:getMethod", and then another
+     * one for "dyn:call". Explicit support for "dyn:callMethod" is provided for the benefit of potential external
+     * callers. The implementation itself actually folds a "dyn:getMethod" method handle into a "dyn:call" method handle.
+     *
+     * @param desc    the call site descriptor.
+     * @param request the link request
+     *
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    protected GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        // R(P0, P1, ...)
+        final MethodType callType = desc.getMethodType();
+        // use type Object(P0) for the getter
+        final CallSiteDescriptor getterType = desc.changeMethodType(MethodType.methodType(Object.class, callType.parameterType(0)));
+        final GuardedInvocation getter = findGetMethod(getterType, request, "getMethod");
+
+        // Object(P0) => Object(P0, P1, ...)
+        final MethodHandle argDroppingGetter = MH.dropArguments(getter.getInvocation(), 1, callType.parameterList().subList(1, callType.parameterCount()));
+        // R(Object, P0, P1, ...)
+        final MethodHandle invoker = Bootstrap.createDynamicInvoker("dyn:call", callType.insertParameterTypes(0, argDroppingGetter.type().returnType()));
+        // Fold Object(P0, P1, ...) into R(Object, P0, P1, ...) => R(P0, P1, ...)
+        return getter.replaceMethods(MH.foldArguments(invoker, argDroppingGetter), getter.getGuard());
+    }
+
+    /**
+     * Find the appropriate GET method for an invoke dynamic call.
+     *
+     * @param desc     the call site descriptor
+     * @param request  the link request
+     * @param operator operator for get: getProp, getMethod, getElem etc
+     *
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
+        final String name = desc.getNameToken(2);
+
+        if (request.isCallSiteUnstable()) {
+            return findMegaMorphicGetMethod(desc, name);
+        }
+
+        final FindProperty find = findProperty(name, true);
+
+        MethodHandle methodHandle;
+
+        if (find == null) {
+            if ("getProp".equals(operator)) {
+                return noSuchProperty(desc, request);
+            } else if ("getMethod".equals(operator)) {
+                return noSuchMethod(desc, request);
+            } else if ("getElem".equals(operator)) {
+                return createEmptyGetter(desc, name);
+            }
+            throw new AssertionError(); // never invoked with any other operation
+        }
+
+        final Class<?> returnType = desc.getMethodType().returnType();
+        final Property property = find.getProperty();
+        methodHandle = find.getGetter(returnType);
+
+        // getMap() is fine as we have the prototype switchpoint depending on where the property was found
+        final MethodHandle guard = NashornGuards.getMapGuard(getMap());
+
+        if (methodHandle != null) {
+            assert methodHandle.type().returnType().equals(returnType);
+            if (find.isSelf()) {
+                return new GuardedInvocation(methodHandle, ObjectClassGenerator.OBJECT_FIELDS_ONLY &&
+                        NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType() ? null : guard);
+            }
+
+            final ScriptObject prototype = find.getOwner();
+
+            if (!property.hasGetterFunction()) {
+                methodHandle = bindTo(methodHandle, prototype);
+            }
+            return new GuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(name), guard);
+        }
+
+        assert !NashornCallSiteDescriptor.isFastScope(desc);
+        return new GuardedInvocation(Lookup.emptyGetter(returnType), getMap().getProtoGetSwitchPoint(name), guard);
+    }
+
+    private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name) {
+        final GuardedInvocation inv = findGetIndexMethod(desc.getMethodType().insertParameterTypes(1, Object.class));
+        return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard());
+    }
+
+    /**
+     * Find the appropriate GETINDEX method for an invoke dynamic call.
+     *
+     * @param desc    the call site descriptor
+     * @param request the link request
+     *
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        return findGetIndexMethod(desc.getMethodType());
+    }
+
+    /**
+     * Find the appropriate GETINDEX method for an invoke dynamic call.
+     *
+     * @param callType the call site method type
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    private static GuardedInvocation findGetIndexMethod(final MethodType callType) {
+        final Class<?> returnClass = callType.returnType();
+        final Class<?> keyClass    = callType.parameterType(1);
+
+        String name = "get";
+        if (returnClass.isPrimitive()) {
+            //turn e.g. get with a double into getDouble
+            final String returnTypeName = returnClass.getName();
+            name += Character.toUpperCase(returnTypeName.charAt(0)) + returnTypeName.substring(1, returnTypeName.length());
+        }
+
+        return new GuardedInvocation(findOwnMH(name, returnClass, keyClass), getScriptObjectGuard(callType));
+    }
+
+    private static MethodHandle getScriptObjectGuard(final MethodType type) {
+        return ScriptObject.class.isAssignableFrom(type.parameterType(0)) ? null : NashornGuards.getScriptObjectGuard();
+    }
+
+    /**
+     * Find the appropriate SET method for an invoke dynamic call.
+     *
+     * @param desc    the call site descriptor
+     * @param request the link request
+     *
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+        if(request.isCallSiteUnstable()) {
+            return findMegaMorphicSetMethod(desc, name);
+        }
+
+        final boolean scope = isScope();
+        /*
+         * If doing property set on a scope object, we should stop proto search on the first
+         * non-scope object. Without this, for example, when assigning "toString" on global scope,
+         * we'll end up assigning it on it's proto - which is Object.prototype.toString !!
+         *
+         * toString = function() { print("global toString"); } // don't affect Object.prototype.toString
+         */
+        FindProperty find = findProperty(name, true, scope, this);
+        // If it's not a scope search, then we don't want any inherited properties except those with user defined accessors.
+        if (!scope && find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
+            // We should still check if inherited data property is not writable
+            if (isExtensible() && !find.getProperty().isWritable()) {
+                return createEmptySetMethod(desc, "property.not.writable", false);
+            }
+            // Otherwise, forget the found property
+            find = null;
+        }
+
+        if (find != null) {
+            if(!find.getProperty().isWritable()) {
+                // Existing, non-writable property
+                return createEmptySetMethod(desc, "property.not.writable", true);
+            }
+        } else if (!isExtensible()) {
+            // Non-existing property on a non-extensible object
+            return createEmptySetMethod(desc, "object.non.extensible", false);
+        }
+
+        return new SetMethodCreator(this, find, desc).createGuardedInvocation();
+    }
+
+    private GuardedInvocation createEmptySetMethod(final CallSiteDescriptor desc, String strictErrorMessage, boolean canBeFastScope) {
+        final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+        if (NashornCallSiteDescriptor.isStrict(desc)) {
+               throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString((this)));
+           }
+           assert canBeFastScope || !NashornCallSiteDescriptor.isFastScope(desc);
+           final PropertyMap myMap = getMap();
+           return new GuardedInvocation(Lookup.EMPTY_SETTER, myMap.getProtoGetSwitchPoint(name), NashornGuards.getMapGuard(myMap));
+    }
+
+    @SuppressWarnings("unused")
+    private static void setEmbed(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final MethodHandle setter, final int i, final Object self, final Object value) throws Throwable {
+        final ScriptObject obj = (ScriptObject)self;
+        if (obj.trySetEmbedOrSpill(desc, oldMap, newMap, value)) {
+            obj.useEmbed(i);
+            setter.invokeExact(self, value);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void setSpill(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final int index, final Object self, final Object value) {
+        final ScriptObject obj = (ScriptObject)self;
+        if (obj.trySetEmbedOrSpill(desc, oldMap, newMap, value)) {
+            obj.spill[index] = value;
+        }
+    }
+
+    private boolean trySetEmbedOrSpill(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final Object value) {
+        final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
+        if (!isExtensible() && isStrict) {
+            throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(this));
+        } else if (compareAndSetMap(oldMap, newMap)) {
+            return true;
+        } else {
+            set(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND), value, isStrict);
+            return false;
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void setSpillWithNew(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final int index, final Object self, final Object value) {
+        final ScriptObject obj      = (ScriptObject)self;
+        final boolean      isStrict = NashornCallSiteDescriptor.isStrict(desc);
+
+        if (!obj.isExtensible()) {
+            if (isStrict) {
+                throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+            }
+        } else if (obj.compareAndSetMap(oldMap, newMap)) {
+            obj.spill = new Object[SPILL_RATE];
+            obj.spill[index] = value;
+        } else {
+            obj.set(desc.getNameToken(2), value, isStrict);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void setSpillWithGrow(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final int index, final int newLength, final Object self, final Object value) {
+        final ScriptObject obj      = (ScriptObject)self;
+        final boolean      isStrict = NashornCallSiteDescriptor.isStrict(desc);
+
+        if (!obj.isExtensible()) {
+            if (isStrict) {
+                throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+            }
+        } else if (obj.compareAndSetMap(oldMap, newMap)) {
+            final int oldLength = obj.spill.length;
+            final Object[] newSpill = new Object[newLength];
+            System.arraycopy(obj.spill, 0, newSpill, 0, oldLength);
+            obj.spill = newSpill;
+            obj.spill[index] = value;
+        } else {
+            obj.set(desc.getNameToken(2), value, isStrict);
+        }
+    }
+
+    private static GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
+        final GuardedInvocation inv = findSetIndexMethod(desc.getMethodType().insertParameterTypes(1, Object.class),
+                NashornCallSiteDescriptor.isStrict(desc));
+        return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard());
+    }
+
+    private static GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc) { // array, index, value
+        return findSetIndexMethod(desc.getMethodType(), NashornCallSiteDescriptor.isStrict(desc));
+    }
+
+    /**
+     * Find the appropriate SETINDEX method for an invoke dynamic call.
+     *
+     * @param callType the method type at the call site
+     * @param isStrict are we in strict mode?
+     *
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    private static GuardedInvocation findSetIndexMethod(final MethodType callType, final boolean isStrict) {
+        assert callType.parameterCount() == 3;
+
+        final Class<?>   keyClass   = callType.parameterType(1);
+        final Class<?>   valueClass = callType.parameterType(2);
+
+        MethodHandle methodHandle = findOwnMH("set", void.class, keyClass, valueClass, boolean.class);
+        methodHandle = MH.insertArguments(methodHandle, 3, isStrict);
+
+        return new GuardedInvocation(methodHandle, getScriptObjectGuard(callType));
+    }
+
+    /**
+     * Fall back if a function property is not found.
+     * @param desc The call site descriptor
+     * @param request the link request
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    public GuardedInvocation noSuchMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+        final String       name      = desc.getNameToken(2);
+        final FindProperty find      = findProperty(NO_SUCH_METHOD_NAME, true);
+        final boolean      scopeCall = isScope() && NashornCallSiteDescriptor.isScope(desc);
+
+        if (find == null) {
+            return noSuchProperty(desc, request);
+        }
+
+        final ScriptFunction func = (ScriptFunction)getObjectValue(find);
+        final Object thiz = scopeCall && func.isStrict() ? ScriptRuntime.UNDEFINED : this;
+        // TODO: It'd be awesome if we could bind "name" without binding "this".
+        return new GuardedInvocation(MH.dropArguments(MH.constant(ScriptFunction.class,
+                func.makeBoundFunction(thiz, new Object[] { name })), 0, Object.class),
+                null, NashornGuards.getMapGuard(getMap()));
+    }
+
+    /**
+     * Fall back if a property is not found.
+     * @param desc the call site descriptor.
+     * @param request the link request
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) {
+        final String name = desc.getNameToken(2);
+        final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
+        final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
+
+        if (find != null) {
+            final ScriptFunction func = (ScriptFunction)getObjectValue(find);
+            MethodHandle methodHandle = getCallMethodHandle(func, desc.getMethodType(), name);
+
+            if (methodHandle != null) {
+                if (scopeAccess && func.isStrict()) {
+                    methodHandle = bindTo(methodHandle, UNDEFINED);
+                }
+                return new GuardedInvocation(methodHandle,
+                        find.isInherited()? getMap().getProtoGetSwitchPoint(NO_SUCH_PROPERTY_NAME) : null,
+                        getKnownFunctionPropertyGuard(getMap(), find.getGetter(Object.class), find.getOwner(), func));
+            }
+        }
+
+        if (scopeAccess) {
+            throw referenceError("not.defined", name);
+        }
+
+        return createEmptyGetter(desc, name);
+    }
+
+    private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final String name) {
+        return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), getMap().getProtoGetSwitchPoint(name), NashornGuards.getMapGuard(getMap()));
+    }
+
+    private abstract static class ScriptObjectIterator <T extends Object> implements Iterator<T> {
+        protected T[] values;
+        protected final ScriptObject object;
+        private int index;
+
+        ScriptObjectIterator(final ScriptObject object) {
+            this.object = object;
+        }
+
+        protected abstract void init();
+
+        @Override
+        public boolean hasNext() {
+            if (values == null) {
+                init();
+            }
+            return index < values.length;
+        }
+
+        @Override
+        public T next() {
+            if (values == null) {
+                init();
+            }
+            return values[index++];
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private static class KeyIterator extends ScriptObjectIterator<String> {
+        KeyIterator(final ScriptObject object) {
+            super(object);
+        }
+
+        @Override
+        protected void init() {
+            final Set<String> keys = new LinkedHashSet<>();
+            for (ScriptObject self = object; self != null; self = self.getProto()) {
+                keys.addAll(Arrays.asList(self.getOwnKeys(false)));
+            }
+            this.values = keys.toArray(new String[keys.size()]);
+        }
+    }
+
+    private static class ValueIterator extends ScriptObjectIterator<Object> {
+        ValueIterator(final ScriptObject object) {
+            super(object);
+        }
+
+        @Override
+        protected void init() {
+            final ArrayList<Object> valueList = new ArrayList<>();
+            for (ScriptObject self = object; self != null; self = self.getProto()) {
+                for (final String key : self.getOwnKeys(false)) {
+                    valueList.add(self.get(key));
+                }
+            }
+            this.values = valueList.toArray(new Object[valueList.size()]);
+        }
+    }
+
+    /**
+     * Add a spill property for the given key.
+     * @param key           Property key.
+     * @param propertyFlags Property flags.
+     * @return Added property.
+     */
+    private Property addSpillProperty(final String key, final int propertyFlags) {
+        int i = findEmbed();
+        Property spillProperty;
+
+        if (i >= EMBED_SIZE) {
+            i = getMap().getSpillLength();
+            MethodHandle getter = MH.arrayElementGetter(Object[].class);
+            MethodHandle setter = MH.arrayElementSetter(Object[].class);
+            getter = MH.asType(MH.insertArguments(getter, 1, i), Lookup.GET_OBJECT_TYPE);
+            setter = MH.asType(MH.insertArguments(setter, 1, i), Lookup.SET_OBJECT_TYPE);
+            spillProperty = new SpillProperty(key, propertyFlags | Property.IS_SPILL, i, getter, setter);
+            notifyPropertyAdded(this, spillProperty);
+            spillProperty = addOwnProperty(spillProperty);
+            i = spillProperty.getSlot();
+
+            final int newLength = (i + SPILL_RATE) / SPILL_RATE * SPILL_RATE;
+            final Object[] newSpill = new Object[newLength];
+
+            if (spill != null) {
+                System.arraycopy(spill, 0, newSpill, 0, spill.length);
+            }
+
+            spill = newSpill;
+         } else {
+            useEmbed(i);
+            spillProperty = new SpillProperty(key, propertyFlags, i, GET_EMBED[i], SET_EMBED[i]);
+            notifyPropertyAdded(this, spillProperty);
+            spillProperty = addOwnProperty(spillProperty);
+        }
+
+        return spillProperty;
+    }
+
+
+    /**
+     * Add a spill entry for the given key.
+     * @param key           Property key.
+     * @param propertyFlags Property flags.
+     * @return Setter method handle.
+     */
+    private MethodHandle addSpill(final String key, final int propertyFlags) {
+        final Property spillProperty = addSpillProperty(key, propertyFlags);
+        final Class<?> type = Object.class;
+        return spillProperty.getSetter(type, getMap()); //TODO specfields
+    }
+
+    MethodHandle addSpill(final String key) {
+        return addSpill(key, 0);
+    }
+
+    /**
+     * Make sure arguments are paired correctly, with respect to more parameters than declared,
+     * fewer parameters than declared and other things that JavaScript allows. This might involve
+     * creating collectors.
+     *
+     * @param methodHandle method handle for invoke
+     * @param callType     type of the call
+     *
+     * @return method handle with adjusted arguments
+     */
+    protected static MethodHandle pairArguments(final MethodHandle methodHandle, final MethodType callType) {
+        return pairArguments(methodHandle, callType, null);
+    }
+
+    /**
+     * Make sure arguments are paired correctly, with respect to more parameters than declared,
+     * fewer parameters than declared and other things that JavaScript allows. This might involve
+     * creating collectors.
+     *
+     * Make sure arguments are paired correctly.
+     * @param methodHandle MethodHandle to adjust.
+     * @param callType     MethodType of caller.
+     * @param callerVarArg true if the caller is vararg, false otherwise, null if it should be inferred.
+     *
+     * @return method handle with adjusted arguments
+     */
+    public static MethodHandle pairArguments(final MethodHandle methodHandle, final MethodType callType, final Boolean callerVarArg) {
+
+        final MethodType methodType = methodHandle.type();
+        if (methodType.equals(callType)) {
+            return methodHandle;
+        }
+
+        final int parameterCount = methodType.parameterCount();
+        final int callCount      = callType.parameterCount();
+
+        final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
+        final boolean isCallerVarArg = callerVarArg != null ? callerVarArg.booleanValue() : (callCount > 1 &&
+                callType.parameterType(callCount - 1).isArray());
+
+        if (callCount < parameterCount) {
+            final int      missingArgs = parameterCount - callCount;
+            final Object[] fillers     = new Object[missingArgs];
+
+            Arrays.fill(fillers, UNDEFINED);
+
+            if (isCalleeVarArg) {
+                fillers[missingArgs - 1] = new Object[0];
+            }
+
+            return MH.insertArguments(
+                methodHandle,
+                parameterCount - missingArgs,
+                fillers);
+        }
+
+        if (isCalleeVarArg) {
+            return isCallerVarArg ?
+                methodHandle :
+                MH.asCollector(methodHandle, Object[].class, callCount - parameterCount + 1);
+        }
+
+        if (isCallerVarArg) {
+            final int spreadArgs = parameterCount - callCount + 1;
+            return MH.filterArguments(
+                MH.asSpreader(
+                    methodHandle,
+                    Object[].class,
+                    spreadArgs),
+                callCount - 1,
+                MH.insertArguments(
+                    TRUNCATINGFILTER,
+                    0,
+                    spreadArgs)
+                );
+        }
+
+        if (callCount > parameterCount) {
+            final int discardedArgs = callCount - parameterCount;
+
+            final Class<?>[] discards = new Class<?>[discardedArgs];
+            Arrays.fill(discards, Object.class);
+
+            return MH.dropArguments(methodHandle, callCount - discardedArgs, discards);
+        }
+
+        return methodHandle;
+    }
+
+    @SuppressWarnings("unused")
+    private static Object[] truncatingFilter(final int n, final Object[] array) {
+        final int length = array == null ? 0 : array.length;
+        if (n == length) {
+            return array == null ? new Object[0] : array;
+        }
+
+        final Object[] newArray = new Object[n];
+
+        if (array != null) {
+            for (int i = 0; i < n && i < length; i++) {
+                newArray[i] = array[i];
+            }
+        }
+
+        if (length < n) {
+            final Object fill = UNDEFINED;
+
+            for (int i = length; i < n; i++) {
+                newArray[i] = fill;
+            }
+        }
+
+        return newArray;
+    }
+
+    /**
+      * Numeric length setter for length property
+      *
+      * @param newLength new length to set
+      */
+    public final void setLength(final long newLength) {
+       final long arrayLength = getArray().length();
+       if (newLength == arrayLength) {
+           return;
+       }
+
+       final boolean isStrict = getContext()._strict;
+
+       if (newLength > arrayLength) {
+           setArray(getArray().ensure(newLength - 1));
+            if (getArray().canDelete(arrayLength, (newLength - 1), isStrict)) {
+               setArray(getArray().delete(arrayLength, (newLength - 1)));
+           }
+           return;
+       }
+
+       if (newLength < arrayLength) {
+           setArray(getArray().shrink(newLength));
+           getArray().setLength(newLength);
+       }
+   }
+
+    @Override
+    public int getInt(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getInt(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getIntValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getInt(key) : 0;
+    }
+
+    @Override
+    public int getInt(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getInt(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getIntValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getInt(key) : 0;
+    }
+
+    @Override
+    public int getInt(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getInt(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getIntValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getInt(key) : 0;
+    }
+
+    @Override
+    public int getInt(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getInt(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getIntValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getInt(key) : 0;
+    }
+
+    @Override
+    public long getLong(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getLong(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getLongValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getLong(key) : 0L;
+    }
+
+    @Override
+    public long getLong(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getLong(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getLongValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getLong(key) : 0L;
+    }
+
+    @Override
+    public long getLong(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getLong(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getLongValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getLong(key) : 0L;
+    }
+
+    @Override
+    public long getLong(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getLong(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getLongValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getLong(key) : 0L;
+    }
+
+    @Override
+    public double getDouble(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getDouble(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getDoubleValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getDouble(key) : Double.NaN;
+    }
+
+    @Override
+    public double getDouble(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getDouble(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getDoubleValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getDouble(key) : Double.NaN;
+    }
+
+    @Override
+    public double getDouble(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getDouble(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getDoubleValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getDouble(key) : Double.NaN;
+    }
+
+    @Override
+    public double getDouble(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getDouble(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getDoubleValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.getDouble(key) : Double.NaN;
+    }
+
+    @Override
+    public Object get(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getObject(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getObjectValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.get(key) : UNDEFINED;
+    }
+
+    @Override
+    public Object get(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getObject(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getObjectValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.get(key) : UNDEFINED;
+    }
+
+    @Override
+    public Object get(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getObject(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getObjectValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.get(key) : UNDEFINED;
+    }
+
+    @Override
+    public Object get(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return getArray().getObject(index);
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        if (find != null) {
+            return getObjectValue(find);
+        }
+
+        final ScriptObject proto = this.getProto();
+
+        return proto != null ? proto.get(key) : UNDEFINED;
+    }
+
+    /**
+     * Handle when an array doesn't have a slot - possibly grow and/or convert array.
+     *
+     * @param index  key as index
+     * @param value  element value
+     * @param strict are we in strict mode
+     */
+    private void doesNotHave(final int index, final Object value, final boolean strict) {
+        final long oldLength = getArray().length();
+        final long longIndex = index & 0xffff_ffffL;
+
+        if (!getArray().has(index)) {
+            final String key = convertKey(longIndex);
+            final FindProperty find = findProperty(key, true);
+
+            if (find != null) {
+                setObject(find, strict, key, value);
+                return;
+            }
+        }
+
+        if (longIndex >= oldLength) {
+            if (!isExtensible()) {
+                if (strict) {
+                    throw typeError("object.non.extensible", JSType.toString(index), ScriptRuntime.safeToString(this));
+                }
+                return;
+            }
+            setArray(getArray().ensure(longIndex));
+        }
+
+        if (value instanceof Integer) {
+            setArray(getArray().set(index, (int)value, strict));
+        } else if (value instanceof Long) {
+            setArray(getArray().set(index, (long)value, strict));
+        } else if (value instanceof Double) {
+            setArray(getArray().set(index, (double)value, strict));
+        } else {
+            setArray(getArray().set(index, value, strict));
+        }
+
+        if (longIndex > oldLength) {
+            ArrayData array = getArray();
+
+            if (array.canDelete(oldLength, (longIndex - 1), strict)) {
+                array = array.delete(oldLength, (longIndex - 1));
+            }
+
+            setArray(array);
+        }
+    }
+
+    /**
+     * This is the most generic of all Object setters. Most of the others use this in some form.
+     * TODO: should be further specialized
+     *
+     * @param find    found property
+     * @param strict  are we in strict mode
+     * @param key     property key
+     * @param value   property value
+     */
+    public final void setObject(final FindProperty find, final boolean strict, final String key, final Object value) {
+        FindProperty f = find;
+
+        if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) {
+            f = null;
+        }
+
+        MethodHandle setter;
+
+        if (f != null) {
+            if (!f.getProperty().isWritable()) {
+                if (strict) {
+                    throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this));
+                }
+
+                return;
+            }
+
+            setter = f.getSetter(Object.class, strict); //TODO specfields
+            try {
+                setter.invokeExact((Object)f.getOwner(), value);
+            } catch (final Error|RuntimeException e) {
+                throw e;
+            } catch (final Throwable e) {
+                throw new RuntimeException(e);
+            }
+        } else if (!isExtensible()) {
+            if (strict) {
+                throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
+            }
+        } else {
+            spill(key, value);
+        }
+    }
+
+    private void spill(final String key, final Object value) {
+        try {
+            addSpill(key).invokeExact((Object)this, value);
+        } catch (final Error|RuntimeException e) {
+            throw e;
+        } catch (final Throwable e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    @Override
+    public void set(final Object key, final int value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(key, JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final Object key, final long value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(key, JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final Object key, final double value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(key, JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final Object key, final Object value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        final String       propName = convertKey(key);
+        final FindProperty find     = findProperty(propName, true);
+
+        setObject(find, strict, propName, value);
+    }
+
+    @Override
+    public void set(final double key, final int value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final double key, final long value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final double key, final double value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final double key, final Object value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), value, strict);
+    }
+
+    @Override
+    public void set(final long key, final int value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final long key, final long value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final long key, final double value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final long key, final Object value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), value, strict);
+    }
+
+    @Override
+    public void set(final int key, final int value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final int key, final long value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final int key, final double value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), JSType.toObject(value), strict);
+    }
+
+    @Override
+    public void set(final int key, final Object value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            if (getArray().has(index)) {
+                setArray(getArray().set(index, value, strict));
+            } else {
+                doesNotHave(index, value, strict);
+            }
+
+            return;
+        }
+
+        set(JSType.toObject(key), value, strict);
+    }
+
+    @Override
+    public boolean has(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            for (ScriptObject self = this; self != null; self = self.getProto()) {
+                if (self.getArray().has(index)) {
+                    return true;
+                }
+            }
+        }
+
+        final FindProperty find = findProperty(convertKey(key), true);
+
+        return find != null;
+    }
+
+    @Override
+    public boolean has(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            for (ScriptObject self = this; self != null; self = self.getProto()) {
+                if (self.getArray().has(index)) {
+                    return true;
+                }
+            }
+        }
+
+        final FindProperty find = findProperty(convertKey(key), true);
+
+        return find != null;
+    }
+
+    @Override
+    public boolean has(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            for (ScriptObject self = this; self != null; self = self.getProto()) {
+                if (self.getArray().has(index)) {
+                    return true;
+                }
+            }
+        }
+
+        final FindProperty find = findProperty(convertKey(key), true);
+
+        return find != null;
+    }
+
+    @Override
+    public boolean has(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (isValidArrayIndex(index)) {
+            for (ScriptObject self = this; self != null; self = self.getProto()) {
+                if (self.getArray().has(index)) {
+                    return true;
+                }
+            }
+        }
+
+        final FindProperty find = findProperty(convertKey(key), true);
+
+        return find != null;
+    }
+
+    @Override
+    public boolean hasOwnProperty(final Object key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return true;
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        return find != null;
+    }
+
+    @Override
+    public boolean hasOwnProperty(final int key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return true;
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        return find != null;
+    }
+
+    @Override
+    public boolean hasOwnProperty(final long key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return true;
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        return find != null;
+    }
+
+    @Override
+    public boolean hasOwnProperty(final double key) {
+        final int index = getArrayIndexNoThrow(key);
+
+        if (getArray().has(index)) {
+            return true;
+        }
+
+        final FindProperty find = findProperty(convertKey(key), false);
+
+        return find != null;
+    }
+
+    @Override
+    public boolean delete(final int key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        final ArrayData array = getArray();
+
+        if (array.has(index)) {
+            if (array.canDelete(index, strict)) {
+                setArray(array.delete(index));
+                return true;
+            }
+            return false;
+        }
+
+        return deleteObject(JSType.toObject(key), strict);
+    }
+
+    @Override
+    public boolean delete(final long key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        final ArrayData array = getArray();
+
+        if (array.has(index)) {
+            if (array.canDelete(index, strict)) {
+                setArray(array.delete(index));
+                return true;
+            }
+            return false;
+        }
+
+        return deleteObject(JSType.toObject(key), strict);
+    }
+
+    @Override
+    public boolean delete(final double key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        final ArrayData array = getArray();
+
+        if (array.has(index)) {
+            if (array.canDelete(index, strict)) {
+                setArray(array.delete(index));
+                return true;
+            }
+            return false;
+        }
+
+        return deleteObject(JSType.toObject(key), strict);
+    }
+
+    @Override
+    public boolean delete(final Object key, final boolean strict) {
+        final int index = getArrayIndexNoThrow(key);
+        final ArrayData array = getArray();
+
+        if (array.has(index)) {
+            if (array.canDelete(index, strict)) {
+                setArray(array.delete(index));
+                return true;
+            }
+            return false;
+        }
+
+        return deleteObject(key, strict);
+    }
+
+    private boolean deleteObject(final Object key, final boolean strict) {
+        final String propName = convertKey(key);
+        final FindProperty find = findProperty(propName, false);
+
+        if (find == null) {
+            return true;
+        }
+
+        if (!find.getProperty().isConfigurable()) {
+            if (strict) {
+                throw typeError("cant.delete.property", propName, ScriptRuntime.safeToString(this));
+            }
+            return false;
+        }
+
+        final Property prop = find.getProperty();
+        notifyPropertyDeleted(this, prop);
+        deleteOwnProperty(prop);
+
+        return true;
+    }
+
+    /*
+     * Embed management
+     */
+
+    /** Number of embed slots */
+    public static final int EMBED_SIZE   = 4;
+    /** Embed offset */
+    public static final int EMBED_OFFSET = 32 - EMBED_SIZE;
+
+    static final MethodHandle[] GET_EMBED;
+    static final MethodHandle[] SET_EMBED;
+
+    static {
+        GET_EMBED = new MethodHandle[EMBED_SIZE];
+        SET_EMBED = new MethodHandle[EMBED_SIZE];
+
+        for (int i = 0; i < EMBED_SIZE; i++) {
+            final String name = "embed" + i;
+            GET_EMBED[i] = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, name, Object.class), Lookup.GET_OBJECT_TYPE);
+            SET_EMBED[i] = MH.asType(MH.setter(MethodHandles.lookup(), ScriptObject.class, name, Object.class), Lookup.SET_OBJECT_TYPE);
+        }
+    }
+
+    void useEmbed(final int i) {
+        flags |= 1 << (EMBED_OFFSET + i);
+    }
+
+    int findEmbed() {
+        final int bits  = ~(flags >>> EMBED_OFFSET);
+        final int least = bits ^ -bits;
+        final int index = Integer.numberOfTrailingZeros(least) - 1;
+
+        return index;
+    }
+
+    /*
+     * Make a new UserAccessorProperty property. getter and setter functions are stored in
+     * this ScriptObject and slot values are used in property object.
+     */
+    private UserAccessorProperty newUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
+        int oldSpillLength = getMap().getSpillLength();
+
+        int getterSlot = findEmbed();
+        if (getterSlot >= EMBED_SIZE) {
+            getterSlot = oldSpillLength + EMBED_SIZE;
+            ++oldSpillLength;
+        } else {
+            useEmbed(getterSlot);
+        }
+        setEmbedOrSpill(getterSlot, getter);
+        // if getter function is null, flag the slot to be negative (less by 1)
+        if (getter == null) {
+            getterSlot = -getterSlot - 1;
+        }
+
+        int setterSlot = findEmbed();
+        if (setterSlot >= EMBED_SIZE) {
+            setterSlot = oldSpillLength + EMBED_SIZE;
+        } else {
+            useEmbed(setterSlot);
+        }
+        setEmbedOrSpill(setterSlot, setter);
+        // if setter function is null, flag the slot to be negative (less by 1)
+        if (setter == null) {
+            setterSlot = -setterSlot - 1;
+        }
+
+        return new UserAccessorProperty(key, propertyFlags, getterSlot, setterSlot);
+    }
+
+    private void setEmbedOrSpill(final int slot, final Object value) {
+        switch (slot) {
+        case 0:
+            embed0 = value;
+            break;
+        case 1:
+            embed1 = value;
+            break;
+        case 2:
+            embed2 = value;
+            break;
+        case 3:
+            embed3 = value;
+            break;
+        default:
+            if (slot >= 0) {
+                final int index = (slot - EMBED_SIZE);
+                if (spill == null) {
+                    // create new spill.
+                    spill = new Object[Math.max(index + 1, SPILL_RATE)];
+                } else if (index >= spill.length) {
+                    // grow spill as needed
+                    final Object[] newSpill = new Object[index + 1];
+                    System.arraycopy(spill, 0, newSpill, 0, spill.length);
+                    spill = newSpill;
+                }
+
+                spill[index] = value;
+            }
+            break;
+        }
+    }
+
+    // user accessors are either stored in embed fields or spill array slots
+    // get the accessor value using slot number. Note that slot is either embed
+    // field number or (spill array index + embedSize).
+    Object getEmbedOrSpill(final int slot) {
+        switch (slot) {
+        case 0:
+            return embed0;
+        case 1:
+            return embed1;
+        case 2:
+            return embed2;
+        case 3:
+            return embed3;
+        default:
+            final int index = (slot - EMBED_SIZE);
+            return (index < 0 || (index >= spill.length)) ? null : spill[index];
+        }
+    }
+
+    // User defined getter and setter are always called by "dyn:call". Note that the user
+    // getter/setter may be inherited. If so, proto is bound during lookup. In either
+    // inherited or self case, slot is also bound during lookup. Actual ScriptFunction
+    // to be called is retrieved everytime and applied.
+    @SuppressWarnings("unused")
+    private static Object userAccessorGetter(final ScriptObject proto, final int slot, final Object self) {
+        final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
+        final Object       func      = container.getEmbedOrSpill(slot);
+
+        if (func instanceof ScriptFunction) {
+            try {
+                return INVOKE_UA_GETTER.invokeExact(func, self);
+            } catch(final Error|RuntimeException t) {
+                throw t;
+            } catch(final Throwable t) {
+                throw new RuntimeException(t);
+            }
+        }
+
+        return UNDEFINED;
+    }
+
+    @SuppressWarnings("unused")
+    private static void userAccessorSetter(final ScriptObject proto, final int slot, final String name, final Object self, final Object value) {
+        final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
+        final Object       func      = container.getEmbedOrSpill(slot);
+
+        if (func instanceof ScriptFunction) {
+            try {
+                INVOKE_UA_SETTER.invokeExact(func, self, value);
+            } catch(final Error|RuntimeException t) {
+                throw t;
+            } catch(final Throwable t) {
+                throw new RuntimeException(t);
+            }
+        }  else if (name != null) {
+            throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
+        }
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        final Class<?>   own = ScriptObject.class;
+        final MethodType mt  = MH.type(rtype, types);
+        try {
+            return MH.findStatic(MethodHandles.lookup(), own, name, mt);
+        } catch (final MethodHandleFactory.LookupException e) {
+            return MH.findVirtual(MethodHandles.lookup(), own, name, mt);
+        }
+    }
+
+    private static MethodHandle getKnownFunctionPropertyGuard(final PropertyMap map, final MethodHandle getter, final Object where, final ScriptFunction func) {
+        return MH.insertArguments(KNOWNFUNCPROPGUARD, 1, map, getter, where, func);
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean knownFunctionPropertyGuard(final Object self, final PropertyMap map, final MethodHandle getter, final Object where, final ScriptFunction func) {
+        if (self instanceof ScriptObject && ((ScriptObject)self).getMap() == map) {
+            try {
+                return getter.invokeExact(where) == func;
+            } catch (final RuntimeException | Error e) {
+                throw e;
+            } catch (final Throwable t) {
+                throw new RuntimeException(t);
+            }
+        }
+
+        return false;
+    }
+
+    /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created */
+    private static int count;
+
+    /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created that are scope */
+    private static int scopeCount;
+
+    /**
+     * Get number of {@code ScriptObject} instances created. If not running in debug
+     * mode this is always 0
+     *
+     * @return number of ScriptObjects created
+     */
+    public static int getCount() {
+        return count;
+    }
+
+    /**
+     * Get number of scope {@code ScriptObject} instances created. If not running in debug
+     * mode this is always 0
+     *
+     * @return number of scope ScriptObjects created
+     */
+    public static int getScopeCount() {
+        return scopeCount;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
new file mode 100644
index 0000000..216b381
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
@@ -0,0 +1,909 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
+import static jdk.nashorn.internal.runtime.ECMAErrors.syntaxError;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Array;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import jdk.internal.dynalink.beans.StaticClass;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.ir.debug.JSONWriter;
+import jdk.nashorn.internal.parser.Lexer;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+
+/**
+ * Utilities to be called by JavaScript runtime API and generated classes.
+ */
+
+public final class ScriptRuntime {
+    private ScriptRuntime() {
+    }
+
+    /** Singleton representing the empty array object '[]' */
+    public static final Object[] EMPTY_ARRAY = new Object[0];
+
+    /** Unique instance of undefined. */
+    public static final Undefined UNDEFINED = Undefined.getUndefined();
+
+    /**
+     * Unique instance of undefined used to mark empty array slots.
+     * Can't escape the array.
+     */
+    public static final Undefined EMPTY = Undefined.getEmpty();
+
+    /** Method handle to generic + operator, operating on objects */
+    public static final Call ADD = staticCallNoLookup(ScriptRuntime.class, "ADD", Object.class, Object.class, Object.class);
+
+    /** Method handle to generic === operator, operating on objects */
+    public static final Call EQ_STRICT = staticCallNoLookup(ScriptRuntime.class, "EQ_STRICT", boolean.class, Object.class, Object.class);
+
+    /** Method handle used to enter a {@code with} scope at runtime. */
+    public static final Call OPEN_WITH = staticCallNoLookup(ScriptRuntime.class, "openWith", ScriptObject.class, ScriptObject.class, Object.class);
+
+    /** Method handle used to exit a {@code with} scope at runtime. */
+    public static final Call CLOSE_WITH = staticCallNoLookup(ScriptRuntime.class, "closeWith", ScriptObject.class, ScriptObject.class);
+
+    /**
+     * Method used to place a scope's variable into the Global scope, which has to be done for the
+     * properties declared at outermost script level.
+     */
+    public static final Call MERGE_SCOPE = staticCallNoLookup(ScriptRuntime.class, "mergeScope", ScriptObject.class, ScriptObject.class);
+
+    /**
+     * Return an appropriate iterator for the elements in a for-in construct
+     */
+    public static final Call TO_PROPERTY_ITERATOR = staticCallNoLookup(ScriptRuntime.class, "toPropertyIterator", Iterator.class, Object.class);
+
+    /**
+     * Return an appropriate iterator for the elements in a for-each construct
+     */
+    public static final Call TO_VALUE_ITERATOR = staticCallNoLookup(ScriptRuntime.class, "toValueIterator", Iterator.class, Object.class);
+
+    /**
+      * Method handle for apply. Used from {@link ScriptFunction} for looking up calls to
+      * call sites that are known to be megamorphic. Using an invoke dynamic here would
+      * lead to the JVM deoptimizing itself to death
+      */
+    public static final Call APPLY = staticCall(ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
+
+    /**
+     * Converts a switch tag value to a simple integer. deflt value if it can't.
+     *
+     * @param tag   Switch statement tag value.
+     * @param deflt default to use if not convertible.
+     * @return int tag value (or deflt.)
+     */
+    public static int switchTagAsInt(final Object tag, final int deflt) {
+        if (tag instanceof Number) {
+            final double d = ((Number)tag).doubleValue();
+            if (isRepresentableAsInt(d)) {
+                return (int)d;
+            }
+        }
+
+        return deflt;
+    }
+
+    /**
+     * Converts a switch tag value to a simple integer. deflt value if it can't.
+     *
+     * @param tag   Switch statement tag value.
+     * @param deflt default to use if not convertible.
+     * @return int tag value (or deflt.)
+     */
+    public static int switchTagAsInt(final long tag, final int deflt) {
+        return isRepresentableAsInt(tag) ? (int)tag : deflt;
+    }
+
+    /**
+     * Converts a switch tag value to a simple integer. deflt value if it can't.
+     *
+     * @param tag   Switch statement tag value.
+     * @param deflt default to use if not convertible.
+     * @return int tag value (or deflt.)
+     */
+    public static int switchTagAsInt(final double tag, final int deflt) {
+        return isRepresentableAsInt(tag) ? (int)tag : deflt;
+    }
+
+    /**
+     * This is the builtin implementation of {@code Object.prototype.toString}
+     * @param self reference
+     * @return string representation as object
+     */
+    public static String builtinObjectToString(final Object self) {
+        String className;
+        // Spec tells us to convert primitives by ToObject..
+        // But we don't need to -- all we need is the right class name
+        // of the corresponding primitive wrapper type.
+
+        final JSType type = JSType.of(self);
+
+        switch (type) {
+        case BOOLEAN:
+            className = "Boolean";
+            break;
+        case NUMBER:
+            className = "Number";
+            break;
+        case STRING:
+            className = "String";
+            break;
+        // special case of null and undefined
+        case NULL:
+            className = "Null";
+            break;
+        case UNDEFINED:
+            className = "Undefined";
+            break;
+        case OBJECT:
+        case FUNCTION:
+            if (self instanceof ScriptObject) {
+                className = ((ScriptObject)self).getClassName();
+            } else {
+                className = self.getClass().getName();
+            }
+            break;
+        default:
+            // Nashorn extension: use Java class name
+            className = self.getClass().getName();
+            break;
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        sb.append("[object ");
+        sb.append(className);
+        sb.append(']');
+
+        return sb.toString();
+    }
+
+    /**
+     * This is called whenever runtime wants to throw an error and wants to provide
+     * meaningful information about an object. We don't want to call toString which
+     * ends up calling "toString" from script world which may itself throw error.
+     * When we want to throw an error, we don't additional error from script land
+     * -- which may sometimes lead to infinite recursion.
+     *
+     * @param obj Object to converted to String safely (without calling user script)
+     * @return safe String representation of the given object
+     */
+    public static String safeToString(final Object obj) {
+        return JSType.toStringImpl(obj, true);
+    }
+
+    /**
+     * Used to determine property iterator used in for in.
+     * @param obj Object to iterate on.
+     * @return Iterator.
+     */
+    public static Iterator<String> toPropertyIterator(final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).propertyIterator();
+        }
+
+        if (obj != null && obj.getClass().isArray()) {
+            final int length = Array.getLength(obj);
+
+            return new Iterator<String>() {
+                private int index = 0;
+
+                @Override
+                public boolean hasNext() {
+                    return index < length;
+                }
+
+                @Override
+                public String next() {
+                    return "" + index++; //TODO numeric property iterator?
+                }
+
+                @Override
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+        }
+
+        return Collections.emptyIterator();
+    }
+
+    /**
+     * Used to determine property value iterator used in for each in.
+     * @param obj Object to iterate on.
+     * @return Iterator.
+     */
+    public static Iterator<?> toValueIterator(final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).valueIterator();
+        }
+
+        if (obj != null && obj.getClass().isArray()) {
+            final Object array  = obj;
+            final int    length = Array.getLength(obj);
+
+            return new Iterator<Object>() {
+                private int index = 0;
+
+                @Override
+                public boolean hasNext() {
+                    return index < length;
+                }
+
+                @Override
+                public Object next() {
+                    if (index >= length) {
+                        throw new NoSuchElementException();
+                    }
+                    return Array.get(array, index++);
+                }
+
+                @Override
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+        }
+
+        if (obj instanceof Iterable) {
+            return ((Iterable<?>)obj).iterator();
+        }
+
+        return Collections.emptyIterator();
+    }
+
+    /**
+     * Merge a scope into its prototype's map.
+     * Merge a scope into its prototype.
+     *
+     * @param scope Scope to merge.
+     * @return prototype object after merge
+     */
+    public static ScriptObject mergeScope(final ScriptObject scope) {
+        final ScriptObject global = scope.getProto();
+        global.addBoundProperties(scope);
+        return global;
+    }
+
+    /**
+     * Check that the target function is associated with current Context. And also make sure that 'self', if
+     * ScriptObject, is from current context.
+     *
+     * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve
+     * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker}
+     * for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead.
+     *
+     * @param target ScriptFunction object.
+     * @param self   Receiver in call.
+     * @param args   Call arguments.
+     * @return Call result.
+     */
+    public static Object checkAndApply(final ScriptFunction target, final Object self, final Object... args) {
+        final ScriptObject global = Context.getGlobalTrusted();
+        if (! (global instanceof GlobalObject)) {
+            throw new IllegalStateException("No current global set");
+        }
+
+        if (target.getContext() != global.getContext()) {
+            throw new IllegalArgumentException("'target' function is not from current Context");
+        }
+
+        if (self instanceof ScriptObject && ((ScriptObject)self).getContext() != global.getContext()) {
+            throw new IllegalArgumentException("'self' object is not from current Context");
+        }
+
+        // all in order - call real 'apply'
+        return apply(target, self, args);
+    }
+
+    /**
+     * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve
+     * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker}
+     * for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead.
+     *
+     * @param target ScriptFunction object.
+     * @param self   Receiver in call.
+     * @param args   Call arguments.
+     * @return Call result.
+     */
+    public static Object apply(final ScriptFunction target, final Object self, final Object... args) {
+        try {
+            return target.invoke(self, args);
+        } catch (final RuntimeException | Error e) {
+            throw e;
+        } catch (final Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    /**
+     * Generic implementation of ECMA 9.12 - SameValue algorithm
+     *
+     * @param x first value to compare
+     * @param y second value to compare
+     *
+     * @return true if both objects have the same value
+     */
+    public static boolean sameValue(final Object x, final Object y) {
+        final JSType xType = JSType.of(x);
+        final JSType yType = JSType.of(y);
+
+        if (xType != yType) {
+            return false;
+        }
+
+        if (xType == JSType.UNDEFINED || xType == JSType.NULL) {
+            return true;
+        }
+
+        if (xType == JSType.NUMBER) {
+            final double xVal = ((Number)x).doubleValue();
+            final double yVal = ((Number)y).doubleValue();
+
+            if (Double.isNaN(xVal) && Double.isNaN(yVal)) {
+                return true;
+            }
+
+            // checking for xVal == -0.0 and yVal == +0.0 or vice versa
+            if (xVal == 0.0 && (Double.doubleToLongBits(xVal) != Double.doubleToLongBits(yVal))) {
+                return false;
+            }
+
+            return xVal == yVal;
+        }
+
+        if (xType == JSType.STRING || yType == JSType.BOOLEAN) {
+            return x.equals(y);
+        }
+
+        return (x == y);
+    }
+
+    /**
+     * Returns AST as JSON compatible string. This is used to
+     * implement "parse" function in resources/parse.js script.
+     *
+     * @param code code to be parsed
+     * @param name name of the code source (used for location)
+     * @param includeLoc tells whether to include location information for nodes or not
+     * @return JSON string representation of AST of the supplied code
+     */
+    public static String parse(final String code, final String name, final boolean includeLoc) {
+        return JSONWriter.parse(Context.getContextTrusted().getEnv(), code, name, includeLoc);
+    }
+
+    /**
+     * Test whether a char is valid JavaScript whitespace
+     * @param ch a char
+     * @return true if valid JavaScript whitespace
+     */
+    public static boolean isJSWhitespace(final char ch) {
+        return Lexer.isJSWhitespace(ch);
+    }
+
+    /**
+     * Entering a {@code with} node requires new scope. This is the implementation
+     *
+     * @param scope      existing scope
+     * @param expression expression in with
+     *
+     * @return {@link WithObject} that is the new scope
+     */
+    public static ScriptObject openWith(final ScriptObject scope, final Object expression) {
+        final ScriptObject global = Context.getGlobalTrusted();
+        if (expression == UNDEFINED) {
+            throw typeError(global, "cant.apply.with.to.undefined");
+        } else if (expression == null) {
+            throw typeError(global, "cant.apply.with.to.null");
+        }
+
+        final ScriptObject withObject = new WithObject(scope, JSType.toScriptObject(global, expression));
+
+        return withObject;
+    }
+
+    /**
+     * Exiting a {@code with} node requires restoring scope. This is the implementation
+     *
+     * @param scope existing scope
+     *
+     * @return restored scope
+     */
+    public static ScriptObject closeWith(final ScriptObject scope) {
+        if (scope instanceof WithObject) {
+            return scope.getProto();
+        }
+        return scope;
+    }
+
+    /**
+     * ECMA 11.6.1 - The addition operator (+) - generic implementation
+     * Compiler specializes using {@link jdk.nashorn.internal.codegen.RuntimeCallSite}
+     * if any type information is available for any of the operands
+     *
+     * @param x  first term
+     * @param y  second term
+     *
+     * @return result of addition
+     */
+    public static Object ADD(final Object x, final Object y) {
+        // This prefix code to handle Number special is for optimization.
+        final boolean xIsNumber = x instanceof Number;
+        final boolean yIsNumber = y instanceof Number;
+
+        if (xIsNumber && yIsNumber) {
+             return ((Number)x).doubleValue() + ((Number)y).doubleValue();
+        }
+
+        final boolean xIsUndefined = x == UNDEFINED;
+        final boolean yIsUndefined = y == UNDEFINED;
+
+        if ((xIsNumber && yIsUndefined) || (xIsUndefined && yIsNumber) || (xIsUndefined && yIsUndefined)) {
+            return Double.NaN;
+        }
+
+        // code below is as per the spec.
+        final Object xPrim = JSType.toPrimitive(x);
+        final Object yPrim = JSType.toPrimitive(y);
+
+        if (xPrim instanceof String || yPrim instanceof String
+                || xPrim instanceof ConsString || yPrim instanceof ConsString) {
+            return new ConsString(JSType.toCharSequence(xPrim), JSType.toCharSequence(yPrim));
+        }
+
+        return JSType.toNumber(xPrim) + JSType.toNumber(yPrim);
+    }
+
+    /**
+     * Debugger hook.
+     * TODO: currently unimplemented
+     *
+     * @return undefined
+     */
+    public static Object DEBUGGER() {
+        return UNDEFINED;
+    }
+
+    /**
+     * New hook
+     *
+     * @param clazz type for the clss
+     * @param args  constructor arguments
+     *
+     * @return undefined
+     */
+    public static Object NEW(final Object clazz, final Object... args) {
+        return UNDEFINED;
+    }
+
+    /**
+     * ECMA 11.4.3 The typeof Operator - generic implementation
+     *
+     * @param object   the object from which to retrieve property to type check
+     * @param property property in object to check
+     *
+     * @return type name
+     */
+    public static Object TYPEOF(final Object object, final Object property) {
+        Object obj = object;
+
+        if (property != null) {
+            if (obj instanceof ScriptObject) {
+                obj = ((ScriptObject)obj).get(property);
+            } else if (object instanceof Undefined) {
+                obj = ((Undefined)obj).get(property);
+            } else if (object == null) {
+                throw typeError("cant.get.property", safeToString(property), "null");
+            } else if (JSType.isPrimitive(obj)) {
+                obj = ((ScriptObject)JSType.toScriptObject(obj)).get(property);
+            } else {
+                obj = UNDEFINED;
+            }
+        }
+
+        return JSType.of(obj).typeName();
+    }
+
+    /**
+     * ECMA 11.4.2 - void operator
+     *
+     * @param object object to evaluate
+     *
+     * @return Undefined as the object type
+     */
+    public static Object VOID(final Object object) {
+        if (object instanceof Number) {
+            if (Double.isNaN(((Number)object).doubleValue())) {
+                return Double.NaN;
+            }
+        }
+
+        return UNDEFINED;
+    }
+
+    /**
+     * Throw ReferenceError when LHS of assignment or increment/decrement
+     * operator is not an assignable node (say a literal)
+     *
+     * @param lhs Evaluated LHS
+     * @param rhs Evaluated RHS
+     * @param msg Additional LHS info for error message
+     * @return undefined
+     */
+    public static Object REFERENCE_ERROR(final Object lhs, final Object rhs, final Object msg) {
+        throw referenceError("cant.be.used.as.lhs", Objects.toString(msg));
+    }
+
+    /**
+     * ECMA 11.4.1 - delete operation, generic implementation
+     *
+     * @param obj       object with property to delete
+     * @param property  property to delete
+     * @param strict    are we in strict mode
+     *
+     * @return true if property was successfully found and deleted
+     */
+    public static boolean DELETE(final Object obj, final Object property, final Object strict) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).delete(property, Boolean.TRUE.equals(strict));
+        }
+
+        if (obj instanceof Undefined) {
+            return ((Undefined)obj).delete(property, false);
+        }
+
+        if (obj == null) {
+            throw typeError("cant.delete.property", safeToString(property), "null");
+        }
+
+        if (JSType.isPrimitive(obj)) {
+            return ((ScriptObject) JSType.toScriptObject(obj)).delete(property, Boolean.TRUE.equals(strict));
+        }
+
+        // if object is not reference type, vacuously delete is successful.
+        return true;
+    }
+
+    /**
+     * ECMA 11.4.1 - delete operator, special case
+     *
+     * This is 'delete' that always fails. We have to check strict mode and throw error.
+     * That is why this is a runtime function. Or else we could have inlined 'false'.
+     *
+     * @param property  property to delete
+     * @param strict    are we in strict mode
+     *
+     * @return false always
+     */
+    public static boolean FAIL_DELETE(final Object property, final Object strict) {
+        if (Boolean.TRUE.equals(strict)) {
+            throw syntaxError("strict.cant.delete", safeToString(property));
+        }
+        return false;
+    }
+
+    /**
+     * ECMA 11.9.1 - The equals operator (==) - generic implementation
+     *
+     * @param x first object to compare
+     * @param y second object to compare
+     *
+     * @return true if type coerced versions of objects are equal
+     */
+    public static boolean EQ(final Object x, final Object y) {
+        return equals(x, y);
+    }
+
+    /**
+     * ECMA 11.9.2 - The does-not-equal operator (==) - generic implementation
+     *
+     * @param x first object to compare
+     * @param y second object to compare
+     *
+     * @return true if type coerced versions of objects are not equal
+     */
+    public static boolean NE(final Object x, final Object y) {
+        return !EQ(x, y);
+    }
+
+    /** ECMA 11.9.3 The Abstract Equality Comparison Algorithm */
+    private static boolean equals(final Object x, final Object y) {
+        final JSType xType = JSType.of(x);
+        final JSType yType = JSType.of(y);
+
+        if (xType == yType) {
+
+            if (xType == JSType.UNDEFINED || xType == JSType.NULL) {
+                return true;
+            }
+
+            if (xType == JSType.NUMBER) {
+                final double xVal = ((Number)x).doubleValue();
+                final double yVal = ((Number)y).doubleValue();
+                if (Double.isNaN(xVal) || Double.isNaN(yVal)) {
+                    return false;
+                }
+
+                return xVal == yVal;
+            }
+
+            if (xType == JSType.STRING) {
+                // String may be represented by ConsString
+                return x.toString().equals(y.toString());
+            }
+
+            if (xType == JSType.BOOLEAN) {
+                // Boolean comparison
+                return x.equals(y);
+            }
+
+            return x == y;
+        }
+
+        if ((xType == JSType.UNDEFINED && yType == JSType.NULL) ||
+            (xType == JSType.NULL && yType == JSType.UNDEFINED)) {
+            return true;
+        }
+
+        if (xType == JSType.NUMBER && yType == JSType.STRING) {
+            return EQ(x, JSType.toNumber(y));
+        }
+
+        if (xType == JSType.STRING && yType == JSType.NUMBER) {
+            return EQ(JSType.toNumber(x), y);
+        }
+
+        if (xType == JSType.BOOLEAN) {
+            return EQ(JSType.toNumber(x), y);
+        }
+
+        if (yType == JSType.BOOLEAN) {
+            return EQ(x, JSType.toNumber(y));
+        }
+
+        if ((xType == JSType.STRING || xType == JSType.NUMBER) &&
+             (y instanceof ScriptObject))  {
+            return EQ(x, JSType.toPrimitive(y));
+        }
+
+        if ((x instanceof ScriptObject) &&
+            (yType == JSType.STRING || yType == JSType.NUMBER)) {
+            return EQ(JSType.toPrimitive(x), y);
+        }
+
+        return false;
+    }
+
+    /**
+     * ECMA 11.9.4 - The strict equal operator (===) - generic implementation
+     *
+     * @param x first object to compare
+     * @param y second object to compare
+     *
+     * @return true if objects are equal
+     */
+    public static boolean EQ_STRICT(final Object x, final Object y) {
+        return strictEquals(x, y);
+    }
+
+    /**
+     * ECMA 11.9.5 - The strict non equal operator (!==) - generic implementation
+     *
+     * @param x first object to compare
+     * @param y second object to compare
+     *
+     * @return true if objects are not equal
+     */
+    public static boolean NE_STRICT(final Object x, final Object y) {
+        return !EQ_STRICT(x, y);
+    }
+
+    /** ECMA 11.9.6 The Strict Equality Comparison Algorithm */
+    private static boolean strictEquals(final Object x, final Object y) {
+        final JSType xType = JSType.of(x);
+        final JSType yType = JSType.of(y);
+
+        if (xType != yType) {
+            return false;
+        }
+
+        if (xType == JSType.UNDEFINED || xType == JSType.NULL) {
+            return true;
+        }
+
+        if (xType == JSType.NUMBER) {
+            final double xVal = ((Number)x).doubleValue();
+            final double yVal = ((Number)y).doubleValue();
+
+            if (Double.isNaN(xVal) || Double.isNaN(yVal)) {
+                return false;
+            }
+
+            return xVal == yVal;
+        }
+
+        if (xType == JSType.STRING) {
+            // String may be represented by ConsString
+            return x.toString().equals(y.toString());
+        }
+
+        if (xType == JSType.BOOLEAN) {
+            return x.equals(y);
+        }
+
+        // finally, the object identity comparison
+        return x == y;
+    }
+
+    /**
+     * ECMA 11.8.6 - The in operator - generic implementation
+     *
+     * @param property property to check for
+     * @param obj object in which to check for property
+     *
+     * @return true if objects are equal
+     */
+    public static boolean IN(final Object property, final Object obj) {
+        final JSType rvalType = JSType.of(obj);
+
+        if (rvalType == JSType.OBJECT || rvalType == JSType.FUNCTION) {
+            if (obj instanceof ScriptObject) {
+                return ((ScriptObject)obj).has(property);
+            }
+
+            return false;
+        }
+
+        throw typeError("in.with.non.object", rvalType.toString().toLowerCase());
+    }
+
+    /**
+     * ECMA 11.8.6 - The strict instanceof operator - generic implementation
+     *
+     * @param obj first object to compare
+     * @param clazz type to check against
+     *
+     * @return true if {@code obj} is an instanceof {@code clazz}
+     */
+    public static boolean INSTANCEOF(final Object obj, final Object clazz) {
+        if (clazz instanceof ScriptFunction) {
+            if (obj instanceof ScriptObject) {
+                return ((ScriptObject)clazz).isInstance((ScriptObject)obj);
+            }
+            return false;
+        }
+
+        if (clazz instanceof StaticClass) {
+            return ((StaticClass)clazz).getRepresentedClass().isInstance(obj);
+        }
+
+        throw typeError("instanceof.on.non.object");
+    }
+
+    /**
+     * ECMA 11.8.1 - The less than operator ({@literal <}) - generic implementation
+     *
+     * @param x first object to compare
+     * @param y second object to compare
+     *
+     * @return true if x is less than y
+     */
+    public static boolean LT(final Object x, final Object y) {
+        final Object value = lessThan(x, y, true);
+        return (value == UNDEFINED) ? false : (Boolean)value;
+    }
+
+    /**
+     * ECMA 11.8.2 - The greater than operator ({@literal >}) - generic implementation
+     *
+     * @param x first object to compare
+     * @param y second object to compare
+     *
+     * @return true if x is greater than y
+     */
+    public static boolean GT(final Object x, final Object y) {
+        final Object value = lessThan(y, x, false);
+        return (value == UNDEFINED) ? false : (Boolean)value;
+    }
+
+    /**
+     * ECMA 11.8.3 - The less than or equal operator ({@literal <=}) - generic implementation
+     *
+     * @param x first object to compare
+     * @param y second object to compare
+     *
+     * @return true if x is less than or equal to y
+     */
+    public static boolean LE(final Object x, final Object y) {
+        final Object value = lessThan(y, x, false);
+        return (!(Boolean.TRUE.equals(value) || value == UNDEFINED));
+    }
+
+    /**
+     * ECMA 11.8.4 - The greater than or equal operator ({@literal >=}) - generic implementation
+     *
+     * @param x first object to compare
+     * @param y second object to compare
+     *
+     * @return true if x is greater than or equal to y
+     */
+    public static boolean GE(final Object x, final Object y) {
+        final Object value = lessThan(x, y, true);
+        return (!(Boolean.TRUE.equals(value) || value == UNDEFINED));
+    }
+
+    /** ECMA 11.8.5 The Abstract Relational Comparison Algorithm */
+    private static Object lessThan(final Object x, final Object y, final boolean leftFirst) {
+        Object px, py;
+
+        //support e.g. x < y should throw exception correctly if x or y are not numeric
+        if (leftFirst) {
+            px = JSType.toPrimitive(x, Number.class);
+            py = JSType.toPrimitive(y, Number.class);
+        } else {
+            py = JSType.toPrimitive(y, Number.class);
+            px = JSType.toPrimitive(x, Number.class);
+        }
+
+        if (JSType.of(px) == JSType.STRING && JSType.of(py) == JSType.STRING) {
+            // May be String or ConsString
+            return (px.toString()).compareTo(py.toString()) < 0;
+        }
+
+        final double nx = JSType.toNumber(px);
+        final double ny = JSType.toNumber(py);
+
+        if (Double.isNaN(nx) || Double.isNaN(ny)) {
+            return UNDEFINED;
+        }
+
+        if (nx == ny) {
+            return false;
+        }
+
+        if (nx > 0 && ny > 0 && Double.isInfinite(nx) && Double.isInfinite(ny)) {
+            return false;
+        }
+
+        if (nx < 0 && ny < 0 && Double.isInfinite(nx) && Double.isInfinite(ny)) {
+            return false;
+        }
+
+        return nx < ny;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java
new file mode 100644
index 0000000..596ec1b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java
@@ -0,0 +1,208 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * Global functions supported only in scripting mode.
+ */
+public final class ScriptingFunctions {
+
+    /** Handle to implementation of {@link ScriptingFunctions#readLine} - Nashorn extension */
+    public static final MethodHandle READLINE = findOwnMH("readLine", Object.class, Object.class);
+
+    /** Handle to implementation of {@link ScriptingFunctions#readFully} - Nashorn extension */
+    public static final MethodHandle READFULLY = findOwnMH("readFully",     Object.class, Object.class, Object.class);
+
+    /** Handle to implementation of {@link ScriptingFunctions#exec} - Nashorn extension */
+    public static final MethodHandle EXEC = findOwnMH("exec",     Object.class, Object.class, Object.class, Object.class);
+
+    /** EXEC name - special property used by $EXEC API. */
+    public static final String EXEC_NAME = "$EXEC";
+
+    /** OUT name - special property used by $EXEC API. */
+    public static final String OUT_NAME  = "$OUT";
+
+    /** ERR name - special property used by $EXEC API. */
+    public static final String ERR_NAME  = "$ERR";
+
+    /** EXIT name - special property used by $EXEC API. */
+    public static final String EXIT_NAME = "$EXIT";
+
+    /** Names of special properties used by $ENV API. */
+    public  static final String ENV_NAME  = "$ENV";
+
+    private static final String PWD_NAME  = "PWD";
+
+    private ScriptingFunctions() {
+    }
+
+    /**
+     * Nashorn extension: global.readLine (scripting-mode-only)
+     * Read one line of input from the standard input.
+     *
+     * @param self self reference
+     *
+     * @return line that was read
+     *
+     * @throws IOException if an exception occurs
+     */
+    public static Object readLine(final Object self) throws IOException {
+        final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+        return reader.readLine();
+    }
+
+    /**
+     * Nashorn extension: Read the entire contents of a text file and return as String.
+     *
+     * @param self self reference
+     * @param file The input file whose content is read.
+     *
+     * @return String content of the input file.
+     *
+     * @throws IOException if an exception occurs
+     */
+    public static Object readFully(final Object self, final Object file) throws IOException {
+        File f = null;
+
+        if (file instanceof File) {
+            f = (File)file;
+        } else if (file instanceof String) {
+            f = new java.io.File((String)file);
+        }
+
+        if (f == null || !f.isFile()) {
+            throw typeError("not.a.file", ScriptRuntime.safeToString(file));
+        }
+
+        return new String(Source.readFully(f));
+    }
+
+    /**
+     * Nashorn extension: exec a string in a separate process.
+     *
+     * @param self   self reference
+     * @param string string to execute
+     * @param input  input
+     *
+     * @return output string from the request
+     * @throws IOException           if any stream access fails
+     * @throws InterruptedException  if execution is interrupted
+     */
+    public static Object exec(final Object self, final Object string, final Object input) throws IOException, InterruptedException {
+        // Current global is need to fetch additional inputs and for additional results.
+        final ScriptObject global = Context.getGlobal();
+
+        // Break exec string into tokens.
+        final StringTokenizer tokenizer = new StringTokenizer(JSType.toString(string));
+        final String[] cmdArray = new String[tokenizer.countTokens()];
+        for (int i = 0; tokenizer.hasMoreTokens(); i++) {
+            cmdArray[i] = tokenizer.nextToken();
+        }
+
+        // Set up initial process.
+        final ProcessBuilder processBuilder = new ProcessBuilder(cmdArray);
+
+        // Current ENV property state.
+        final Object env = global.get(ENV_NAME);
+        if (env instanceof ScriptObject) {
+            final ScriptObject envProperties = (ScriptObject)env;
+
+            // If a working directory is present, use it.
+            final Object pwd = envProperties.get(PWD_NAME);
+            if (pwd != UNDEFINED) {
+                processBuilder.directory(new File(JSType.toString(pwd)));
+            }
+
+            // Set up ENV variables.
+            final Map<String, String> environment = processBuilder.environment();
+            environment.clear();
+            for (Map.Entry<Object, Object> entry : envProperties.entrySet()) {
+                environment.put(JSType.toString(entry.getKey()), JSType.toString(entry.getValue()));
+            }
+        }
+
+        // Start the process.
+        final Process process = processBuilder.start();
+
+        // If input is present, pass on to process.
+        try (OutputStream outputStream = process.getOutputStream()) {
+            if (input != UNDEFINED) {
+                outputStream.write(JSType.toString(input).getBytes());
+            }
+        }
+
+        // Wait for the process to complete.
+        final int exit = process.waitFor();
+
+        // Collect output.
+        String out;
+         try (InputStream inputStream = process.getInputStream()) {
+            final StringBuilder outBuffer = new StringBuilder();
+            for (int ch; (ch = inputStream.read()) != -1; ) {
+                outBuffer.append((char)ch);
+            }
+            out = outBuffer.toString();
+        }
+
+        // Collect errors.
+        String err;
+        try (InputStream errorStream = process.getErrorStream()) {
+            final StringBuilder errBuffer = new StringBuilder();
+            for (int ch; (ch = errorStream.read()) != -1; ) {
+                errBuffer.append((char)ch);
+            }
+            err = errBuffer.toString();
+        }
+
+        // Set globals for secondary results.
+        final boolean isStrict = global.isStrictContext();
+        global.set(OUT_NAME, out, isStrict);
+        global.set(ERR_NAME, err, isStrict);
+        global.set(EXIT_NAME, exit, isStrict);
+
+        // Return the result from stdout.
+        return out;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), ScriptingFunctions.class, name, MH.type(rtype, types));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
new file mode 100644
index 0000000..8012ce0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
@@ -0,0 +1,221 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
+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.lookup.Lookup;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+import jdk.nashorn.internal.runtime.linker.NashornGuards;
+
+
+/**
+ * Instances of this class are quite ephemeral; they only exist for the duration of an invocation of
+ * {@link ScriptObject#findSetMethod(CallSiteDescriptor, jdk.internal.dynalink.linker.LinkRequest)} and
+ * serve as the actual encapsulation of the algorithm for creating an appropriate property setter method.
+ */
+final class SetMethodCreator {
+    // See constructor parameters for description of fields
+    private final ScriptObject sobj;
+    private final PropertyMap map;
+    private final FindProperty find;
+    private final CallSiteDescriptor desc;
+
+    /**
+     * Creates a new property setter method creator.
+     * @param sobj the object for which we're creating the property setter
+     * @param find a result of a {@link ScriptObject#findProperty(String, boolean)} on the object for the property we
+     * want to create a setter for. Can be null if the property does not yet exist on the object.
+     * @param desc the descriptor of the call site that triggered the property setter lookup
+     */
+    SetMethodCreator(final ScriptObject sobj, final FindProperty find, final CallSiteDescriptor desc) {
+        this.sobj = sobj;
+        this.map = sobj.getMap();
+        this.find = find;
+        this.desc = desc;
+    }
+
+    private String getName() {
+        return desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+    }
+
+    private PropertyMap getMap() {
+        return map;
+    }
+
+    /**
+     * Creates the actual guarded invocation that represents the dynamic setter method for the property.
+     * @return the actual guarded invocation that represents the dynamic setter method for the property.
+     */
+    GuardedInvocation createGuardedInvocation() {
+        return createSetMethod().createGuardedInvocation();
+    }
+
+    /**
+     * This class encapsulates the results of looking up a setter method; it's basically a triple of a method hanle,
+     * a Property object, and flags for invocation.
+     *
+     */
+    private class SetMethod {
+        private final MethodHandle methodHandle;
+        private final Property property;
+
+        /**
+         * Creates a new lookup result.
+         * @param methodHandle the actual method handle
+         * @param property the property object. Can be null in case we're creating a new property in the global object.
+         */
+        SetMethod(final MethodHandle methodHandle, final Property property) {
+            assert methodHandle != null;
+            this.methodHandle = methodHandle;
+            this.property = property;
+        }
+
+        /**
+         * Composes from its components an actual guarded invocation that represents the dynamic setter method for the property.
+         * @return the composed guarded invocation that represents the dynamic setter method for the property.
+         */
+        GuardedInvocation createGuardedInvocation() {
+            return new GuardedInvocation(methodHandle, getGuard());
+        }
+
+        private MethodHandle getGuard() {
+            return needsNoGuard() ? null : NashornGuards.getMapGuard(getMap());
+        }
+
+        private boolean needsNoGuard() {
+            return NashornCallSiteDescriptor.isFastScope(desc) &&
+                    (ObjectClassGenerator.OBJECT_FIELDS_ONLY || isPropertyTypeStable());
+        }
+
+        private boolean isPropertyTypeStable() {
+            return property == null || !property.canChangeType();
+        }
+    }
+
+    private SetMethod createSetMethod() {
+        if (find != null) {
+            return createExistingPropertySetter();
+        }
+
+        checkStrictCreateNewVariable();
+
+        if (sobj.isScope()) {
+            return createGlobalPropertySetter();
+        }
+
+        return createNewPropertySetter();
+    }
+
+    private void checkStrictCreateNewVariable() {
+        // In strict mode, assignment can not create a new variable.
+        // See also ECMA Annex C item 4. ReferenceError is thrown.
+        if (NashornCallSiteDescriptor.isScope(desc) && NashornCallSiteDescriptor.isStrict(desc)) {
+            throw referenceError("not.defined", getName());
+        }
+    }
+
+    private SetMethod createExistingPropertySetter() {
+        final Property property = find.getProperty();
+        final Class<?> type = desc.getMethodType().parameterType(1);
+        final MethodHandle methodHandle = find.getSetter(type, NashornCallSiteDescriptor.isStrict(desc));
+
+        assert methodHandle != null;
+        assert property     != null;
+
+        final MethodHandle boundHandle;
+        if (!property.hasSetterFunction() && find.isInherited()) {
+            boundHandle = ScriptObject.bindTo(methodHandle, find.getOwner());
+        } else {
+            boundHandle = methodHandle;
+        }
+        return new SetMethod(boundHandle, property);
+    }
+
+    private SetMethod createGlobalPropertySetter() {
+        final ScriptObject global = Context.getGlobalTrusted();
+        return new SetMethod(ScriptObject.bindTo(global.addSpill(getName()), global), null);
+    }
+
+    private SetMethod createNewPropertySetter() {
+        final int nextEmbed = sobj.findEmbed();
+        final SetMethod sm;
+        if (nextEmbed >= ScriptObject.EMBED_SIZE) {
+            sm = createNewSpillPropertySetter();
+        } else {
+            sm = createNewEmbedPropertySetter(nextEmbed);
+        }
+
+        sobj.notifyPropertyAdded(sobj, sm.property);
+        return sm;
+    }
+
+    private SetMethod createNewSpillPropertySetter() {
+        final int nextSpill = getMap().getSpillLength();
+
+        final Property property = createSpillProperty(nextSpill);
+        return new SetMethod(createSpillMethodHandle(nextSpill, property), property);
+    }
+
+    private Property createSpillProperty(final int nextSpill) {
+        final MethodHandle getter = MH.asType(MH.insertArguments(MH.arrayElementGetter(Object[].class), 1, nextSpill), Lookup.GET_OBJECT_TYPE);
+        final MethodHandle setter = MH.asType(MH.insertArguments(MH.arrayElementSetter(Object[].class), 1, nextSpill), Lookup.SET_OBJECT_TYPE);
+
+        return new SpillProperty(getName(), Property.IS_SPILL, nextSpill, getter, setter);
+    }
+
+    private MethodHandle createSpillMethodHandle(final int nextSpill, Property property) {
+        final PropertyMap oldMap = getMap();
+        final PropertyMap newMap = getNewMap(property);
+
+        final Object[] spill = sobj.spill;
+        if (spill == null) {
+            return MH.insertArguments(ScriptObject.SETSPILLWITHNEW,  0, desc, oldMap, newMap, nextSpill);
+        } else if (nextSpill < spill.length) {
+            return MH.insertArguments(ScriptObject.SETSPILL,         0, desc, oldMap, newMap, nextSpill);
+        } else {
+            final int newLength = (nextSpill + ScriptObject.SPILL_RATE) / ScriptObject.SPILL_RATE * ScriptObject.SPILL_RATE;
+            return MH.insertArguments(ScriptObject.SETSPILLWITHGROW, 0, desc, oldMap, newMap, nextSpill, newLength);
+        }
+    }
+
+    private SetMethod createNewEmbedPropertySetter(final int nextEmbed) {
+        sobj.useEmbed(nextEmbed);
+        final Property property = new SpillProperty(getName(), 0, nextEmbed, ScriptObject.GET_EMBED[nextEmbed], ScriptObject.SET_EMBED[nextEmbed]);
+        //TODO specfields
+        final MethodHandle methodHandle = MH.insertArguments(ScriptObject.SETEMBED, 0, desc, getMap(), getNewMap(property), property.getSetter(Object.class, getMap()), nextEmbed);
+        return new SetMethod(methodHandle, property);
+    }
+
+    private PropertyMap getNewMap(Property property) {
+        return getMap().addProperty(property);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Source.java b/nashorn/src/jdk/nashorn/internal/runtime/Source.java
new file mode 100644
index 0000000..24c041a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Source.java
@@ -0,0 +1,449 @@
+/*
+ * 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;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOError;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Objects;
+import jdk.nashorn.internal.parser.Token;
+
+/**
+ * Source objects track the origin of JavaScript entities.
+ *
+ */
+public final class Source {
+    /**
+     * Descriptive name of the source as supplied by the user. Used for error
+     * reporting to the user. For example, SyntaxError will use this to print message.
+     * Used to implement __FILE__. Also used for SourceFile in .class for debugger usage.
+     */
+    private final String name;
+
+    /**
+     * Base directory the File or base part of the URL. Used to implement __DIR__.
+     * Used to load scripts relative to the 'directory' or 'base' URL of current script.
+     * This will be null when it can't be computed.
+     */
+    private final String base;
+
+    /** Cached source content. */
+    private final char[] content;
+
+    /** Length of source content. */
+    private final int length;
+
+    /** Cached hash code */
+    private int hash;
+
+    /** Source URL if available */
+    private final URL url;
+
+    private static final int BUFSIZE = 8 * 1024;
+
+    // Do *not* make this public ever! Trusts the URL and content. So has to be called
+    // from other public constructors. Note that this can not be some init method as
+    // we initialize final fields from here.
+    private Source(final String name, final String base, final char[] content, final URL url) {
+        this.name    = name;
+        this.base    = base;
+        this.content = content;
+        this.length  = content.length;
+        this.url     = url;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param name    source name
+     * @param content contents as char array
+     */
+    public Source(final String name, final char[] content) {
+        this(name, baseName(name, null), content, null);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param name    source name
+     * @param content contents as string
+     */
+    public Source(final String name, final String content) {
+        this(name, content.toCharArray());
+    }
+
+    /**
+     * Constructor
+     *
+     * @param name  source name
+     * @param url   url from which source can be loaded
+     *
+     * @throws IOException if source cannot be loaded
+     */
+    public Source(final String name, final URL url) throws IOException {
+        this(name, baseURL(url, null), readFully(url.openStream()), url);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param name  source name
+     * @param file  file from which source can be loaded
+     *
+     * @throws IOException if source cannot be loaded
+     */
+    public Source(final String name, final File file) throws IOException {
+        this(name, dirName(file, null), readFully(file), getURLFromFile(file));
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (!(obj instanceof Source)) {
+            return false;
+        }
+
+        final Source src = (Source)obj;
+        // Only compare content as a last resort measure
+        return length == src.length && Objects.equals(name, src.name) && Arrays.equals(content, src.content);
+    }
+
+    @Override
+    public int hashCode() {
+        int h = hash;
+        if (h == 0) {
+            h = hash = Arrays.hashCode(content) ^ Objects.hashCode(name);
+        }
+        return h;
+    }
+
+    /**
+     * Fetch source content.
+     * @return Source content.
+     */
+    public String getString() {
+        return new String(content, 0, length);
+    }
+
+    /**
+     * Get the user supplied name of this script.
+     * @return User supplied source name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the "directory" part of the file or "base" of the URL.
+     * @return base of file or URL.
+     */
+    public String getBase() {
+        return base;
+    }
+
+    /**
+     * Fetch a portion of source content.
+     * @param start start index in source
+     * @param len length of portion
+     * @return Source content portion.
+     */
+    public String getString(final int start, final int len) {
+        return new String(content, start, len);
+    }
+
+    /**
+     * Fetch a portion of source content associated with a token.
+     * @param token Token descriptor.
+     * @return Source content portion.
+     */
+    public String getString(final long token) {
+        final int start = Token.descPosition(token);
+        final int len = Token.descLength(token);
+        return new String(content, start, len);
+    }
+
+    /**
+     * Returns the source URL of this script Source. Can be null if Source
+     * was created from a String or a char[].
+     *
+     * @return URL source or null
+     */
+    public URL getURL() {
+        return url;
+    }
+
+    /**
+     * Find the beginning of the line containing position.
+     * @param position Index to offending token.
+     * @return Index of first character of line.
+     */
+    private int findBOLN(final int position) {
+        for (int i = position - 1; i > 0; i--) {
+            final char ch = content[i];
+
+            if (ch == '\n' || ch == '\r') {
+                return i + 1;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Find the end of the line containing position.
+     * @param position Index to offending token.
+     * @return Index of last character of line.
+     */
+    private int findEOLN(final int position) {
+         for (int i = position; i < length; i++) {
+            final char ch = content[i];
+
+            if (ch == '\n' || ch == '\r') {
+                return i - 1;
+            }
+        }
+
+        return length - 1;
+    }
+
+    /**
+     * Return line number of character position.
+     * @param position Position of character in source content.
+     * @return Line number.
+     */
+    public int getLine(final int position) {
+        // Line count starts at 1.
+        int line = 1;
+
+        for (int i = 0; i < position; i++) {
+            final char ch = content[i];
+            // Works for both \n and \r\n.
+            if (ch == '\n') {
+                line++;
+            }
+        }
+
+        return line;
+    }
+
+    /**
+     * Return column number of character position.
+     * @param position Position of character in source content.
+     * @return Column number.
+     */
+    public int getColumn(final int position) {
+        // TODO - column needs to account for tabs.
+        return position - findBOLN(position);
+    }
+
+    /**
+     * Return line text including character position.
+     * @param position Position of character in source content.
+     * @return Line text.
+     */
+    public String getSourceLine(final int position) {
+        // Find end of previous line.
+        final int first = findBOLN(position);
+        // Find end of this line.
+        final int last = findEOLN(position);
+
+        return new String(content, first, last - first + 1);
+    }
+
+    /**
+     * Get the content of this source as a char array
+     * @return content
+     */
+    public char[] getContent() {
+        return content.clone();
+    }
+
+    /**
+     * Get the length in chars for this source
+     * @return length
+     */
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * Read all of the source until end of file. Return it as char array
+     *
+     * @param reader  reader opened to source stream
+     * @return source as content
+     *
+     * @throws IOException if source could not be read
+     */
+    public static char[] readFully(final Reader reader) throws IOException {
+        final char[]        arr = new char[BUFSIZE];
+        final StringBuilder sb  = new StringBuilder();
+
+        try {
+            int numChars;
+            while ((numChars = reader.read(arr, 0, arr.length)) > 0) {
+                sb.append(arr, 0, numChars);
+            }
+        } finally {
+            reader.close();
+        }
+
+        return sb.toString().toCharArray();
+    }
+
+    /**
+     * Read all of the source until end of file. Return it as char array
+     *
+     * @param file  source file
+     * @return source as content
+     *
+     * @throws IOException if source could not be read
+     */
+    public static char[] readFully(final File file) throws IOException {
+        if (!file.isFile()) {
+            throw new IOException(file + " is not a file"); //TODO localize?
+        }
+        return byteToCharArray(Files.readAllBytes(file.toPath()));
+    }
+
+    /**
+     * Get the base url. This is currently used for testing only
+     * @param url a URL
+     * @return base URL for url
+     */
+    public static String baseURL(final URL url) {
+        return baseURL(url, null);
+    }
+
+    private static String baseURL(final URL url, final String defaultValue) {
+        if (url.getProtocol().equals("file")) {
+            try {
+                final Path path = Paths.get(url.toURI());
+                final Path parent = path.getParent();
+                return (parent != null) ? (parent + File.separator) : defaultValue;
+            } catch (final SecurityException | URISyntaxException | IOError e) {
+                return defaultValue;
+            }
+        }
+
+        // FIXME: is there a better way to find 'base' URL of a given URL?
+        String path = url.getPath();
+        if (path.isEmpty()) {
+            return defaultValue;
+        }
+        path = path.substring(0, path.lastIndexOf('/') + 1);
+        final int port = url.getPort();
+        try {
+            return new URL(url.getProtocol(), url.getHost(), port, path).toString();
+        } catch (final MalformedURLException e) {
+            return defaultValue;
+        }
+    }
+
+    private static String dirName(final File file, final String defaultValue) {
+        final String res = file.getParent();
+        return (res != null)? (res + File.separator) : defaultValue;
+    }
+
+    // fake directory like name
+    private static String baseName(final String name, final String defaultValue) {
+        int idx = name.lastIndexOf('/');
+        if (idx == -1) {
+            idx = name.lastIndexOf('\\');
+        }
+        return (idx != -1)? name.substring(0, idx + 1) : defaultValue;
+    }
+
+    private static char[] readFully(final InputStream is) throws IOException {
+        return byteToCharArray(readBytes(is));
+    }
+
+    private static char[] byteToCharArray(final byte[] bytes) {
+        Charset cs = StandardCharsets.UTF_8;
+        int start = 0;
+        // BOM detection.
+        if (bytes.length > 1 && bytes[0] == (byte)0xFE && bytes[1] == (byte)0xFF) {
+            start = 2;
+            cs = StandardCharsets.UTF_16BE;
+        } else if (bytes.length > 1 && bytes[0] == (byte)0xFF && bytes[1] == (byte)0xFE) {
+            start = 2;
+            cs = StandardCharsets.UTF_16LE;
+        } else if (bytes.length > 2 && bytes[0] == (byte)0xEF && bytes[1] == (byte)0xBB && bytes[2] == (byte)0xBF) {
+            start = 3;
+            cs = StandardCharsets.UTF_8;
+        } else if (bytes.length > 3 && bytes[0] == (byte)0xFF && bytes[1] == (byte)0xFE && bytes[2] == 0 && bytes[3] == 0) {
+            start = 4;
+            cs = Charset.forName("UTF-32LE");
+        } else if (bytes.length > 3 && bytes[0] == 0 && bytes[1] == 0 && bytes[2] == (byte)0xFE && bytes[3] == (byte)0xFF) {
+            start = 4;
+            cs = Charset.forName("UTF-32BE");
+        }
+
+        return new String(bytes, start, bytes.length - start, cs).toCharArray();
+    }
+
+    static byte[] readBytes(final InputStream is) throws IOException {
+        final byte[] arr = new byte[BUFSIZE];
+        try {
+            try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) {
+                int numBytes;
+                while ((numBytes = is.read(arr, 0, arr.length)) > 0) {
+                    buf.write(arr, 0, numBytes);
+                }
+                return buf.toByteArray();
+            }
+        } finally {
+            is.close();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+
+    private static URL getURLFromFile(final File file) {
+        try {
+            return file.toURI().toURL();
+        } catch (final SecurityException | MalformedURLException ignored) {
+            return null;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/SpecializedMethodChooser.java b/nashorn/src/jdk/nashorn/internal/runtime/SpecializedMethodChooser.java
new file mode 100644
index 0000000..2853cdf
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/SpecializedMethodChooser.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.runtime;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.runtime.options.Options;
+
+class SpecializedMethodChooser {
+    /** Should specialized function and specialized constructors for the builtin be used if available? */
+    private static final boolean DISABLE_SPECIALIZATION = Options.getBooleanProperty("nashorn.scriptfunction.specialization.disable");
+
+    static MethodHandle candidateWithLowestWeight(final MethodType descType, final MethodHandle initialCandidate, final MethodHandle[] specs) {
+        if (DISABLE_SPECIALIZATION || specs == null) {
+            return initialCandidate;
+        }
+
+        int          minimumWeight = Integer.MAX_VALUE;
+        MethodHandle candidate     = initialCandidate;
+
+        for (final MethodHandle spec : specs) {
+            final MethodType specType = spec.type();
+
+            if (!typeCompatible(descType, specType)) {
+                continue;
+            }
+
+            //return type is ok. we want a wider or equal one for our callsite.
+            final int specWeight = weigh(specType);
+            if (specWeight < minimumWeight) {
+                candidate = spec;
+                minimumWeight = specWeight;
+            }
+        }
+
+        return candidate;
+    }
+
+    private static boolean typeCompatible(final MethodType desc, final MethodType spec) {
+        //spec must fit in desc
+        final Class<?>[] dparray = desc.parameterArray();
+        final Class<?>[] sparray = spec.parameterArray();
+
+        if (dparray.length != sparray.length) {
+            return false;
+        }
+
+        for (int i = 0; i < dparray.length; i++) {
+            final Type dp = Type.typeFor(dparray[i]);
+            final Type sp = Type.typeFor(sparray[i]);
+
+            if (dp.isBoolean()) {
+                return false; //don't specialize on booleans, we have the "true" vs int 1 ambiguity in resolution
+            }
+
+            //specialization arguments must be at least as wide as dp, if not wider
+            if (Type.widest(dp, sp) != sp) {
+                //e.g. specialization takes double and callsite says "object". reject.
+                //but if specialization says double and callsite says "int" or "long" or "double", that's fine
+                return false;
+            }
+        }
+
+        return true; // anything goes for return type, take the convenient one and it will be upcasted thru dynalink magic.
+    }
+
+    private static int weigh(final MethodType t) {
+        int weight = Type.typeFor(t.returnType()).getWeight();
+        for (final Class<?> paramType : t.parameterArray()) {
+            final int pweight = Type.typeFor(paramType).getWeight();
+            weight += pweight;
+        }
+        return weight;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/SpillProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/SpillProperty.java
new file mode 100644
index 0000000..716097d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/SpillProperty.java
@@ -0,0 +1,85 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import jdk.nashorn.internal.lookup.Lookup;
+
+/**
+ * The SpillProperty is a subclass of AccessorProperties. Anything not in the initial property map
+ * will end up in the embed fields of the ScriptObject or in the Spill, which currently is a growing
+ * Object only array in ScriptObject
+ *
+ * @see AccessorProperty
+ * @see ScriptObject
+ */
+public final class SpillProperty extends AccessorProperty {
+    private static final MethodHandle SPILLGETTER = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class), Lookup.GET_OBJECT_TYPE);
+
+    /**
+     * Constructor
+     *
+     * @param key    property key
+     * @param flags  property flags
+     * @param slot   property slot/index
+     * @param getter getter for property
+     * @param setter setter for property, or null if not configurable and writable
+     */
+    public SpillProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) {
+        super(key, flags, slot, getter, setter);
+    }
+
+    private SpillProperty(final SpillProperty property) {
+        super(property);
+    }
+
+    @Override
+    protected Property copy() {
+        return new SpillProperty(this);
+    }
+
+    @Override
+    public MethodHandle getGetter(final Class<?> type) {
+        if (isSpill()) {
+            return MH.filterArguments(super.getGetter(type), 0, SPILLGETTER);
+        }
+
+        return super.getGetter(type);
+    }
+
+    @Override
+    public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
+        if (isSpill()) {
+            return MH.filterArguments(super.getSetter(type, currentMap), 0, SPILLGETTER);
+        }
+
+        return super.getSetter(type, currentMap);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java
new file mode 100644
index 0000000..da64655
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java
@@ -0,0 +1,134 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.codegen.Compiler.OBJECTS_PACKAGE;
+import static jdk.nashorn.internal.codegen.Compiler.SCRIPTS_PACKAGE;
+import static jdk.nashorn.internal.codegen.Compiler.binaryName;
+import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_PREFIX;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+
+/**
+ * Responsible for on the fly construction of structure classes as well
+ * as loading jdk.nashorn.internal.objects.* classes.
+ *
+ */
+final class StructureLoader extends NashornLoader {
+    private static final String JS_OBJECT_PREFIX_EXTERNAL = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_PREFIX.tag();
+    private static final String OBJECTS_PACKAGE_EXTERNAL  = binaryName(OBJECTS_PACKAGE);
+
+    /**
+     * Constructor.
+     */
+    StructureLoader(final ClassLoader parent, final Context context) {
+        super(parent, context);
+    }
+
+    @Override
+    protected synchronized Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+        // check the cache first
+        final Class<?> loadedClass = findLoadedClass(name);
+        if (loadedClass != null) {
+            if (resolve) {
+                resolveClass(loadedClass);
+            }
+            return loadedClass;
+        }
+
+        if (name.startsWith(binaryName(OBJECTS_PACKAGE_EXTERNAL))) {
+            try {
+                return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
+                    @Override
+                    public Class<?> run() throws ClassNotFoundException {
+                        final String      source  = name.replace('.','/') + ".clazz";
+                        final URL         url     = getResource(source);
+                        try (final InputStream is = getResourceAsStream(source)) {
+                            if (is == null) {
+                                throw new ClassNotFoundException(name);
+                            }
+
+                            byte[] code;
+                            try {
+                                code = Source.readBytes(is);
+                            } catch (final IOException e) {
+                                Context.printStackTrace(e);
+                                throw new ClassNotFoundException(name, e);
+                            }
+
+                            final Class<?> cl = defineClass(name, code, 0, code.length, new CodeSource(url, (CodeSigner[])null));
+                            if (resolve) {
+                                resolveClass(cl);
+                            }
+                            return cl;
+                        } catch (final IOException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                });
+            } catch (final PrivilegedActionException  e) {
+                throw new ClassNotFoundException(name, e);
+            }
+        }
+
+        return super.loadClassTrusted(name, resolve);
+    }
+
+
+    @Override
+    protected Class<?> findClass(final String name) throws ClassNotFoundException {
+        if (name.startsWith(JS_OBJECT_PREFIX_EXTERNAL)) {
+            final int start = name.indexOf(JS_OBJECT_PREFIX.tag()) + JS_OBJECT_PREFIX.tag().length();
+            return generateClass(name, name.substring(start, name.length()));
+        }
+        return super.findClass(name);
+    }
+
+    /**
+     * Generate a layout class.
+     * @param name       Name of class.
+     * @param descriptor Layout descriptor.
+     * @return Generated class.
+     */
+    private Class<?> generateClass(final String name, final String descriptor) {
+        Context context = getContext();
+
+        if (context == null) {
+            context = Context.getContextTrusted();
+        }
+
+        final byte[] code = new ObjectClassGenerator(context).generate(descriptor);
+        return defineClass(name, code, 0, code.length);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Timing.java b/nashorn/src/jdk/nashorn/internal/runtime/Timing.java
new file mode 100644
index 0000000..aa32f1c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Timing.java
@@ -0,0 +1,109 @@
+/*
+ * 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;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Simple wallclock timing framework
+ */
+public final class Timing {
+    private static final boolean ENABLED = Options.getBooleanProperty("nashorn.time");
+    private static final Map<String, Long> TIMINGS;
+    private static final long START_TIME;
+
+    static {
+        if (ENABLED) {
+            TIMINGS    = new LinkedHashMap<>();
+            START_TIME = System.currentTimeMillis();
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+                @Override
+                public void run() {
+                    final long t = System.currentTimeMillis();
+                    long knownTime = 0L;
+                    int  maxLength = 0;
+
+                    for (final Map.Entry<String, Long> entry : TIMINGS.entrySet()) {
+                        maxLength = Math.max(maxLength, entry.getKey().length());
+                    }
+                    maxLength++;
+
+                    for (final Map.Entry<String, Long> entry : TIMINGS.entrySet()) {
+                        final StringBuilder sb = new StringBuilder();
+
+                        sb.append(entry.getKey());
+                        while (sb.length() < maxLength) {
+                            sb.append(' ');
+                        }
+
+                        final long duration = entry.getValue();
+                        sb.append(duration);
+                        sb.append(' ');
+                        sb.append(" ms");
+
+                        knownTime += duration;
+
+                        System.err.println(sb.toString()); //Context err is gone by shutdown TODO
+                    }
+
+                    final long total = t - START_TIME;
+                    System.err.println("Total runtime: " + total + " ms (Non-runtime: " + knownTime + " ms [" + (int)(knownTime * 100.0 / total) + "%])");
+                }
+            });
+        } else {
+            TIMINGS = null;
+            START_TIME = 0L;
+        }
+    }
+
+    /**
+     * Check if timing is inabled
+     * @return true if timing is enabled
+     */
+    public static boolean isEnabled() {
+        return ENABLED;
+    }
+
+    /**
+     * When timing, this can be called to register a new module for timing
+     * or add to its accumulated time
+     *
+     * @param module   module name
+     * @param duration duration to add to accumulated time for module
+     */
+    public static void accumulateTime(final String module, final long duration) {
+        if (Timing.isEnabled()) {
+            Long accumulatedTime = TIMINGS.get(module);
+            if (accumulatedTime == null) {
+                accumulatedTime = 0L;
+            }
+            TIMINGS.put(module, accumulatedTime + duration);
+        }
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java b/nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java
new file mode 100644
index 0000000..448d72c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java
@@ -0,0 +1,294 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.uriError;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * URI handling global functions. ECMA 15.1.3 URI Handling Function Properties
+ *
+ */
+public final class URIUtils {
+
+    private URIUtils() {
+    }
+
+    static String encodeURI(final Object self, final String string) {
+        return encode(self, string, false);
+    }
+
+    static String encodeURIComponent(final Object self, final String string) {
+        return encode(self, string, true);
+    }
+
+    static String decodeURI(final Object self, final String string) {
+        return decode(self, string, false);
+    }
+
+    static String decodeURIComponent(final Object self, final String string) {
+        return decode(self, string, true);
+    }
+
+    // abstract encode function
+    private static String encode(final Object self, final String string, final boolean component) {
+        if (string.isEmpty()) {
+            return string;
+        }
+
+        final int len = string.length();
+        final StringBuilder sb = new StringBuilder();
+
+        for (int k = 0; k < len; k++) {
+            final char C = string.charAt(k);
+            if (isUnescaped(C, component)) {
+                sb.append(C);
+                continue;
+            }
+
+            if (C >= 0xDC00 && C <= 0xDFFF) {
+                return error(string, k);
+            }
+
+            int V;
+            if (C < 0xD800 || C > 0xDBFF) {
+                V = C;
+            } else {
+                k++;
+                if (k == len) {
+                    return error(string, k);
+                }
+
+                final char kChar = string.charAt(k);
+                if (kChar < 0xDC00 || kChar > 0xDFFF) {
+                    return error(string, k);
+                }
+                V = ((C - 0xD800) * 0x400 + (kChar - 0xDC00) + 0x10000);
+            }
+
+            try {
+                sb.append(toHexEscape(V));
+            } catch (final Exception e) {
+                throw uriError(e, "bad.uri", string, Integer.toString(k));
+            }
+        }
+
+        return sb.toString();
+    }
+
+    // abstract decode function
+    private static String decode(final Object self, final String string, final boolean component) {
+        if (string.isEmpty()) {
+            return string;
+        }
+
+        final int           len = string.length();
+        final StringBuilder sb  = new StringBuilder();
+
+        for (int k = 0; k < len; k++) {
+            final char ch = string.charAt(k);
+            if (ch != '%') {
+                sb.append(ch);
+                continue;
+            }
+            final int start = k;
+            if (k + 2 >= len) {
+                return error(string, k);
+            }
+
+            int B = toHexByte(string.charAt(k + 1), string.charAt(k + 2));
+            if (B < 0) {
+                return error(string, k + 1);
+            }
+
+            k += 2;
+            char C;
+            if ((B & 0x80) == 0) {
+                C = (char) B;
+                if (!component && URI_RESERVED.indexOf(C) >= 0) {
+                    for (int j = start; j <= k; j++) {
+                        sb.append(string.charAt(j));
+                    }
+                } else {
+                    sb.append(C);
+                }
+            } else {
+                int n;
+                for (n = 1; n < 6; n++) {
+                    if (((B << n) & 0x80) == 0) {
+                        break;
+                    }
+                }
+
+                if (n == 1 || n > 4) {
+                    return error(string, k);
+                }
+
+                if ((k + (3 * (n - 1))) >= len) {
+                    return error(string, k);
+                }
+
+                final byte[] bbuf = new byte[n];
+                bbuf[0] = (byte) B;
+
+                for (int j = 1; j < n; j++) {
+                    k++;
+                    if (string.charAt(k) != '%') {
+                        return error(string, k);
+                    }
+
+                    if (k + 2 == len) {
+                        return error(string, k);
+                    }
+
+                    B = toHexByte(string.charAt(k + 1), string.charAt(k + 2));
+                    if (B < 0 || (B & 0xC0) != 0x80) {
+                        return error(string, k + 1);
+                    }
+
+                    k += 2;
+                    bbuf[j] = (byte) B;
+                }
+
+                int V;
+                try {
+                    V = ucs4Char(bbuf);
+                } catch (final Exception e) {
+                    throw uriError(e, "bad.uri", string, Integer.toString(k));
+                }
+                if (V < 0x10000) {
+                    C = (char) V;
+                    if (!component && URI_RESERVED.indexOf(C) >= 0) {
+                        for (int j = start; j != k; j++) {
+                            sb.append(string.charAt(j));
+                        }
+                    } else {
+                        sb.append(C);
+                    }
+                } else { // V >= 0x10000
+                    if (V > 0x10FFFF) {
+                        return error(string, k);
+                    }
+                    final int L = ((V - 0x10000) & 0x3FF) + 0xDC00;
+                    final int H = (((V - 0x10000) >> 10) & 0x3FF) + 0xD800;
+                    sb.append((char) H);
+                    sb.append((char) L);
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    private static int hexDigit(final char ch) {
+        final char chu = Character.toUpperCase(ch);
+        if (chu >= '0' && chu <= '9') {
+            return (chu - '0');
+        } else if (chu >= 'A' && chu <= 'F') {
+            return (chu - 'A' + 10);
+        } else {
+            return -1;
+        }
+    }
+
+    private static int toHexByte(final char ch1, final char ch2) {
+        final int i1 = hexDigit(ch1);
+        final int i2 = hexDigit(ch2);
+        if (i1 >= 0 && i2 >= 0) {
+            return (i1 << 4) | i2;
+        }
+        return -1;
+    }
+
+    private static int ucs4Char(final byte[] utf8) throws UnsupportedEncodingException {
+        return new String(utf8, "UTF-8").codePointAt(0);
+    }
+
+    private static String toHexEscape(final int u0) {
+        int u = u0;
+        int len;
+        final byte[] b = new byte[6];
+
+        if (u <= 0x7f) {
+            b[0] = (byte) u;
+            len = 1;
+        } else {
+            // > 0x7ff -> length 2
+            // > 0xffff -> length 3
+            // and so on. each new length is an additional 5 bits from the
+            // original 11
+            // the final mask is 8-len zeros in the low part.
+            len = 2;
+            for (int mask = u >>> 11; mask != 0; mask >>>= 5) {
+                len++;
+            }
+            for (int i = len - 1; i > 0; i--) {
+                b[i] = (byte) (0x80 | (u & 0x3f));
+                u >>>= 6; // 64 bits per octet.
+            }
+
+            b[0] = (byte) (~((1 << (8 - len)) - 1) | u);
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < len; i++) {
+            sb.append('%');
+            if ((b[i] & 0xff) < 0x10) {
+                sb.append('0');
+            }
+            sb.append(Integer.toHexString(b[i] & 0xff).toUpperCase());
+        }
+
+        return sb.toString();
+    }
+
+    private static String error(final String string, final int index) {
+        throw uriError("bad.uri", string, Integer.toString(index));
+    }
+
+    // 'uriEscaped' except for alphanumeric chars
+    private static final String URI_UNESCAPED_NONALPHANUMERIC = "-_.!~*'()";
+    // 'uriReserved' + '#'
+    private static final String URI_RESERVED = ";/?:@&=+$,#";
+
+    private static boolean isUnescaped(final char ch, final boolean component) {
+        if (('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z')
+                || ('0' <= ch && ch <= '9')) {
+            return true;
+        }
+
+        if (URI_UNESCAPED_NONALPHANUMERIC.indexOf(ch) >= 0) {
+            return true;
+        }
+
+        if (!component) {
+            return URI_RESERVED.indexOf(ch) >= 0;
+        }
+
+        return false;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Undefined.java b/nashorn/src/jdk/nashorn/internal/runtime/Undefined.java
new file mode 100644
index 0000000..a19c244
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Undefined.java
@@ -0,0 +1,199 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.internal.dynalink.support.Guards;
+
+/**
+ * Unique instance of this class is used to represent JavaScript undefined.
+ */
+public final class Undefined extends DefaultPropertyAccess {
+
+    private Undefined() {
+    }
+
+    private static final Undefined UNDEFINED = new Undefined();
+    private static final Undefined EMPTY     = new Undefined();
+
+    // Guard used for indexed property access/set on the Undefined instance
+    private static final MethodHandle UNDEFINED_GUARD = Guards.getIdentityGuard(UNDEFINED);
+
+    /**
+     * Get the value of {@code undefined}, this is represented as a global singleton
+     * instance of this class. It can always be reference compared
+     *
+     * @return the undefined object
+     */
+    public static Undefined getUndefined() {
+        return UNDEFINED;
+    }
+
+    /**
+     * Get the value of {@code empty}. This is represented as a global singleton
+     * instanceof this class. It can always be reference compared.
+     * <p>
+     * We need empty to differentiate behavior in things like array iterators
+     * <p>
+     * @return the empty object
+     */
+    public static Undefined getEmpty() {
+        return EMPTY;
+    }
+
+    /**
+     * Get the class name of Undefined
+     * @return "Undefined"
+     */
+    @SuppressWarnings("static-method")
+    public String getClassName() {
+        return "Undefined";
+    }
+
+    @Override
+    public String toString() {
+        return "undefined";
+    }
+
+    /**
+     * Lookup the appropriate method for an invoke dynamic call.
+     * @param desc The invoke dynamic callsite descriptor.
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    public static GuardedInvocation lookup(final CallSiteDescriptor desc) {
+        final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
+
+        switch (operator) {
+        case "new":
+        case "call":
+            throw lookupTypeError("cant.call.undefined", desc);
+        case "callMethod":
+            throw lookupTypeError("cant.read.property.of.undefined", desc);
+        // NOTE: we support getElem and setItem as JavaScript doesn't distinguish items from properties. Nashorn itself
+        // emits "dyn:getProp:identifier" for "<expr>.<identifier>" and "dyn:getElem" for "<expr>[<expr>]", but we are
+        // more flexible here and dispatch not on operation name (getProp vs. getElem), but rather on whether the
+        // operation has an associated name or not.
+        case "getProp":
+        case "getElem":
+        case "getMethod":
+            if (desc.getNameTokenCount() < 3) {
+                return findGetIndexMethod(desc);
+            }
+            throw lookupTypeError("cant.read.property.of.undefined", desc);
+        case "setProp":
+        case "setElem":
+            if (desc.getNameTokenCount() < 3) {
+                return findSetIndexMethod(desc);
+            }
+            throw lookupTypeError("cant.set.property.of.undefined", desc);
+        default:
+            break;
+        }
+
+        return null;
+    }
+
+    private static ECMAException lookupTypeError(final String msg, final CallSiteDescriptor desc) {
+        return typeError(msg, desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null);
+    }
+
+    /**
+     * Find the appropriate GETINDEX method for an invoke dynamic call.
+     * @param desc The invoke dynamic callsite descriptor
+     * @param args arguments
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    private static GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final Object... args) {
+        final MethodType callType  = desc.getMethodType();
+        final Class<?> returnClass = callType.returnType();
+        final Class<?> keyClass    = callType.parameterType(1);
+
+        String name = "get";
+        if (returnClass.isPrimitive()) {
+            //turn e.g. get with a double into getDouble
+            final String returnTypeName = returnClass.getName();
+            name += Character.toUpperCase(returnTypeName.charAt(0)) + returnTypeName.substring(1, returnTypeName.length());
+        }
+        MethodHandle methodHandle = findOwnMH(name, returnClass, keyClass);
+        methodHandle = MH.asType(methodHandle, methodHandle.type().changeParameterType(0, Object.class));
+
+        return new GuardedInvocation(methodHandle, UNDEFINED_GUARD);
+    }
+
+    /**
+     * Find the appropriate SETINDEX method for an invoke dynamic call.
+     * @param desc The invoke dynamic callsite descriptor
+     * @return GuardedInvocation to be invoked at call site.
+     */
+    private static GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc) {
+        final MethodType callType   = desc.getMethodType();
+        final Class<?>   keyClass   = callType.parameterType(1);
+        final Class<?>   valueClass = callType.parameterType(2);
+
+        MethodHandle methodHandle = findOwnMH("set", void.class, keyClass, valueClass, boolean.class);
+        methodHandle = MH.asType(methodHandle, methodHandle.type().changeParameterType(0, Object.class));
+        methodHandle = MH.insertArguments(methodHandle, 3, false);
+
+        return new GuardedInvocation(methodHandle, UNDEFINED_GUARD);
+    }
+
+    @Override
+    public Object get(final Object key) {
+        throw typeError("cant.read.property.of.undefined", ScriptRuntime.safeToString(key));
+    }
+
+    @Override
+    public void set(final Object key, final Object value, final boolean strict) {
+        throw typeError("cant.set.property.of.undefined", ScriptRuntime.safeToString(key));
+    }
+
+    @Override
+    public boolean delete(final Object key, final boolean strict) {
+        throw typeError("cant.delete.property.of.undefined", ScriptRuntime.safeToString(key));
+    }
+
+    @Override
+    public boolean has(final Object key) {
+        return false;
+    }
+
+    @Override
+    public boolean hasOwnProperty(final Object key) {
+        return false;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findVirtual(MethodHandles.lookup(), Undefined.class, name, MH.type(rtype, types));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
new file mode 100644
index 0000000..83d3c8d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
@@ -0,0 +1,159 @@
+/*
+ * 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;
+
+import java.lang.invoke.MethodHandle;
+import jdk.nashorn.internal.lookup.Lookup;
+
+/**
+ * Property with user defined getters/setters. Actual getter and setter
+ * functions are stored in underlying ScriptObject. Only the 'slot' info is
+ * stored in the property.
+ *
+ * The slots here denote either ScriptObject embed field number or spill
+ * array index. For spill array index, we use slot value of
+ * (index + ScriptObject.embedSize). See also ScriptObject.getEmbedOrSpill
+ * method. Negative slot value means that the corresponding getter or setter
+ * is null. Note that always two slots are allocated in ScriptObject - but
+ * negative (less by 1) slot number is stored for null getter or setter.
+ * This is done so that when the property is redefined with a different
+ * getter and setter (say, both non-null), we'll have spill slots to store
+ * those. When a slot is negative, (-slot - 1) is the embed/spill index.
+ */
+public final class UserAccessorProperty extends Property {
+
+    /** User defined getter function slot. */
+    private final int getterSlot;
+
+    /** User defined setter function slot. */
+    private final int setterSlot;
+
+    /**
+     * Constructor
+     *
+     * @param key        property key
+     * @param flags      property flags
+     * @param getterSlot getter slot, starting at first embed
+     * @param setterSlot setter slot, starting at first embed
+     */
+    public UserAccessorProperty(final String key, final int flags, final int getterSlot, final int setterSlot) {
+        super(key, flags, -1);
+        this.getterSlot = getterSlot;
+        this.setterSlot = setterSlot;
+    }
+
+    private UserAccessorProperty(final UserAccessorProperty property) {
+        super(property);
+
+        this.getterSlot = property.getterSlot;
+        this.setterSlot = property.setterSlot;
+    }
+
+    /**
+     * Return getter slot for this UserAccessorProperty. Slots start with first embed field.
+     * @return getter slot
+     */
+    public int getGetterSlot() {
+        return getterSlot < 0 ? -getterSlot - 1 : getterSlot;
+    }
+
+    /**
+     * Return setter slot for this UserAccessorProperty. Slots start with first embed field.
+     * @return setter slot
+     */
+    public int getSetterSlot() {
+        return setterSlot < 0 ? -setterSlot - 1 : setterSlot;
+    }
+
+    @Override
+    protected Property copy() {
+        return new UserAccessorProperty(this);
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        final UserAccessorProperty uc = (UserAccessorProperty) other;
+        return getterSlot == uc.getterSlot && setterSlot == uc.setterSlot;
+     }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ getterSlot ^ setterSlot;
+    }
+
+    /*
+     * Accessors.
+     */
+    @Override
+    public int getSpillCount() {
+        // calculate how many spill array slots used by this propery.
+        int count = 0;
+        if (getGetterSlot() >= ScriptObject.EMBED_SIZE) {
+            count++;
+        }
+        if (getSetterSlot() >= ScriptObject.EMBED_SIZE) {
+            count++;
+        }
+        return count;
+    }
+
+    @Override
+    public boolean hasGetterFunction() {
+        return getterSlot > -1;
+    }
+
+    @Override
+    public boolean hasSetterFunction() {
+        return setterSlot > -1;
+    }
+
+    @Override
+    public MethodHandle getGetter(final Class<?> type) {
+        return Lookup.filterReturnType(ScriptObject.USER_ACCESSOR_GETTER.methodHandle(), type);
+    }
+
+    @Override
+    public ScriptFunction getGetterFunction(final ScriptObject obj) {
+        final Object value = obj.getEmbedOrSpill(getterSlot);
+        return (value instanceof ScriptFunction) ? (ScriptFunction) value : null;
+    }
+
+    @Override
+    public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
+        return ScriptObject.USER_ACCESSOR_SETTER.methodHandle();
+    }
+
+    @Override
+    public ScriptFunction getSetterFunction(final ScriptObject obj) {
+        final Object value = obj.getEmbedOrSpill(setterSlot);
+        return (value instanceof ScriptFunction) ? (ScriptFunction) value : null;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Version.java b/nashorn/src/jdk/nashorn/internal/runtime/Version.java
new file mode 100644
index 0000000..8c102dd
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Version.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Class to handle version strings for Nashorn.
+ */
+public final class Version {
+    // Don't create me!
+    private Version() {
+    }
+
+    /**
+     * The current version number as a string.
+     * @return version string
+     */
+    public static String version() {
+        return version("release");  // mm.nn.oo[-milestone]
+    }
+
+    /**
+     * The current full version number as a string.
+     * @return full version string
+     */
+    public static String fullVersion() {
+        return version("full"); // mm.mm.oo[-milestone]-build
+    }
+
+    private static final String   VERSION_RB_NAME = "jdk.nashorn.internal.runtime.resources.version";
+    private static ResourceBundle versionRB;
+
+    private static String version(final String key) {
+        if (versionRB == null) {
+            try {
+                versionRB = ResourceBundle.getBundle(VERSION_RB_NAME);
+            } catch (final MissingResourceException e) {
+                return "version not available";
+            }
+        }
+        try {
+            return versionRB.getString(key);
+        }
+        catch (final MissingResourceException e) {
+            return "version not available";
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java
new file mode 100644
index 0000000..5eaf5f5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java
@@ -0,0 +1,295 @@
+/*
+ * 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;
+
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+
+
+/**
+ * This class supports the handling of scope in a with body.
+ *
+ */
+public final class WithObject extends ScriptObject implements Scope {
+
+    private static final MethodHandle WITHEXPRESSIONFILTER = findOwnMH("withFilterExpression", Object.class, Object.class);
+    private static final MethodHandle WITHSCOPEFILTER      = findOwnMH("withFilterScope",      Object.class, Object.class);
+    private static final MethodHandle BIND_TO_EXPRESSION   = findOwnMH("bindToExpression",     Object.class, Object.class, Object.class);
+
+    /** With expression object. */
+    private final Object expression;
+
+    /**
+     * Constructor
+     *
+     * @param scope scope object
+     * @param expression with expression
+     */
+    public WithObject(final ScriptObject scope, final Object expression) {
+        super();
+
+        setIsScope();
+        setProto(scope);
+        this.expression = expression;
+    }
+
+    /**
+     * Delete a property based on a key.
+     * @param key Any valid JavaScript value.
+     * @param strict strict mode execution.
+     * @return True if deleted.
+     */
+    @Override
+    public boolean delete(final Object key, final boolean strict) {
+        if (expression instanceof ScriptObject) {
+            final ScriptObject self = (ScriptObject)expression;
+            final String propName = ScriptObject.convertKey(key);
+
+            final FindProperty find = self.findProperty(propName, true);
+
+            if (find != null) {
+                return self.delete(propName, strict);
+            }
+        }
+
+        return false;
+    }
+
+
+    @Override
+    public GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request) {
+        // With scopes can never be observed outside of Nashorn code, so all call sites that can address it will of
+        // necessity have a Nashorn descriptor - it is safe to cast.
+        final NashornCallSiteDescriptor ndesc = (NashornCallSiteDescriptor)desc;
+        FindProperty find = null;
+        GuardedInvocation link = null;
+        ScriptObject self = null;
+
+        final boolean isNamedOperation;
+        final String name;
+        if(desc.getNameTokenCount() > 2) {
+            isNamedOperation = true;
+            name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+        } else {
+            isNamedOperation = false;
+            name = null;
+        }
+
+        if (expression instanceof ScriptObject) {
+            self = (ScriptObject)expression;
+            if (isNamedOperation) {
+                find = self.findProperty(name, true);
+            }
+
+            if (find != null) {
+                link = self.lookup(desc, request);
+
+                if (link != null) {
+                    return fixExpressionCallSite(ndesc, link);
+                }
+            }
+        }
+
+        final ScriptObject scope = getProto();
+        if (isNamedOperation) {
+            find = scope.findProperty(name, true);
+        }
+
+        if (find != null) {
+            return fixScopeCallSite(scope.lookup(desc, request));
+        }
+
+        // the property is not found - now check for
+        // __noSuchProperty__ and __noSuchMethod__ in expression
+        if (self != null) {
+            final String fallBack;
+
+            final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
+
+            switch (operator) {
+            case "callMethod":
+                throw new AssertionError(); // Nashorn never emits callMethod
+            case "getMethod":
+                fallBack = NO_SUCH_METHOD_NAME;
+                break;
+            case "getProp":
+            case "getElem":
+                fallBack = NO_SUCH_PROPERTY_NAME;
+                break;
+            default:
+                fallBack = null;
+                break;
+            }
+
+            if (fallBack != null) {
+                find = self.findProperty(fallBack, true);
+                if (find != null) {
+                    switch (operator) {
+                    case "getMethod":
+                        link = self.noSuchMethod(desc, request);
+                        break;
+                    case "getProp":
+                    case "getElem":
+                        link = self.noSuchProperty(desc, request);
+                        break;
+                    default:
+                        break;
+                    }
+                }
+            }
+
+            if (link != null) {
+                return fixExpressionCallSite(ndesc, link);
+            }
+        }
+
+        // still not found, may be scope can handle with it's own
+        // __noSuchProperty__, __noSuchMethod__ etc.
+        link = scope.lookup(desc, request);
+
+        if (link != null) {
+            return fixScopeCallSite(link);
+        }
+
+        return null;
+    }
+
+    /**
+     * Overridden to try to find the property first in the expression object (and its prototypes), and only then in this
+     * object (and its prototypes).
+     *
+     * @param key  Property key.
+     * @param deep Whether the search should look up proto chain.
+     * @param stopOnNonScope should a deep search stop on the first non-scope object?
+     * @param start the object on which the lookup was originally initiated
+     *
+     * @return FindPropertyData or null if not found.
+     */
+    @Override
+    FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) {
+        if (expression instanceof ScriptObject) {
+            final FindProperty exprProperty = ((ScriptObject)expression).findProperty(key, deep, stopOnNonScope, start);
+            if(exprProperty != null) {
+                return exprProperty;
+            }
+        }
+        return super.findProperty(key, deep, stopOnNonScope, start);
+    }
+
+    @Override
+    public void setSplitState(final int state) {
+        getNonWithParent().setSplitState(state);
+    }
+
+    @Override
+    public int getSplitState() {
+        return getNonWithParent().getSplitState();
+    }
+
+    /**
+     * Get first parent scope that is not an instance of WithObject.
+     */
+    private Scope getNonWithParent() {
+        ScriptObject proto = getProto();
+
+        while (proto != null && proto instanceof WithObject) {
+            proto = proto.getProto();
+        }
+
+        assert proto instanceof Scope : "with scope without parent scope";
+        return (Scope) proto;
+    }
+
+    private static GuardedInvocation fixExpressionCallSite(final NashornCallSiteDescriptor desc, final GuardedInvocation link) {
+        // If it's not a getMethod, just add an expression filter that converts WithObject in "this" position to its
+        // expression.
+        if(!"getMethod".equals(desc.getFirstOperator())) {
+            return link.filterArguments(0, WITHEXPRESSIONFILTER);
+        }
+
+        return link.replaceMethods(
+                // Make sure getMethod will bind the script functions it receives to WithObject.expression
+                MH.foldArguments(BIND_TO_EXPRESSION, filter(link.getInvocation(), WITHEXPRESSIONFILTER)),
+                // No clever things for the guard -- it is still identically filtered.
+                filterGuard(link, WITHEXPRESSIONFILTER));
+    }
+
+    private static GuardedInvocation fixScopeCallSite(final GuardedInvocation link) {
+        return link.replaceMethods(filter(link.getInvocation(), WITHSCOPEFILTER), filterGuard(link, WITHSCOPEFILTER));
+    }
+
+    private static MethodHandle filterGuard(final GuardedInvocation link, final MethodHandle filter) {
+        final MethodHandle test = link.getGuard();
+        return test == null ? null : filter(test, filter);
+    }
+
+    private static MethodHandle filter(final MethodHandle mh, final MethodHandle filter) {
+        return MH.filterArguments(mh, 0, filter);
+    }
+
+    /**
+     * Drops the WithObject wrapper from the expression.
+     * @param receiver WithObject wrapper.
+     * @return The with expression.
+     */
+    public static Object withFilterExpression(final Object receiver) {
+        return ((WithObject)receiver).expression;
+    }
+
+
+    @SuppressWarnings("unused")
+    private static Object bindToExpression(final Object fn, final Object receiver) {
+        return fn instanceof ScriptFunction ? ((ScriptFunction) fn).makeBoundFunction(withFilterExpression(receiver), new Object[0]) : fn;
+    }
+
+    /**
+     * Drops the WithObject wrapper from the scope.
+     * @param receiver WithObject wrapper.
+     * @return The with scope.
+     */
+    public static Object withFilterScope(final Object receiver) {
+        return ((WithObject)receiver).getProto();
+    }
+
+    /**
+     * Get the with expression for this {@code WithObject}
+     * @return the with expression
+     */
+    public Object getExpression() {
+        return expression;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), WithObject.class, name, MH.type(rtype, types));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java
new file mode 100644
index 0000000..fca724a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java
@@ -0,0 +1,507 @@
+/*
+ * 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.arrays;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Array;
+import jdk.nashorn.internal.runtime.GlobalObject;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+/**
+ * ArrayData - abstraction for wrapping array elements
+ */
+public abstract class ArrayData {
+
+    /** Minimum chunk size for underlying arrays */
+    protected static final int CHUNK_SIZE = 16;
+
+    /** Mask for getting a chunk */
+    protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
+
+    /**
+     * Immutable empty array to get ScriptObjects started.
+     */
+    public static final ArrayData EMPTY_ARRAY = new NoTypeArrayData();
+
+    /**
+     * Length of the array data. Not necessarily length of the wrapped array.
+     */
+    private long length;
+
+    /**
+     * Constructor
+     * @param length Virtual length of the array.
+     */
+    public ArrayData(final long length) {
+        this.length = length;
+    }
+
+    /**
+     * Factory method for unspecified array - start as int
+     * @return ArrayData
+     */
+    public static ArrayData initialArray() {
+        return new IntArrayData();
+    }
+
+    /**
+     * Factory method for unspecified array with given length - start as int array data
+     *
+     * @param length the initial length
+     * @return ArrayData
+     */
+    public static ArrayData allocate(final int length) {
+        final ArrayData arrayData = new IntArrayData(length);
+        return length == 0 ? arrayData : new DeletedRangeArrayFilter(arrayData, 0, length - 1);
+    }
+
+    /**
+     * Factory method for unspecified given an array object
+     *
+     * @param  array the array
+     * @return ArrayData wrapping this array
+     */
+    public static ArrayData allocate(final Object array) {
+        final Class<?> clazz = array.getClass();
+
+        if (clazz == int[].class) {
+            return new IntArrayData((int[])array, ((int[])array).length);
+        } else if (clazz == long[].class) {
+            return new LongArrayData((long[])array, ((long[])array).length);
+        } else if (clazz == double[].class) {
+            return new NumberArrayData((double[])array, ((double[])array).length);
+        } else {
+            return new ObjectArrayData((Object[])array, ((Object[])array).length);
+        }
+    }
+
+    /**
+     * Allocate an ArrayData wrapping a given array
+     *
+     * @param array the array to use for initial elements
+     * @return the ArrayData
+     */
+    public static ArrayData allocate(final int[] array) {
+         return new IntArrayData(array, array.length);
+    }
+
+    /**
+     * Allocate an ArrayData wrapping a given array
+     *
+     * @param array the array to use for initial elements
+     * @return the ArrayData
+     */
+    public static ArrayData allocate(final long[] array) {
+        return new LongArrayData(array, array.length);
+    }
+
+    /**
+     * Allocate an ArrayData wrapping a given array
+     *
+     * @param array the array to use for initial elements
+     * @return the ArrayData
+     */
+    public static ArrayData allocate(final double[] array) {
+        return new NumberArrayData(array, array.length);
+    }
+
+    /**
+     * Allocate an ArrayData wrapping a given array
+     *
+     * @param array the array to use for initial elements
+     * @return the ArrayData
+     */
+    public static ArrayData allocate(final Object[] array) {
+        return new ObjectArrayData(array, array.length);
+    }
+
+    /**
+     * Apply a freeze filter to an ArrayData.
+     *
+     * @param underlying  the underlying ArrayData to wrap in the freeze filter
+     * @return the frozen ArrayData
+     */
+    public static ArrayData freeze(final ArrayData underlying) {
+        return new FrozenArrayFilter(underlying);
+    }
+
+    /**
+     * Apply a seal filter to an ArrayData.
+     *
+     * @param underlying  the underlying ArrayData to wrap in the seal filter
+     * @return the sealed ArrayData
+     */
+    public static ArrayData seal(final ArrayData underlying) {
+        return new SealedArrayFilter(underlying);
+    }
+
+    /**
+     * Return the length of the array data. This may differ from the actual
+     * length of the array this wraps as length may be set or gotten as any
+     * other JavaScript Property
+     *
+     * Even though a JavaScript array length may be a long, we only store
+     * int parts for the optimized array access. For long lengths there
+     * are special cases anyway.
+     *
+     * TODO: represent arrays with "long" lengths as a special ArrayData
+     * that basically maps to the ScriptObject directly for better abstraction
+     *
+     * @return the length of the data
+     */
+    public final long length() {
+        return length;
+    }
+
+    /**
+     * Return a copy of the array data as an Object array.
+     *
+     * @return an Object array
+     */
+    public abstract Object[] asObjectArray();
+
+    /**
+     * Return a copy of the array data as an array of the specified type.
+     *
+     * @param componentType  the type of elements in the array
+     * @return and array of the given type
+     */
+    public Object asArrayOfType(final Class<?> componentType) {
+        final Object[] src = asObjectArray();
+        final int l = src.length;
+        final Object dst = Array.newInstance(componentType, l);
+        final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType);
+        try {
+            for (int i = 0; i < src.length; i++) {
+                Array.set(dst, i, invoke(converter, src[i]));
+            }
+        } catch (final RuntimeException | Error e) {
+            throw e;
+        } catch (final Throwable t) {
+            throw new RuntimeException(t);
+        }
+        return dst;
+    }
+
+    /**
+     * Set the length of the data array
+     *
+     * @param length the new length for the data array
+     */
+    public void setLength(final long length) {
+        this.length = length;
+    }
+
+    /**
+     * Shift the array data left
+     *
+     * TODO: explore start at an index and not at zero, to make these operations
+     * even faster. Offset everything from the index. Costs memory but is probably
+     * worth it
+     *
+     * @param by offset to shift
+     */
+    public abstract void shiftLeft(int by);
+
+    /**
+     * Shift the array right
+     *
+     * @param by offset to shift
+
+     * @return New arraydata (or same)
+     */
+    public abstract ArrayData shiftRight(int by);
+
+    /**
+     * Ensure that the given index exists and won't fail subsequent
+     *
+     * @param safeIndex the index to ensure wont go out of bounds
+     * @return new array data (or same)
+     */
+    public abstract ArrayData ensure(long safeIndex);
+
+    /**
+     * Shrink the array to a new length, may or may not retain the
+     * inner array
+     *
+     * @param newLength new max length
+     *
+     * @return new array data (or same)
+     */
+    public abstract ArrayData shrink(long newLength);
+
+    /**
+     * Set an object value at a given index
+     *
+     * @param index the index
+     * @param value the value
+     * @param strict are we in strict mode
+     * @return new array data (or same)
+     */
+    public abstract ArrayData set(int index, Object value, boolean strict);
+
+    /**
+     * Set an int value at a given index
+     *
+     * @param index the index
+     * @param value the value
+     * @param strict are we in strict mode
+     * @return new array data (or same)
+     */
+    public abstract ArrayData set(int index, int value, boolean strict);
+
+    /**
+     * Set a long value at a given index
+     *
+     * @param index the index
+     * @param value the value
+     * @param strict are we in strict mode
+     * @return new array data (or same)
+     */
+    public abstract ArrayData set(int index, long value, boolean strict);
+
+    /**
+     * Set an double value at a given index
+     *
+     * @param index the index
+     * @param value the value
+     * @param strict are we in strict mode
+     * @return new array data (or same)
+     */
+    public abstract ArrayData set(int index, double value, boolean strict);
+
+    /**
+     * Get an int value from a given index
+     *
+     * @param index the index
+     * @return the value
+     */
+    public abstract int getInt(int index);
+
+    /**
+     * Get a long value from a given index
+     *
+     * @param index the index
+     * @return the value
+     */
+    public abstract long getLong(int index);
+
+    /**
+     * Get a double value from a given index
+     *
+     * @param index the index
+     * @return the value
+     */
+    public abstract double getDouble(int index);
+
+    /**
+     * Get an Object value from a given index
+     *
+     * @param index the index
+     * @return the value
+     */
+    public abstract Object getObject(int index);
+
+    /**
+     * Tests to see if an entry exists (avoids boxing.)
+     * @param index the index
+     * @return true if entry exists
+     */
+    public abstract boolean has(int index);
+
+    /**
+     * Returns if element at specific index can be deleted or not.
+     *
+     * @param index the index of the element
+     * @param strict are we in strict mode
+     *
+     * @return true if element can be deleted
+     */
+    public boolean canDelete(final int index, final boolean strict) {
+        return true;
+    }
+
+    /**
+     * Returns if element at specific index range can be deleted or not.
+     *
+     * @param fromIndex  the start index
+     * @param toIndex    the end index
+     * @param strict     are we in strict mode
+     *
+     * @return true if range can be deleted
+     */
+    public boolean canDelete(final long fromIndex, final long toIndex, final boolean strict) {
+        return true;
+    }
+
+    /**
+     * Returns property descriptor for element at a given index
+     *
+     * @param global the global object
+     * @param index  the index
+     *
+     * @return property descriptor for element
+     */
+    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+        return global.newDataDescriptor(getObject(index), true, true, true);
+    }
+
+    /**
+     * Delete an array value at the given index, substituting
+     * for an undefined
+     *
+     * @param index the index
+     * @return new array data (or same)
+     */
+    public abstract ArrayData delete(int index);
+
+    /**
+     * Delete a given range from this array;
+     *
+     * @param fromIndex  from index (inclusive)
+     * @param toIndex    to index (inclusive)
+     *
+     * @return new ArrayData after deletion
+     */
+    public abstract ArrayData delete(long fromIndex, long toIndex);
+
+    /**
+     * Convert the ArrayData to one with a different element type
+     * Currently Arrays are not collapsed to narrower types, just to
+     * wider ones. Attempting to narrow an array will assert
+     *
+     * @param type new element type
+     * @return new array data
+     */
+    protected abstract ArrayData convert(Class<?> type);
+
+    /**
+     * Push an array of items to the end of the array
+     *
+     * @param strict are we in strict mode
+     * @param items  the items
+     * @return new array data (or same)
+     */
+    public ArrayData push(final boolean strict, final Object... items) {
+        if (items.length == 0) {
+            return this;
+        }
+
+        final Class<?>  widest  = widestType(items);
+
+        ArrayData newData = convert(widest);
+        long      pos     = newData.length();
+        for (final Object item : items) {
+            newData = newData.ensure(pos); //avoid sparse array
+            newData.set((int)pos++, item, strict);
+        }
+        return newData;
+    }
+
+    /**
+     * Pop an element from the end of the array
+     *
+     * @return the popped element
+     */
+    public abstract Object pop();
+
+    /**
+     * Slice out a section of the array and return that
+     * subsection as a new array data: [from, to)
+     *
+     * @param from start index
+     * @param to   end index + 1
+     * @return new array data
+     */
+    public abstract ArrayData slice(long from, long to);
+
+    private static Class<?> widestType(final Object... items) {
+        assert items.length > 0;
+
+        Class<?> widest = Integer.class;
+
+        for (final Object item : items) {
+            final Class<?> itemClass = item == null ? null : item.getClass();
+            if (itemClass == Long.class) {
+                if (widest == Integer.class) {
+                    widest = Long.class;
+                }
+            } else if (itemClass == Double.class) {
+                if (widest == Integer.class || widest == Long.class) {
+                    widest = Double.class;
+                }
+            } else if (!(item instanceof Number)) {
+                widest = Object.class;
+                break;
+            }
+        }
+
+        return widest;
+    }
+
+    /**
+     * Exponential growth function for array size when in
+     * need of resizing.
+     *
+     * @param size current size
+     * @return next size to allocate for internal array
+     */
+    protected static int nextSize(final int size) {
+        if (size == 0) {
+            return CHUNK_SIZE;
+        }
+
+        int i = size;
+        while ((i & CHUNK_MASK) != 0) {
+            i++;
+        }
+
+        return i << 1;
+    }
+
+    /**
+     * Return the next valid index from a given one. Subclassed for various
+     * array representation
+     *
+     * @param index the current index
+     *
+     * @return the next index
+     */
+    public long nextIndex(final long index) {
+        return index + 1;
+    }
+
+    static Object invoke(final MethodHandle mh, final Object arg) {
+        try {
+            return mh.invoke(arg);
+        } catch (final RuntimeException | Error e) {
+            throw e;
+        } catch (final Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java
new file mode 100644
index 0000000..c347ed7
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java
@@ -0,0 +1,194 @@
+/*
+ * 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.arrays;
+
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Undefined;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+/**
+ * Base class for array filters. Implements all core routines so that the
+ * filter only has to implement those needed.
+ */
+abstract class ArrayFilter extends ArrayData {
+    /** Underlying array. */
+    protected ArrayData underlying;
+
+    ArrayFilter(final ArrayData underlying) {
+        super(underlying.length());
+        this.underlying = underlying;
+    }
+
+    /**
+     * Get the underlying {@link ArrayData} that this filter wraps
+     * @return array data
+     */
+    protected ArrayData getUnderlying() {
+        return underlying;
+    }
+
+    @Override
+    public void setLength(final long length) {
+        super.setLength(length);
+        underlying.setLength(length);
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        return underlying.asObjectArray();
+    }
+
+    @Override
+    public Object asArrayOfType(final Class<?> componentType) {
+        return underlying.asArrayOfType(componentType);
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        underlying.shiftLeft(by);
+        setLength(underlying.length());
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        underlying = underlying.shiftRight(by);
+        setLength(underlying.length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        underlying = underlying.ensure(safeIndex);
+        setLength(underlying.length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        underlying = underlying.shrink(newLength);
+        setLength(underlying.length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        underlying = underlying.set(index, value, strict);
+        setLength(underlying.length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        underlying = underlying.set(index, value, strict);
+        setLength(underlying.length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        underlying = underlying.set(index, value, strict);
+        setLength(underlying.length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        underlying = underlying.set(index, value, strict);
+        setLength(underlying.length());
+
+        return this;
+    }
+
+    @Override
+    public int getInt(final int index) {
+        return underlying.getInt(index);
+    }
+
+    @Override
+    public long getLong(final int index) {
+        return underlying.getLong(index);
+    }
+
+    @Override
+    public double getDouble(final int index) {
+        return underlying.getDouble(index);
+    }
+
+    @Override
+    public Object getObject(final int index) {
+        return underlying.getObject(index);
+    }
+
+    @Override
+    public boolean has(final int index) {
+        return underlying.has(index);
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        underlying = underlying.delete(index);
+        setLength(underlying.length());
+        return this;
+    }
+
+    @Override
+    public ArrayData delete(final long from, final long to) {
+        underlying = underlying.delete(from, to);
+        setLength(underlying.length());
+        return this;
+    }
+
+    @Override
+    protected ArrayData convert(final Class<?> type) {
+        underlying = underlying.convert(type);
+        setLength(underlying.length());
+        return this;
+    }
+
+    @Override
+    public Object pop() {
+        final Object value = underlying.pop();
+        setLength(underlying.length());
+
+        return value;
+    }
+
+    @Override
+    public long nextIndex(final long index) {
+        return underlying.nextIndex(index);
+    }
+
+    static Object convertUndefinedValue(final Class<?> targetType) {
+        return invoke(Bootstrap.getLinkerServices().getTypeConverter(Undefined.class, targetType),
+                ScriptRuntime.UNDEFINED);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java
new file mode 100644
index 0000000..c7de94b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java
@@ -0,0 +1,247 @@
+/*
+ * 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.arrays;
+
+import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.JSType;
+
+/**
+ * Array index computation helpers. that both throw exceptions or return
+ * invalid values.
+ *
+ */
+public final class ArrayIndex {
+
+    private static final int  INVALID_ARRAY_INDEX = -1;
+    private static final long MAX_ARRAY_INDEX = 0xfffffffeL;
+
+    private ArrayIndex() {
+    }
+
+    /**
+     * Fast conversion of non-negative integer string to long.
+     * @param key Key as a string.
+     * @return long value of string or -1.
+     */
+    private static long fromString(final String key) {
+        long value = 0;
+        final int length = key.length();
+
+        // Check for empty string or leading 0
+        if (length == 0 || (length > 1 && key.charAt(0) == '0')) {
+            return -1;
+        }
+
+        // Fast toNumber.
+        for (int i = 0; i < length; i++) {
+            final char digit = key.charAt(i);
+
+            // If not a digit.
+            if (digit < '0' || digit > '9') {
+                return -1;
+            }
+
+            // Insert digit.
+            value = value * 10 + digit - '0';
+
+            // Check for overflow (need to catch before wrap around.)
+            if (value > MAX_ARRAY_INDEX) {
+                return -1;
+            }
+        }
+
+        return value;
+    }
+
+    /**
+     * Returns a valid array index in an int, if the object represents one. This
+     * routine needs to perform quickly since all keys are tested with it.
+     *
+     * @param  key key to check for array index
+     * @return valid array index, or negative value if not valid
+     */
+    public static int getArrayIndexNoThrow(final Object key) {
+        if (key instanceof Number) {
+            return getArrayIndexNoThrow(((Number)key).doubleValue());
+        } else if (key instanceof String) {
+            return (int)fromString((String)key);
+        } else if (key instanceof ConsString) {
+            return (int)fromString(key.toString());
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns a valid array index in an int, if the object represents one
+     *
+     * @param key key to check
+     * @return array index for key
+     * @throws InvalidArrayIndexException if not a valid array index key
+     */
+    public static int getArrayIndex(final Object key) throws InvalidArrayIndexException {
+        final int index = getArrayIndexNoThrow(key);
+        if (index != -1) {
+            return index;
+        }
+
+        throw new InvalidArrayIndexException(key);
+    }
+
+    /**
+     * Returns a valid array index in an int, if the long represents one
+     *
+     * @param key key to check
+     * @return valid index or a negative value if long is not a valid array index
+     */
+    public static int getArrayIndexNoThrow(final long key) {
+        if (key >= 0 && key <= MAX_ARRAY_INDEX) {
+            return (int)key;
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns a valid array index in an int, if the long represents one
+     *
+     * @param key key to check
+     * @return valid index for the long
+     * @throws InvalidArrayIndexException if long is not a valid array index
+     */
+    public static int getArrayIndex(final long key) throws InvalidArrayIndexException {
+        final int index = getArrayIndexNoThrow(key);
+        if (index != -1) {
+            return index;
+        }
+
+        throw new InvalidArrayIndexException(key);
+    }
+
+
+    /**
+     * Return a valid index for this double, if it represents one
+     *
+     * Doubles that aren't representable exactly as longs/ints aren't working
+     * array indexes, however, array[1.1] === array["1.1"] in JavaScript.
+     *
+     * @param key the key to check
+     * @return the array index this double represents or a negative value if this isn't an index
+     */
+    public static int getArrayIndexNoThrow(final double key) {
+        if (JSType.isRepresentableAsInt(key)) {
+            final int intKey = (int)key;
+            if (intKey >= 0) {
+                return intKey;
+            }
+        } else if (JSType.isRepresentableAsLong(key)) {
+            return getArrayIndexNoThrow((long)key);
+        }
+
+        return -1;
+    }
+
+    /**
+     * Return a valid array index for this double, if it represents one
+     *
+     * Doubles that aren't representable exactly as longs/ints aren't working
+     * array indexes, however, array[1.1] === array["1.1"] in JavaScript.
+     *
+     * @param key the key to check
+     * @return the array index this double represents
+     * @throws InvalidArrayIndexException if this isn't an array index
+     */
+    public static int getArrayIndex(final double key) throws InvalidArrayIndexException {
+        final int index = getArrayIndexNoThrow(key);
+        if (index != -1) {
+            return index;
+        }
+
+        throw new InvalidArrayIndexException(key);
+    }
+
+    /**
+     * Return a valid array index for this string, if it represents one
+     *
+     * @param key the key to check
+     * @return the array index this string represents or a negative value if this isn't an index
+     */
+    public static int getArrayIndexNoThrow(final String key) {
+        return (int)fromString(key);
+    }
+
+    /**
+     * Return a valid array index for this string, if it represents one
+     *
+     * @param key the key to check
+     * @return the array index this string represents
+     * @throws InvalidArrayIndexException if the string isn't an array index
+     */
+    public static int getArrayIndex(final String key) throws InvalidArrayIndexException {
+        final int index = getArrayIndexNoThrow(key);
+        if (index != -1) {
+            return index;
+        }
+
+        throw new InvalidArrayIndexException(key);
+    }
+
+    /**
+     * Check whether an index is valid as an array index. This check only tests if
+     * it is the special "invalid array index" type, not if it is e.g. less than zero
+     * or corrupt in some other way
+     *
+     * @param index index to test
+     * @return true if {@code index} is not the special invalid array index type
+     */
+    public static boolean isValidArrayIndex(final int index) {
+        return index != INVALID_ARRAY_INDEX;
+    }
+
+    /**
+     * Convert an index to a long value. This basically amounts to ANDing it
+     * with {@link JSType#MAX_UINT}, as the maximum array index in JavaScript
+     * is 0xffffffff
+     *
+     * @param index index to convert to long form
+     * @return index as uint32 in a long
+     */
+    public static long toLongIndex(final int index) {
+        return index & JSType.MAX_UINT;
+    }
+
+    /**
+     * Check whether a key string can be used as a valid numeric array index in
+     * JavaScript
+     *
+     * @param key the key
+     * @return true if key works as a valid numeric array index
+     */
+    public static boolean isIndexKey(final String key) {
+       return ArrayIndex.getArrayIndexNoThrow(key) >= 0;
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java
new file mode 100644
index 0000000..3b9905a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java
@@ -0,0 +1,88 @@
+/*
+ * 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.arrays;
+
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Iterator over a NativeArray
+ */
+public class ArrayIterator extends ArrayLikeIterator<Object> {
+
+    /** Array {@link ScriptObject} to iterate over */
+    protected final ScriptObject array;
+
+    /** length of array */
+    protected final int length;
+
+    /**
+     * Constructor
+     * @param array array to iterate over
+     * @param includeUndefined should undefined elements be included in iteration
+     */
+    protected ArrayIterator(final ScriptObject array, final boolean includeUndefined) {
+        super(includeUndefined);
+        this.array = array;
+        this.length = (int) array.getArray().length();
+    }
+
+    /**
+     * Is the current index still inside the array
+     * @return true if inside the array
+     */
+    protected boolean indexInArray() {
+        return index < length;
+    }
+
+    @Override
+    public Object next() {
+        return array.get(bumpIndex());
+    }
+
+    @Override
+    public int getLength() {
+        return length;
+    }
+
+    @Override
+    public boolean hasNext() {
+        if (!includeUndefined) {
+            while (indexInArray()) {
+                if (array.has(index)) {
+                    break;
+                }
+                bumpIndex();
+            }
+        }
+
+        return indexInArray();
+    }
+
+    @Override
+    public void remove() {
+        array.delete(index, array.isStrictContext());
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java
new file mode 100644
index 0000000..1703b7e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java
@@ -0,0 +1,155 @@
+/*
+ * 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.arrays;
+
+import java.util.Iterator;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Superclass for array iterators
+ * TODO: rewrite these
+ *
+ * @param <T> element type
+ */
+abstract public class ArrayLikeIterator<T> implements Iterator<T> {
+
+    /** current element index in iteration */
+    protected int index;
+
+    /** should undefined elements be included in the iteration? */
+    protected final boolean includeUndefined;
+
+    /**
+     * Constructor
+     *
+     * @param includeUndefined should undefined elements be included in the iteration?
+     */
+    protected ArrayLikeIterator(final boolean includeUndefined) {
+        this.includeUndefined = includeUndefined;
+        this.index = 0;
+    }
+
+    /**
+     * Is this a reverse order iteration?
+     * @return true if reverse
+     */
+    @SuppressWarnings("static-method")
+    public boolean isReverse() {
+        return false;
+    }
+
+    /**
+     * Go the the next valid element index of the iterator
+     * @return next index
+     */
+    protected int bumpIndex() {
+        return index++;
+    }
+
+    /**
+     * Return the next valid element index of the iterator
+     * @return next index
+     */
+    public int nextIndex() {
+        return index;
+    }
+
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException("remove");
+    }
+
+    /**
+     * Get the length of the iteration
+     * @return length
+     */
+    public abstract int getLength();
+
+    /**
+     * ArrayLikeIterator factory
+     *
+     * @param object object over which to do element iteration
+     * @return iterator
+     */
+    public static ArrayLikeIterator<Object> arrayLikeIterator(final Object object) {
+        return arrayLikeIterator(object, false);
+    }
+
+    /**
+     * ArrayLikeIterator factory (reverse order)
+     * @param object object over which to do reverse element iteration
+     * @return iterator
+     */
+    public static ArrayLikeIterator<Object> reverseArrayLikeIterator(final Object object) {
+        return reverseArrayLikeIterator(object, false);
+    }
+
+    /**
+     * ArrayLikeIterator factory
+     * @param object object over which to do reverse element iteration
+     * @param includeUndefined should undefined elements be included in the iteration
+     * @return iterator
+     */
+    public static ArrayLikeIterator<Object> arrayLikeIterator(final Object object, final boolean includeUndefined) {
+        Object obj = object;
+
+        if (ScriptObject.isArray(obj)) {
+            return new ArrayIterator((ScriptObject) obj, includeUndefined);
+        }
+
+        obj = JSType.toScriptObject(obj);
+        if (obj instanceof ScriptObject) {
+            return new MapIterator((ScriptObject)obj, includeUndefined);
+        }
+
+        return new EmptyArrayLikeIterator();
+    }
+
+    /**
+     * ArrayLikeIterator factory (reverse order)
+     * @param object object over which to do reverse element iteration
+     * @param includeUndefined should undefined elements be included in the iteration
+     * @return iterator
+     */
+    public static ArrayLikeIterator<Object> reverseArrayLikeIterator(final Object object, final boolean includeUndefined) {
+        Object obj = object;
+
+        if (ScriptObject.isArray(obj)) {
+            return new ReverseArrayIterator((ScriptObject) obj, includeUndefined);
+        }
+
+        obj = JSType.toScriptObject(obj);
+        if (obj instanceof ScriptObject) {
+            return new ReverseMapIterator((ScriptObject)obj, includeUndefined);
+        }
+
+        assert !obj.getClass().isArray();
+
+        return new EmptyArrayLikeIterator();
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java
new file mode 100644
index 0000000..57bea4c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java
@@ -0,0 +1,182 @@
+/*
+ * 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.arrays;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.lang.reflect.Array;
+import jdk.nashorn.internal.runtime.BitVector;
+
+/**
+ * This filter handles the deletion of array elements.
+ */
+final class DeletedArrayFilter extends ArrayFilter {
+    /** Bit vector tracking deletions. */
+    private final BitVector deleted;
+
+    DeletedArrayFilter(final ArrayData underlying) {
+        super(underlying);
+
+        this.deleted = new BitVector(underlying.length());
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        final Object[] value = super.asObjectArray();
+
+        for (int i = 0; i < value.length; i++) {
+            if (deleted.isSet(i)) {
+                value[i] = UNDEFINED;
+            }
+        }
+
+        return value;
+    }
+
+    @Override
+    public Object asArrayOfType(final Class<?> componentType) {
+        final Object value = super.asArrayOfType(componentType);
+        final Object undefValue = convertUndefinedValue(componentType);
+        final int l = Array.getLength(value);
+        for (int i = 0; i < l; i++) {
+            if (deleted.isSet(i)) {
+                Array.set(value, i, undefValue);
+            }
+        }
+
+        return value;
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        super.shiftLeft(by);
+        deleted.shiftLeft(by, length());
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        super.shiftRight(by);
+        deleted.shiftRight(by, length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) {
+            return new SparseArrayData(this, safeIndex + 1);
+        }
+
+        super.ensure(safeIndex);
+        deleted.resize(length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        super.shrink(newLength);
+        deleted.resize(length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        deleted.clear(ArrayIndex.toLongIndex(index));
+
+        return super.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        deleted.clear(ArrayIndex.toLongIndex(index));
+
+        return super.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        deleted.clear(ArrayIndex.toLongIndex(index));
+
+        return super.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        deleted.clear(ArrayIndex.toLongIndex(index));
+
+        return super.set(index, value, strict);
+    }
+
+    @Override
+    public boolean has(final int index) {
+        return super.has(index) && deleted.isClear(ArrayIndex.toLongIndex(index));
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        final long longIndex = ArrayIndex.toLongIndex(index);
+        assert longIndex >= 0 && longIndex < length();
+        deleted.set(longIndex);
+        return this;
+    }
+
+    @Override
+    public ArrayData delete(final long fromIndex, final long toIndex) {
+        assert fromIndex >= 0 && fromIndex <= toIndex && toIndex < length();
+        deleted.setRange(fromIndex, toIndex + 1);
+        return this;
+    }
+
+    @Override
+    public Object pop() {
+        final long index = length() - 1;
+
+        if (super.has((int)index)) {
+            final boolean isDeleted = deleted.isSet(index);
+            final Object value = super.pop();
+
+            return isDeleted ? UNDEFINED : value;
+        }
+
+        return super.pop();
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        final ArrayData newArray = underlying.slice(from, to);
+        final DeletedArrayFilter newFilter = new DeletedArrayFilter(newArray);
+        newFilter.getDeleted().copy(deleted);
+        newFilter.getDeleted().shiftLeft(from, newFilter.length());
+
+        return newFilter;
+    }
+
+    private BitVector getDeleted() {
+        return deleted;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java
new file mode 100644
index 0000000..588252a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java
@@ -0,0 +1,245 @@
+/*
+ * 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.arrays;
+
+import java.lang.reflect.Array;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * This filter handles the deletion of array elements.
+ */
+final class DeletedRangeArrayFilter extends ArrayFilter {
+    /** Range (inclusive) tracking deletions */
+    private long lo, hi;
+
+    DeletedRangeArrayFilter(final ArrayData underlying, final long lo, final long hi) {
+        super(underlying);
+        this.lo = lo;
+        this.hi = hi;
+    }
+
+    private boolean isEmpty() {
+        return lo > hi;
+    }
+
+    private boolean isDeleted(final int index) {
+        return lo <= index && index <= hi;
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        final Object[] value = super.asObjectArray();
+
+        if (lo <= Integer.MAX_VALUE) {
+            final int intHi = (int)Math.min(hi, Integer.MAX_VALUE);
+            for (int i = (int)lo; i <= intHi; i++) {
+                value[i] = ScriptRuntime.UNDEFINED;
+            }
+        }
+
+        return value;
+    }
+
+    @Override
+    public Object asArrayOfType(final Class<?> componentType) {
+        final Object value = super.asArrayOfType(componentType);
+        final Object undefValue = convertUndefinedValue(componentType);
+
+        if (lo <= Integer.MAX_VALUE) {
+            final int intHi = (int)Math.min(hi, Integer.MAX_VALUE);
+            for (int i = (int)lo; i <= intHi; i++) {
+                Array.set(value, i, undefValue);
+            }
+        }
+
+        return value;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) {
+            return new SparseArrayData(this, safeIndex + 1);
+        }
+
+        return super.ensure(safeIndex);
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        super.shiftLeft(by);
+        lo = Math.max(0, lo - by);
+        hi = Math.max(-1, hi - by);
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        super.shiftRight(by);
+        lo = Math.min(length(), lo + by);
+        hi = Math.min(length() - 1, hi + by);
+
+        return isEmpty() ? getUnderlying() : this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        super.shrink(newLength);
+        lo = Math.min(newLength, lo);
+        hi = Math.min(newLength - 1, hi);
+
+        return isEmpty() ? getUnderlying() : this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        final long longIndex = ArrayIndex.toLongIndex(index);
+        if (longIndex < lo || longIndex > hi) {
+            return super.set(index, value, strict);
+        } else if (longIndex > lo && longIndex < hi) {
+            return getDeletedArrayFilter().set(index, value, strict);
+        }
+        if (longIndex == lo) {
+            lo++;
+        } else {
+            assert longIndex == hi;
+            hi--;
+        }
+
+        return isEmpty() ? getUnderlying().set(index, value, strict) : super.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        final long longIndex = ArrayIndex.toLongIndex(index);
+        if (longIndex < lo || longIndex > hi) {
+            return super.set(index, value, strict);
+        } else if (longIndex > lo && longIndex < hi) {
+            return getDeletedArrayFilter().set(index, value, strict);
+        }
+        if (longIndex == lo) {
+            lo++;
+        } else {
+            assert longIndex == hi;
+            hi--;
+        }
+
+        return isEmpty() ? getUnderlying().set(index, value, strict) : super.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        final long longIndex = ArrayIndex.toLongIndex(index);
+        if (longIndex < lo || longIndex > hi) {
+            return super.set(index, value, strict);
+        } else if (longIndex > lo && longIndex < hi) {
+            return getDeletedArrayFilter().set(index, value, strict);
+        }
+        if (longIndex == lo) {
+            lo++;
+        } else {
+            assert longIndex == hi;
+            hi--;
+        }
+
+        return isEmpty() ? getUnderlying().set(index, value, strict) : super.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        final long longIndex = ArrayIndex.toLongIndex(index);
+        if (longIndex < lo || longIndex > hi) {
+            return super.set(index, value, strict);
+        } else if (longIndex > lo && longIndex < hi) {
+            return getDeletedArrayFilter().set(index, value, strict);
+        }
+        if (longIndex == lo) {
+            lo++;
+        } else {
+            assert longIndex == hi;
+            hi--;
+        }
+
+        return isEmpty() ? getUnderlying().set(index, value, strict) : super.set(index, value, strict);
+    }
+
+    @Override
+    public boolean has(final int index) {
+        return super.has(index) && !isDeleted(index);
+    }
+
+    private ArrayData getDeletedArrayFilter() {
+        final ArrayData deleteFilter = new DeletedArrayFilter(getUnderlying());
+
+        for (long i = lo; i <= hi; i++) {
+            deleteFilter.delete((int) i);
+        }
+
+        return deleteFilter;
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        final long longIndex = ArrayIndex.toLongIndex(index);
+        if (longIndex + 1 == lo) {
+            lo = longIndex;
+        } else if (longIndex - 1 == hi) {
+            hi = longIndex;
+        } else if (longIndex < lo || hi < longIndex) {
+           return getDeletedArrayFilter().delete(index);
+        }
+
+        return this;
+    }
+
+    @Override
+    public ArrayData delete(final long fromIndex, final long toIndex) {
+        if (fromIndex > hi + 1  || toIndex < lo - 1) {
+            return getDeletedArrayFilter().delete(fromIndex, toIndex);
+        }
+        lo = Math.min(fromIndex, lo);
+        hi = Math.max(toIndex, hi);
+        return this;
+    }
+
+    @Override
+    public Object pop() {
+        final int index = (int)(length() - 1);
+        if (super.has(index)) {
+            final boolean isDeleted = isDeleted(index);
+            final Object value      = super.pop();
+
+            lo = Math.min(index + 1, lo);
+            hi = Math.min(index, hi);
+            return isDeleted ? ScriptRuntime.UNDEFINED : value;
+        }
+
+        return super.pop();
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        return new DeletedRangeArrayFilter(underlying.slice(from, to), Math.max(0, lo - from), Math.max(0, hi - from));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java
new file mode 100644
index 0000000..5264283
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java
@@ -0,0 +1,53 @@
+/*
+ * 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.arrays;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Dummy array iterator that has no elements
+ */
+final class EmptyArrayLikeIterator extends ArrayLikeIterator<Object> {
+
+    EmptyArrayLikeIterator() {
+        super(false);
+    }
+
+    @Override
+    public boolean hasNext() {
+        return false;
+    }
+
+    @Override
+    public Object next() {
+        throw new NoSuchElementException();
+    }
+
+    @Override
+    public int getLength() {
+        return 0;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java
new file mode 100644
index 0000000..07a53fd
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java
@@ -0,0 +1,77 @@
+/*
+ * 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.arrays;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
+import jdk.nashorn.internal.runtime.GlobalObject;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+
+/**
+ * ArrayData after the array has been frozen by Object.freeze call.
+ */
+final class FrozenArrayFilter extends SealedArrayFilter {
+    FrozenArrayFilter(final ArrayData underlying) {
+        super(underlying);
+    }
+
+    @Override
+    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+        return global.newDataDescriptor(getObject(index), false, true, false);
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        if (strict) {
+            throw typeError("cant.set.property", Integer.toString(index), "frozen array");
+        }
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        if (strict) {
+            throw typeError("cant.set.property", Integer.toString(index), "frozen array");
+        }
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        if (strict) {
+            throw typeError("cant.set.property", Integer.toString(index), "frozen array");
+        }
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        if (strict) {
+            throw typeError("cant.set.property", Integer.toString(index), "frozen array");
+        }
+        return this;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java
new file mode 100644
index 0000000..3c34081
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java
@@ -0,0 +1,274 @@
+/*
+ * 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.arrays;
+
+import java.util.Arrays;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Implementation of {@link ArrayData} as soon as an int has been
+ * written to the array. This is the default data for new arrays
+ */
+public final class IntArrayData extends ArrayData {
+    /**
+     * The wrapped array
+     */
+    private int[] array;
+
+    IntArrayData() {
+        this(new int[ArrayData.CHUNK_SIZE], 0);
+    }
+
+    IntArrayData(final int length) {
+        super(length);
+        this.array  = new int[ArrayData.nextSize(length)];
+    }
+
+    /**
+     * Constructor
+     * @param array an int array
+     * @param length a length, not necessarily array.length
+     */
+    IntArrayData(final int array[], final int length) {
+        super(length);
+        this.array = array;
+        if (array.length > length) {
+            Arrays.fill(array, length, array.length, 0);
+        }
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        return toObjectArray(array, (int) length());
+    }
+
+    @Override
+    public Object asArrayOfType(final Class<?> componentType) {
+        if(componentType == int.class) {
+            return array.length == length() ? array.clone() : Arrays.copyOf(array, (int) length());
+        }
+        return super.asArrayOfType(componentType);
+    }
+
+    private static Object[] toObjectArray(final int[] array, final int length) {
+        final Object[] oarray = new Object[length];
+        for (int index = 0; index < length; index++) {
+            oarray[index] = Integer.valueOf(array[index]);
+        }
+
+        return oarray;
+    }
+
+    private static double[] toDoubleArray(final int[] array) {
+        final double[] darray = new double[array.length];
+        for (int index = 0; index < array.length; index++) {
+            darray[index] = array[index];
+        }
+
+        return darray;
+    }
+
+    private static long[] toLongArray(final int[] array) {
+        final long[] larray = new long[array.length];
+        for (int index = 0; index < array.length; index++) {
+            larray[index] = array[index];
+        }
+
+        return larray;
+    }
+
+    @Override
+    public ArrayData convert(final Class<?> type) {
+        if (type == Integer.class) {
+            return this;
+        } else if (type == Long.class) {
+            return new LongArrayData(IntArrayData.toLongArray(array), (int) length());
+        } else if (type == Double.class) {
+            return new NumberArrayData(IntArrayData.toDoubleArray(array), (int) length());
+        } else {
+            return new ObjectArrayData(IntArrayData.toObjectArray(array, array.length), (int) length());
+        }
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        System.arraycopy(array, by, array, 0, array.length - by);
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        final ArrayData newData = ensure(by + length() - 1);
+        if (newData != this) {
+            newData.shiftRight(by);
+            return newData;
+        }
+        System.arraycopy(array, 0, array, by, array.length - by);
+
+        return this;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= array.length) {
+            return new SparseArrayData(this, safeIndex + 1);
+        }
+
+        int newLength = array.length;
+
+        while (newLength <= safeIndex) {
+            newLength = ArrayData.nextSize(newLength);
+        }
+
+        if (array.length <= safeIndex) {
+            array = Arrays.copyOf(array, newLength);
+        }
+
+        setLength(safeIndex + 1);
+
+        return this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        Arrays.fill(array, (int) newLength, array.length, 0);
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        try {
+            final int intValue = ((Integer)value).intValue();
+            array[index] = intValue;
+            setLength(Math.max(index + 1, length()));
+            return this;
+        } catch (final NullPointerException | ClassCastException e) {
+            if (value instanceof Short || value instanceof Byte) {
+                final int intValue = ((Number)value).intValue();
+                array[index] = intValue;
+                setLength(Math.max(index + 1, length()));
+                return this;
+            }
+
+            if (value == ScriptRuntime.UNDEFINED) {
+                return new UndefinedArrayFilter(this).set(index, value, strict);
+            }
+        }
+
+        final ArrayData newData = convert(value == null ? Object.class : value.getClass());
+
+        return newData.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        final int intValue = (int)value;
+        if (intValue == value) {
+            array[index] = intValue;
+            setLength(Math.max(index + 1, length()));
+            return this;
+        }
+
+        return convert(Long.class).set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        if (JSType.isRepresentableAsInt(value)) {
+            array[index] = (int)(long)value;
+            setLength(Math.max(index + 1, length()));
+            return this;
+        }
+
+        return convert(Double.class).set(index, value, strict);
+    }
+
+    @Override
+    public int getInt(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public long getLong(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public double getDouble(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public Object getObject(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public boolean has(final int index) {
+        return 0 <= index && index < length();
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        return new DeletedRangeArrayFilter(this, index, index);
+    }
+
+    @Override
+    public ArrayData delete(final long fromIndex, final long toIndex) {
+        return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
+    }
+
+    @Override
+    public Object pop() {
+        if (length() == 0) {
+            return ScriptRuntime.UNDEFINED;
+        }
+
+        final int newLength = (int) length() - 1;
+        final int elem = array[newLength];
+        array[newLength] = 0;
+        setLength(newLength);
+
+        return elem;
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        final long start     = from < 0 ? (from + length()) : from;
+        final long newLength = to - start;
+
+        return new IntArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/InvalidArrayIndexException.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/InvalidArrayIndexException.java
new file mode 100644
index 0000000..170b65d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/InvalidArrayIndexException.java
@@ -0,0 +1,66 @@
+/*
+ * 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.arrays;
+
+/**
+ * Mechanism for communicating that something isn't a plain
+ * numeric integer array index. This enables things like
+ * array getters for the fast case in a try, basically
+ * just consisting of an "array[index]" access without
+ * any checks of boundary conditions that rarely happen
+ */
+@SuppressWarnings("serial")
+class InvalidArrayIndexException extends Exception {
+
+    private final Object index;
+
+    InvalidArrayIndexException(final Object index) {
+        super(index == null ? "null" : index.toString());
+        this.index = index;
+    }
+
+    InvalidArrayIndexException(final int index) {
+        this(Integer.valueOf(index));
+    }
+
+    InvalidArrayIndexException(final long index) {
+        this(Long.valueOf(index));
+    }
+
+    InvalidArrayIndexException(final double index) {
+        this(Double.valueOf(index));
+    }
+
+    @Override
+    public String toString() {
+        return index.toString();
+    }
+
+    Object getIndex() {
+        return index;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java
new file mode 100644
index 0000000..9fb4eed
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java
@@ -0,0 +1,139 @@
+/*
+ * 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.arrays;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Helper class for the various map/apply functions in {@link jdk.nashorn.internal.objects.NativeArray}.
+ * @param <T> element type of results from application callback
+ */
+public abstract class IteratorAction<T> {
+    /** Self object */
+    protected final Object self;
+
+    /** This for the callback invocation */
+    protected Object thisArg;
+
+    /** Callback function to be applied to elements */
+    protected final Object callbackfn;
+
+    /** Result of array iteration */
+    protected T result;
+
+    /** Current array index of iterator */
+    protected int index;
+
+    /** Iterator object */
+    private final ArrayLikeIterator<Object> iter;
+
+    /**
+     * Constructor
+     *
+     * @param self          self reference to array object
+     * @param callbackfn    callback function for each element
+     * @param thisArg       the reference
+     * @param initialResult result accumulator initialization
+     */
+    public IteratorAction(final Object self, final Object callbackfn, final Object thisArg, final T initialResult) {
+        this(self, callbackfn, thisArg, initialResult, ArrayLikeIterator.arrayLikeIterator(self));
+    }
+
+    /**
+     * Constructor
+     *
+     * @param self          self reference to array object
+     * @param callbackfn    callback function for each element
+     * @param thisArg       the reference
+     * @param initialResult result accumulator initialization
+     * @param iter          custom element iterator
+     */
+    public IteratorAction(final Object self, final Object callbackfn, final Object thisArg, final T initialResult, final ArrayLikeIterator<Object> iter) {
+        this.self       = self;
+        this.callbackfn = callbackfn;
+        this.result     = initialResult;
+        this.iter       = iter;
+        this.thisArg    = thisArg;
+    }
+
+    /**
+     * An action to be performed once at the start of the apply loop
+     * @param iterator array element iterator
+     */
+    protected void applyLoopBegin(final ArrayLikeIterator<Object> iterator) {
+        //empty
+    }
+
+    /**
+     * Apply action main loop.
+     * @return result of apply
+     */
+    public final T apply() {
+        if (!(callbackfn instanceof ScriptFunction)) {
+            throw typeError("not.a.function", ScriptRuntime.safeToString(callbackfn));
+        }
+        final ScriptFunction func = ((ScriptFunction)callbackfn);
+        // for non-strict callback, need to translate undefined thisArg to be global object
+        thisArg = (thisArg == ScriptRuntime.UNDEFINED && !func.isStrict()) ? Context.getGlobal() : thisArg;
+
+        applyLoopBegin(iter);
+        final boolean reverse = iter.isReverse();
+        while (iter.hasNext()) {
+
+            final Object val = iter.next();
+            index = iter.nextIndex() + (reverse ? 1 : -1);
+
+            try {
+                if (!forEach(val, index)) {
+                    return result;
+                }
+            } catch (final RuntimeException | Error e) {
+                throw e;
+            } catch (final Throwable t) {
+                throw new RuntimeException(t);
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * For each callback
+     *
+     * @param val value
+     * @param i   position of value
+     *
+     * @return true if callback invocation return true
+     *
+     * @throws Throwable if invocation throws an exception/error
+     */
+    protected abstract boolean forEach(final Object val, final int i) throws Throwable;
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java
new file mode 100644
index 0000000..800c7c6
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java
@@ -0,0 +1,236 @@
+/*
+ * 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.arrays;
+
+import java.util.Arrays;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Implementation of {@link ArrayData} as soon as a long has been
+ * written to the array
+ */
+final class LongArrayData extends ArrayData {
+    /**
+     * The wrapped array
+     */
+    private long[] array;
+
+    /**
+     * Constructor
+     * @param array an int array
+     * @param length a length, not necessarily array.length
+     */
+    LongArrayData(final long array[], final int length) {
+        super(length);
+        this.array  = array;
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        return toObjectArray(array, (int) length());
+    }
+
+    private static Object[] toObjectArray(final long[] array, final int length) {
+        final Object[] oarray = new Object[length];
+        for (int index = 0; index < length; index++) {
+            oarray[index] = Long.valueOf(array[index]);
+        }
+
+        return oarray;
+    }
+
+    @Override
+    public Object asArrayOfType(final Class<?> componentType) {
+        if(componentType == long.class) {
+            return array.length == length() ? array.clone() : Arrays.copyOf(array, (int) length());
+        }
+        return super.asArrayOfType(componentType);
+    }
+
+    private static double[] toDoubleArray(final long[] array) {
+        final double[] darray = new double[array.length];
+        for (int index = 0; index < array.length; index++) {
+            darray[index] = array[index];
+        }
+
+        return darray;
+    }
+
+    @Override
+    public ArrayData convert(final Class<?> type) {
+        if (type == Long.class) {
+            return this;
+        } else if (type == Double.class) {
+            return new NumberArrayData(LongArrayData.toDoubleArray(array), (int) length());
+        } else {
+            return new ObjectArrayData(LongArrayData.toObjectArray(array, array.length), (int) length());
+        }
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        System.arraycopy(array, by, array, 0, array.length - by);
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        final ArrayData newData = ensure(by + length() - 1);
+        if (newData != this) {
+            newData.shiftRight(by);
+            return newData;
+        }
+        System.arraycopy(array, 0, array, by, array.length - by);
+
+        return this;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= array.length) {
+            return new SparseArrayData(this, safeIndex + 1);
+        }
+
+        int newLength = array.length;
+
+        while (newLength <= safeIndex) {
+            newLength = ArrayData.nextSize(newLength);
+        }
+
+        if (array.length <= safeIndex) {
+            array = Arrays.copyOf(array, newLength);
+        }
+
+        setLength(safeIndex + 1);
+
+        return this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        Arrays.fill(array, (int) newLength, array.length, 0);
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        try {
+            final long longValue = ((Long)value).longValue();
+            array[index] = longValue;
+            setLength(Math.max(index + 1, length()));
+            return this;
+        } catch (final NullPointerException | ClassCastException e) {
+            if (value == ScriptRuntime.UNDEFINED) {
+                return new UndefinedArrayFilter(this).set(index, value, strict);
+            }
+        }
+
+        final ArrayData newData = convert(value == null ? Object.class : value.getClass());
+
+        return newData.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        if (JSType.isRepresentableAsLong(value)) {
+            array[index] = (long)value;
+            setLength(Math.max(index + 1, length()));
+            return this;
+        }
+        return convert(Double.class).set(index, value, strict);
+    }
+
+    @Override
+    public int getInt(final int index) {
+        return (int)array[index];
+    }
+
+    @Override
+    public long getLong(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public double getDouble(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public Object getObject(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public boolean has(final int index) {
+        return 0 <= index && index < length();
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        return new DeletedRangeArrayFilter(this, index, index);
+    }
+
+    @Override
+    public ArrayData delete(final long fromIndex, final long toIndex) {
+        return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
+    }
+
+    @Override
+    public Object pop() {
+        if (length() == 0) {
+            return ScriptRuntime.UNDEFINED;
+        }
+
+        final int newLength = (int) (length() - 1);
+        final long elem = array[newLength];
+        array[newLength] = 0;
+        setLength(newLength);
+
+        return elem;
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        final long start     = from < 0 ? (from + length()) : from;
+        final long newLength = to - start;
+        return new LongArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java
new file mode 100644
index 0000000..be9bc23
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java
@@ -0,0 +1,81 @@
+/*
+ * 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.arrays;
+
+import java.util.NoSuchElementException;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Iterator over a map
+ */
+class MapIterator extends ArrayLikeIterator<Object> {
+
+    protected final ScriptObject obj;
+    private final long length;
+
+    MapIterator(final ScriptObject obj, final boolean includeUndefined) {
+        super(includeUndefined);
+        this.obj    = obj;
+        this.length = JSType.toUint32(obj.getLength());
+        this.index  = 0;
+    }
+
+    protected boolean indexInArray() {
+        return index < length;
+    }
+
+    @Override
+    public int getLength() {
+        return (int) length;
+    }
+
+    @Override
+    public boolean hasNext() {
+        if (length == 0L) {
+            return false; //return empty string if toUint32(length) == 0
+        }
+
+        while (indexInArray()) {
+            if (obj.has(index) || includeUndefined) {
+                break;
+            }
+            bumpIndex();
+        }
+
+        // special case - balk at iterating to infinity or MAX_UINT
+        return (length != JSType.MAX_UINT) && indexInArray();
+    }
+
+    @Override
+    public Object next() {
+        if (indexInArray()) {
+            return obj.get(bumpIndex());
+        }
+
+        throw new NoSuchElementException();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/NoTypeArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NoTypeArrayData.java
new file mode 100644
index 0000000..8fb5360
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NoTypeArrayData.java
@@ -0,0 +1,181 @@
+/*
+ * 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.arrays;
+
+import java.lang.reflect.Array;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Place holding array data for non-array objects.  Activates a true array when
+ * accessed.  Should only exist as a singleton defined in ArrayData.
+ */
+final class NoTypeArrayData extends ArrayData {
+    NoTypeArrayData() {
+        super(0);
+    }
+
+    NoTypeArrayData(final long length) {
+         super(length);
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        return new Object[0];
+    }
+
+    @Override
+    public Object asArrayOfType(final Class<?> componentType) {
+        return Array.newInstance(componentType, 0);
+    }
+
+    @Override
+    public ArrayData convert(final Class<?> type) {
+        final long length = length();
+        final ArrayData arrayData;
+        if (type == Long.class) {
+            arrayData = new LongArrayData(new long[ArrayData.nextSize((int)length)], (int)length);
+        } else if (type == Double.class) {
+            arrayData = new NumberArrayData(new double[ArrayData.nextSize((int)length)], (int)length);
+        } else if (type == Integer.class) {
+            arrayData = new IntArrayData(new int[ArrayData.nextSize((int)length)], (int)length);
+        } else {
+            assert !type.isPrimitive();
+            arrayData = new ObjectArrayData(new Object[ArrayData.nextSize((int)length)], (int)length);
+        }
+        return length == 0 ? arrayData : new DeletedRangeArrayFilter(arrayData, 0, length - 1);
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        //empty
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        return this;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
+            return new SparseArrayData(this, safeIndex + 1);
+        }
+
+        // Don't trample the shared EMPTY_ARRAY.
+        if (length() == 0) {
+            return new NoTypeArrayData(Math.max(safeIndex + 1, length()));
+        }
+
+        setLength(Math.max(safeIndex + 1, length()));
+        return this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        ArrayData newData;
+
+        if (value instanceof Double) {
+            newData = convert(Double.class);
+        } else if (value instanceof Long) {
+            newData = convert(Long.class);
+        } else if (value instanceof Integer) {
+            newData = convert(Integer.class);
+        } else {
+            assert !(value instanceof Number);
+            newData = convert(value == null ? Object.class : value.getClass());
+        }
+
+        return newData.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        final ArrayData newData = convert(Integer.class);
+        return newData.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        final ArrayData newData = convert(Long.class);
+        return newData.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        final ArrayData newData = convert(Double.class);
+        return newData.set(index, value, strict);
+    }
+
+    @Override
+    public int getInt(final int index) {
+        throw new ArrayIndexOutOfBoundsException(index);
+    }
+
+    @Override
+    public long getLong(final int index) {
+        throw new ArrayIndexOutOfBoundsException(index);
+    }
+
+    @Override
+    public double getDouble(final int index) {
+        throw new ArrayIndexOutOfBoundsException(index);
+    }
+
+    @Override
+    public Object getObject(final int index) {
+        throw new ArrayIndexOutOfBoundsException(index);
+    }
+
+    @Override
+    public boolean has(final int index) {
+        return false;
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        return new DeletedRangeArrayFilter(this, index, index);
+    }
+
+    @Override
+    public ArrayData delete(final long fromIndex, final long toIndex) {
+        return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
+    }
+
+    @Override
+    public Object pop() {
+        return ScriptRuntime.UNDEFINED;
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        return this;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java
new file mode 100644
index 0000000..149cbf0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java
@@ -0,0 +1,219 @@
+/*
+ * 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.arrays;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.util.Arrays;
+
+/**
+ * Implementation of {@link ArrayData} as soon as a double has been
+ * written to the array
+ */
+final class NumberArrayData extends ArrayData {
+    /**
+     * The wrapped array
+     */
+    private double[] array;
+
+    /**
+     * Constructor
+     * @param array an int array
+     * @param length a length, not necessarily array.length
+     */
+    NumberArrayData(final double array[], final int length) {
+        super(length);
+        this.array  = array;
+        if (array.length > length) {
+            Arrays.fill(array, length, array.length, 0.0);
+        }
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        return toObjectArray(array, (int) length());
+    }
+
+    private static Object[] toObjectArray(final double[] array, final int length) {
+        final Object[] oarray = new Object[length];
+        for (int index = 0; index < length; index++) {
+            oarray[index] = Double.valueOf(array[index]);
+        }
+        return oarray;
+    }
+
+    @Override
+    public Object asArrayOfType(final Class<?> componentType) {
+        if(componentType == double.class) {
+            return array.length == length() ? array.clone() : Arrays.copyOf(array, (int) length());
+        }
+        return super.asArrayOfType(componentType);
+    }
+
+    @Override
+    public ArrayData convert(final Class<?> type) {
+        if (type != Double.class && type != Integer.class && type != Long.class) {
+            return new ObjectArrayData(NumberArrayData.toObjectArray(array, array.length), (int) length());
+        }
+        return this;
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        System.arraycopy(array, by, array, 0, array.length - by);
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        final ArrayData newData = ensure(by + length() - 1);
+        if (newData != this) {
+            newData.shiftRight(by);
+            return newData;
+        }
+        System.arraycopy(array, 0, array, by, array.length - by);
+        return this;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= array.length) {
+            return new SparseArrayData(this, safeIndex + 1);
+        }
+
+        int newLength = array.length;
+
+        while (newLength <= safeIndex) {
+            newLength = ArrayData.nextSize(newLength);
+        }
+
+        if (array.length <= safeIndex) {
+            array = Arrays.copyOf(array, newLength);
+            Arrays.fill(array, (int) length(), newLength, Double.NaN);
+        }
+
+        setLength(safeIndex + 1);
+
+        return this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        Arrays.fill(array, (int) newLength, array.length, 0.0);
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        try {
+            final double doubleValue = ((Number)value).doubleValue();
+            array[index] = doubleValue;
+            setLength(Math.max(index + 1, length()));
+            return this;
+        } catch (final NullPointerException | ClassCastException e) {
+            if (value == UNDEFINED) {
+                return new UndefinedArrayFilter(this).set(index, value, strict);
+            }
+        }
+        final ArrayData newData = convert(value == null ? Object.class : value.getClass());
+        return newData.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+        return this;
+    }
+
+    @Override
+    public int getInt(final int index) {
+        return (int)array[index];
+    }
+
+    @Override
+    public long getLong(final int index) {
+        return (long)array[index];
+    }
+
+    @Override
+    public double getDouble(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public Object getObject(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public boolean has(final int index) {
+        return 0 <= index && index < length();
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        return new DeletedRangeArrayFilter(this, index, index);
+    }
+
+    @Override
+    public ArrayData delete(final long fromIndex, final long toIndex) {
+        return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
+    }
+
+    @Override
+    public Object pop() {
+        if (length() == 0) {
+            return UNDEFINED;
+        }
+
+        final int newLength = (int) (length() - 1);
+        final double elem = array[newLength];
+        array[newLength] = 0;
+        setLength(newLength);
+        return elem;
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        final long start     = from < 0 ? (from + length()) : from;
+        final long newLength = to - start;
+        return new NumberArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
new file mode 100644
index 0000000..cb1e2fa
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
@@ -0,0 +1,195 @@
+/*
+ * 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.arrays;
+
+import java.util.Arrays;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Implementation of {@link ArrayData} as soon as an Object has been
+ * written to the array
+ */
+final class ObjectArrayData extends ArrayData {
+
+    /**
+     * The wrapped array
+     */
+    private Object[] array;
+
+    /**
+     * Constructor
+     * @param array an int array
+     * @param length a length, not necessarily array.length
+     */
+    ObjectArrayData(final Object array[], final int length) {
+        super(length);
+        this.array  = array;
+        if (array.length > length) {
+            Arrays.fill(array, length, array.length, ScriptRuntime.UNDEFINED);
+        }
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        return Arrays.copyOf(array, (int) length());
+    }
+
+    @Override
+    public ArrayData convert(final Class<?> type) {
+        return this;
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        System.arraycopy(array, by, array, 0, array.length - by);
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        final ArrayData newData = ensure(by + length() - 1);
+        if (newData != this) {
+            newData.shiftRight(by);
+            return newData;
+        }
+        System.arraycopy(array, 0, array, by, array.length - by);
+        return this;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= array.length) {
+            return new SparseArrayData(this, safeIndex + 1);
+        }
+
+        int newLength = array.length;
+
+        while (newLength <= safeIndex) {
+            newLength = ArrayData.nextSize(newLength);
+        }
+
+        if (array.length <= safeIndex) {
+            array = Arrays.copyOf(array, newLength);
+            Arrays.fill(array, (int) length(), newLength, ScriptRuntime.UNDEFINED);
+        }
+
+        setLength(safeIndex + 1);
+
+        return this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        Arrays.fill(array, (int) newLength, array.length, ScriptRuntime.UNDEFINED);
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        if (value == ScriptRuntime.UNDEFINED) {
+            return new UndefinedArrayFilter(this).set(index, value, strict);
+        }
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        array[index] = value;
+        setLength(Math.max(index + 1, length()));
+        return this;
+    }
+
+    @Override
+    public int getInt(final int index) {
+        return JSType.toInt32(array[index]);
+    }
+
+    @Override
+    public long getLong(final int index) {
+        return JSType.toLong(array[index]);
+    }
+
+    @Override
+    public double getDouble(final int index) {
+        return JSType.toNumber(array[index]);
+    }
+
+    @Override
+    public Object getObject(final int index) {
+        return array[index];
+    }
+
+    @Override
+    public boolean has(final int index) {
+        return 0 <= index && index < length();
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        return new DeletedRangeArrayFilter(this, index, index);
+    }
+
+    @Override
+    public ArrayData delete(final long fromIndex, final long toIndex) {
+        return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
+    }
+
+    @Override
+    public Object pop() {
+        if (length() == 0) {
+            return ScriptRuntime.UNDEFINED;
+        }
+
+        final int newLength = (int) (length() - 1);
+        final Object elem = array[newLength];
+        array[newLength] = 0;
+        setLength(newLength);
+        return elem;
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        final long start     = from < 0 ? (from + length()) : from;
+        final long newLength = to - start;
+        return new ObjectArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java
new file mode 100644
index 0000000..72a47a9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java
@@ -0,0 +1,59 @@
+/*
+ * 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.arrays;
+
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Reverse iterator over a NativeArray
+ */
+public final class ReverseArrayIterator extends ArrayIterator {
+
+    /**
+     * Constructor
+     * @param array array to iterate over
+     * @param includeUndefined should undefined elements be included in iteration
+     */
+    public ReverseArrayIterator(final ScriptObject array, final boolean includeUndefined) {
+        super(array, includeUndefined);
+        this.index = (int) (array.getArray().length() - 1);
+    }
+
+    @Override
+    public boolean isReverse() {
+        return true;
+    }
+
+    @Override
+    protected boolean indexInArray() {
+        return index >= 0;
+    }
+
+    @Override
+    protected int bumpIndex() {
+        return index--;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java
new file mode 100644
index 0000000..760ac72
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java
@@ -0,0 +1,55 @@
+/*
+ * 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.arrays;
+
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Reverse iterator over a map
+ */
+final class ReverseMapIterator extends MapIterator {
+
+    ReverseMapIterator(final ScriptObject obj, final boolean includeUndefined) {
+        super(obj, includeUndefined);
+        this.index = JSType.toInt32(obj.getLength()) - 1;
+    }
+
+    @Override
+    public boolean isReverse() {
+        return true;
+    }
+
+    @Override
+    protected boolean indexInArray() {
+        return index >= 0;
+    }
+
+    @Override
+    protected int bumpIndex() {
+        return index--;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java
new file mode 100644
index 0000000..7cf7321
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java
@@ -0,0 +1,63 @@
+/*
+ * 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.arrays;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
+import jdk.nashorn.internal.runtime.GlobalObject;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+
+/**
+ * ArrayData after the array has been sealed by Object.seal call.
+ */
+class SealedArrayFilter extends ArrayFilter {
+    SealedArrayFilter(final ArrayData underlying) {
+        super(underlying);
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        return getUnderlying().slice(from, to);
+    }
+
+    @Override
+    public boolean canDelete(final int index, final boolean strict) {
+        if (strict) {
+            throw typeError("cant.delete.property", Integer.toString(index), "sealed array");
+        }
+        return false;
+    }
+
+    @Override
+    public boolean canDelete(final long fromIndex, final long toIndex, final boolean strict) {
+        return canDelete((int) fromIndex, strict);
+    }
+
+    @Override
+    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+        return global.newDataDescriptor(getObject(index), false, true, true);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
new file mode 100644
index 0000000..e5ba1cd
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
@@ -0,0 +1,336 @@
+/*
+ * 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.arrays;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.TreeMap;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Handle arrays where the index is very large.
+ */
+class SparseArrayData extends ArrayData {
+    static final long MAX_DENSE_LENGTH = 512 * 1024;
+
+    /** Underlying array. */
+    private ArrayData underlying;
+
+    /** Maximum length to be stored in the array. */
+
+    private final long maxDenseLength;
+
+    /** Sparse elements. */
+    private TreeMap<Long, Object> sparseMap = new TreeMap<>();
+
+    SparseArrayData(final ArrayData underlying) {
+        super(underlying.length());
+        this.underlying = underlying;
+        this.maxDenseLength = Math.max(MAX_DENSE_LENGTH, underlying.length());
+    }
+
+    SparseArrayData(final ArrayData array, final long length) {
+        this(array);
+        assert array.length() <= length;
+        super.setLength(length);
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        final Object[] objArray = new Object[Math.min((int) length(), Integer.MAX_VALUE)];
+
+        for (int i = 0; i < underlying.length(); i++) {
+            objArray[i] = underlying.getObject(i);
+        }
+
+        Arrays.fill(objArray, (int) underlying.length(), objArray.length, ScriptRuntime.UNDEFINED);
+
+        for (final Map.Entry<Long, Object> entry : sparseMap.entrySet()) {
+            final long key = entry.getKey();
+            if (key <= Integer.MAX_VALUE) {
+                objArray[(int)key] = entry.getValue();
+            } else {
+                break; // ascending key order
+            }
+        }
+
+        return objArray;
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        underlying.shiftLeft(by);
+
+        final TreeMap<Long, Object> newSparseMap = new TreeMap<>();
+
+        for (final Map.Entry<Long, Object> entry : sparseMap.entrySet()) {
+            final long newIndex = entry.getKey().longValue() - by;
+            if (newIndex < maxDenseLength) {
+                underlying = underlying.set((int) newIndex, entry.getValue(), false);
+            } else if (newIndex >= 0) {
+                newSparseMap.put(Long.valueOf(newIndex), entry.getValue());
+            }
+        }
+
+        sparseMap = newSparseMap;
+        setLength(Math.max(length() - by, 0));
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        final TreeMap<Long, Object> newSparseMap = new TreeMap<>();
+        if (underlying.length() + by > maxDenseLength) {
+            for (long i = maxDenseLength - by; i < underlying.length(); i++) {
+                if (underlying.has((int) i)) {
+                    newSparseMap.put(Long.valueOf(i + by), underlying.getObject((int) i));
+                }
+            }
+            underlying = underlying.shrink((int) (maxDenseLength - by));
+        }
+
+        underlying.shiftRight(by);
+
+        for (final Map.Entry<Long, Object> entry : sparseMap.entrySet()) {
+            final long newIndex = entry.getKey().longValue() + by;
+            newSparseMap.put(Long.valueOf(newIndex), entry.getValue());
+        }
+
+        sparseMap = newSparseMap;
+        setLength(length() + by);
+
+        return this;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        if (safeIndex < maxDenseLength && underlying.length() <= safeIndex) {
+            underlying = underlying.ensure(safeIndex);
+        }
+        setLength(Math.max(safeIndex + 1, length()));
+        return this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        if (newLength < underlying.length()) {
+            underlying = underlying.shrink(newLength);
+            underlying.setLength(newLength);
+            sparseMap.clear();
+            setLength(newLength);
+        }
+
+        sparseMap.subMap(Long.valueOf(newLength), Long.MAX_VALUE).clear();
+        setLength(newLength);
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        if (index >= 0 && index < maxDenseLength) {
+            ensure(index);
+            underlying = underlying.set(index, value, strict);
+            setLength(Math.max(underlying.length(), length()));
+        } else {
+            sparseMap.put(indexToKey(index), value);
+            setLength(Math.max(index + 1, length()));
+        }
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        if (index >= 0 && index < maxDenseLength) {
+            ensure(index);
+            underlying = underlying.set(index, value, strict);
+            setLength(Math.max(underlying.length(), length()));
+        } else {
+            sparseMap.put(indexToKey(index), value);
+            setLength(Math.max(index + 1, length()));
+        }
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        if (index >= 0 && index < maxDenseLength) {
+            ensure(index);
+            underlying = underlying.set(index, value, strict);
+            setLength(Math.max(underlying.length(), length()));
+        } else {
+            sparseMap.put(indexToKey(index), value);
+            setLength(Math.max(index + 1, length()));
+        }
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        if (index >= 0 && index < maxDenseLength) {
+            ensure(index);
+            underlying = underlying.set(index, value, strict);
+            setLength(Math.max(underlying.length(), length()));
+        } else {
+            sparseMap.put(indexToKey(index), value);
+            setLength(Math.max(index + 1, length()));
+        }
+        return this;
+    }
+
+    @Override
+    public int getInt(final int index) {
+        if (index >= 0 && index < maxDenseLength) {
+            return underlying.getInt(index);
+        }
+        return JSType.toInt32(sparseMap.get(indexToKey(index)));
+    }
+
+    @Override
+    public long getLong(final int index) {
+        if (index >= 0 && index < maxDenseLength) {
+            return underlying.getLong(index);
+        }
+        return JSType.toLong(sparseMap.get(indexToKey(index)));
+    }
+
+    @Override
+    public double getDouble(final int index) {
+        if (index >= 0 && index < maxDenseLength) {
+            return underlying.getDouble(index);
+        }
+        return JSType.toNumber(sparseMap.get(indexToKey(index)));
+    }
+
+    @Override
+    public Object getObject(final int index) {
+        if (index >= 0 && index < maxDenseLength) {
+            return underlying.getObject(index);
+        }
+
+        final Long key = indexToKey(index);
+        if (sparseMap.containsKey(key)) {
+            return sparseMap.get(key);
+        }
+
+        return ScriptRuntime.UNDEFINED;
+    }
+
+    @Override
+    public boolean has(final int index) {
+        if (index >= 0 && index < maxDenseLength) {
+            return index < underlying.length() && underlying.has(index);
+        }
+
+        return sparseMap.containsKey(indexToKey(index));
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        if (index >= 0 && index < maxDenseLength) {
+            if (index < underlying.length()) {
+                underlying = underlying.delete(index);
+            }
+        } else {
+            sparseMap.remove(indexToKey(index));
+        }
+
+        return this;
+    }
+
+    @Override
+    public ArrayData delete(final long fromIndex, final long toIndex) {
+        if (fromIndex < maxDenseLength && fromIndex < underlying.length()) {
+            underlying = underlying.delete(fromIndex, Math.min(toIndex, underlying.length() - 1));
+        }
+        if (toIndex >= maxDenseLength) {
+            sparseMap.subMap(fromIndex, true, toIndex, true).clear();
+        }
+        return this;
+    }
+
+    private static Long indexToKey(final int index) {
+        return Long.valueOf(index & 0xffff_ffffL);
+    }
+
+    @Override
+    protected ArrayData convert(final Class<?> type) {
+        underlying = underlying.convert(type);
+        return this;
+    }
+
+    @Override
+    public Object pop() {
+        if (length() == 0) {
+            return ScriptRuntime.UNDEFINED;
+        }
+        if (length() == underlying.length()) {
+            final Object result = underlying.pop();
+            setLength(underlying.length());
+            return result;
+        }
+        setLength(length() - 1);
+        final Long key = Long.valueOf(length());
+        return sparseMap.containsKey(key) ? sparseMap.remove(key) : ScriptRuntime.UNDEFINED;
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        assert to <= length();
+        final long start = from < 0 ? (from + length()) : from;
+        final long newLength = to - start;
+
+        if (start >= 0 && to <= maxDenseLength) {
+            if (newLength <= underlying.length()) {
+                return underlying.slice(from, to);
+            }
+            return underlying.slice(from, to).ensure(newLength - 1).delete(underlying.length(), newLength);
+        }
+
+        ArrayData sliced = EMPTY_ARRAY;
+        sliced = sliced.ensure(newLength - 1);
+        for (long i = start; i < to; i = nextIndex(i)) {
+            if (has((int)i)) {
+                sliced = sliced.set((int)(i - start), getObject((int)i), false);
+            }
+        }
+        assert sliced.length() == newLength;
+        return sliced;
+    }
+
+    @Override
+    public long nextIndex(final long index) {
+        if (index < underlying.length() - 1) {
+            return underlying.nextIndex(index);
+        }
+
+        final Long nextKey = sparseMap.higherKey(index);
+        if (nextKey != null) {
+            return nextKey;
+        }
+        return length();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java
new file mode 100644
index 0000000..f71a995
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java
@@ -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.  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.arrays;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.lang.reflect.Array;
+import jdk.nashorn.internal.runtime.BitVector;
+
+/**
+ * This filter handles the presence of undefined array elements.
+ */
+final class UndefinedArrayFilter extends ArrayFilter {
+    /** Bit vector tracking undefines. */
+    private final BitVector undefined;
+
+    UndefinedArrayFilter(final ArrayData underlying) {
+        super(underlying);
+
+        this.undefined = new BitVector(underlying.length());
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        final Object[] value = super.asObjectArray();
+
+        for (int i = 0; i < value.length; i++) {
+            if (undefined.isSet(i)) {
+                value[i] = UNDEFINED;
+            }
+        }
+
+        return value;
+    }
+
+    @Override
+    public Object asArrayOfType(final Class<?> componentType) {
+        final Object value = super.asArrayOfType(componentType);
+        final Object undefValue = convertUndefinedValue(componentType);
+        final int l = Array.getLength(value);
+        for (int i = 0; i < l; i++) {
+            if (undefined.isSet(i)) {
+                Array.set(value, i,undefValue);
+            }
+        }
+
+        return value;
+    }
+
+    @Override
+    public void shiftLeft(final int by) {
+        super.shiftLeft(by);
+        undefined.shiftLeft(by, length());
+    }
+
+    @Override
+    public ArrayData shiftRight(final int by) {
+        super.shiftRight(by);
+        undefined.shiftRight(by, length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData ensure(final long safeIndex) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) {
+            return new SparseArrayData(this, safeIndex + 1);
+        }
+
+        super.ensure(safeIndex);
+        undefined.resize(length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData shrink(final long newLength) {
+        super.shrink(newLength);
+        undefined.resize(length());
+
+        return this;
+    }
+
+    @Override
+    public ArrayData set(final int index, final Object value, final boolean strict) {
+        undefined.clear(index);
+
+        if (value == UNDEFINED) {
+            undefined.set(index);
+            return this;
+        }
+
+        return super.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final int value, final boolean strict) {
+        undefined.clear(index);
+
+        return super.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final long value, final boolean strict) {
+        undefined.clear(index);
+
+        return super.set(index, value, strict);
+    }
+
+    @Override
+    public ArrayData set(final int index, final double value, final boolean strict) {
+        undefined.clear(index);
+
+        return super.set(index, value, strict);
+    }
+
+    @Override
+    public int getInt(final int index) {
+        if (undefined.isSet(index)) {
+            return 0;
+        }
+
+        return super.getInt(index);
+    }
+
+    @Override
+    public long getLong(final int index) {
+        if (undefined.isSet(index)) {
+            return 0L;
+        }
+
+        return super.getLong(index);
+    }
+
+    @Override
+    public double getDouble(final int index) {
+        if (undefined.isSet(index)) {
+            return Double.NaN;
+        }
+
+        return super.getDouble(index);
+    }
+
+    @Override
+    public Object getObject(final int index) {
+        if (undefined.isSet(index)) {
+            return UNDEFINED;
+        }
+
+        return super.getObject(index);
+    }
+
+    @Override
+    public ArrayData delete(final int index) {
+        undefined.clear(index);
+
+        return super.delete(index);
+    }
+
+    @Override
+    public Object pop() {
+        final long index = length() - 1;
+
+        if (super.has((int)index)) {
+            final boolean isUndefined = undefined.isSet(index);
+            final Object value = super.pop();
+
+            return isUndefined ? UNDEFINED : value;
+        }
+
+        return super.pop();
+    }
+
+    @Override
+    public ArrayData slice(final long from, final long to) {
+        final ArrayData newArray = underlying.slice(from, to);
+        final UndefinedArrayFilter newFilter = new UndefinedArrayFilter(newArray);
+        newFilter.getUndefined().copy(undefined);
+        newFilter.getUndefined().shiftLeft(from, newFilter.length());
+
+        return newFilter;
+    }
+
+    private BitVector getUndefined() {
+        return undefined;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
new file mode 100644
index 0000000..3c5e2d8
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
@@ -0,0 +1,237 @@
+/*
+ * 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.codegen.CompilerConstants.staticCallNoLookup;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.DynamicLinker;
+import jdk.internal.dynalink.DynamicLinkerFactory;
+import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.codegen.RuntimeCallSite;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * This class houses bootstrap method for invokedynamic instructions generated by compiler.
+ */
+public final class Bootstrap {
+    /** Reference to the seed boostrap function */
+    public static final Call BOOTSTRAP = staticCallNoLookup(Bootstrap.class, "bootstrap", CallSite.class, Lookup.class, String.class, MethodType.class, int.class);
+
+    // do not create me!!
+    private Bootstrap() {
+    }
+
+    private static final DynamicLinker dynamicLinker;
+    static {
+        final DynamicLinkerFactory factory = new DynamicLinkerFactory();
+        factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(),
+                new JSObjectLinker());
+        factory.setFallbackLinkers(new BeansLinker(), new NashornBottomLinker());
+        factory.setSyncOnRelink(true);
+        final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1);
+        if (relinkThreshold > -1) {
+            factory.setUnstableRelinkThreshold(relinkThreshold);
+        }
+        dynamicLinker = factory.createLinker();
+    }
+
+    /**
+     * Create a call site and link it for Nashorn. This version of the method conforms to the invokedynamic bootstrap
+     * method expected signature and is referenced from Nashorn generated bytecode as the bootstrap method for all
+     * invokedynamic instructions.
+     * @param lookup MethodHandle lookup. Ignored as Nashorn only uses public lookup.
+     * @param opDesc Dynalink dynamic operation descriptor.
+     * @param type   Method type.
+     * @param flags  flags for call type, trace/profile etc.
+     * @return CallSite with MethodHandle to appropriate method or null if not found.
+     */
+    public static CallSite bootstrap(final Lookup lookup, final String opDesc, final MethodType type, final int flags) {
+        return dynamicLinker.link(LinkerCallSite.newLinkerCallSite(opDesc, type, flags));
+    }
+
+    /**
+     * Bootstrapper for a specialized Runtime call
+     *
+     * @param lookup       lookup
+     * @param initialName  initial name for callsite
+     * @param type         method type for call site
+     *
+     * @return callsite for a runtime node
+     */
+    public static CallSite runtimeBootstrap(final MethodHandles.Lookup lookup, final String initialName, final MethodType type) {
+        return new RuntimeCallSite(type, initialName);
+    }
+
+
+    /**
+     * Returns a dynamic invoker for a specified dynamic operation. You can use this method to create a method handle
+     * that when invoked acts completely as if it were a Nashorn-linked call site. An overview of available dynamic
+     * operations can be found in the <a href="https://github.com/szegedi/dynalink/wiki/User-Guide-0.4">Dynalink User Guide</a>,
+     * but we'll show few examples here:
+     * <ul>
+     *   <li>Get a named property with fixed name:
+     *     <pre>
+     * MethodHandle getColor = Boostrap.createDynamicInvoker("dyn:getProp:color", Object.class, Object.class);
+     * Object obj = ...; // somehow obtain the object
+     * Object color = getColor.invokeExact(obj);
+     *     </pre>
+     *   </li>
+     *   <li>Get a named property with variable name:
+     *     <pre>
+     * MethodHandle getProperty = Boostrap.createDynamicInvoker("dyn:getElem", Object.class, Object.class, String.class);
+     * Object obj = ...; // somehow obtain the object
+     * Object color = getProperty.invokeExact(obj, "color");
+     * Object shape = getProperty.invokeExact(obj, "shape");
+     * MethodHandle getNumProperty = Boostrap.createDynamicInvoker("dyn:getElem", Object.class, Object.class, int.class);
+     * Object elem42 = getNumProperty.invokeExact(obj, 42);
+     *     </pre>
+     *   </li>
+     *   <li>Set a named property with fixed name:
+     *     <pre>
+     * MethodHandle setColor = Boostrap.createDynamicInvoker("dyn:setProp:color", void.class, Object.class, Object.class);
+     * Object obj = ...; // somehow obtain the object
+     * setColor.invokeExact(obj, Color.BLUE);
+     *     </pre>
+     *   </li>
+     *   <li>Set a property with variable name:
+     *     <pre>
+     * MethodHandle setProperty = Boostrap.createDynamicInvoker("dyn:setElem", void.class, Object.class, String.class, Object.class);
+     * Object obj = ...; // somehow obtain the object
+     * setProperty.invokeExact(obj, "color", Color.BLUE);
+     * setProperty.invokeExact(obj, "shape", Shape.CIRCLE);
+     *     </pre>
+     *   </li>
+     *   <li>Call a function on an object; two-step variant. This is the actual variant used by Nashorn-generated code:
+     *     <pre>
+     * MethodHandle findFooFunction = Boostrap.createDynamicInvoker("dyn:getMethod:foo", Object.class, Object.class);
+     * Object obj = ...; // somehow obtain the object
+     * Object foo_fn = findFooFunction.invokeExact(obj);
+     * MethodHandle callFunctionWithTwoArgs = Boostrap.createDynamicInvoker("dyn:call", Object.class, Object.class, Object.class, Object.class, Object.class);
+     * // Note: "call" operation takes a function, then a "this" value, then the arguments:
+     * Object foo_retval = callFunctionWithTwoArgs.invokeExact(foo_fn, obj, arg1, arg2);
+     *     </pre>
+     *   </li>
+     *   <li>Call a function on an object; single-step variant. Although Nashorn doesn't use this variant and never
+     *   emits any INVOKEDYNAMIC instructions with {@code dyn:getMethod}, it still supports this standard Dynalink
+     *   operation:
+     *     <pre>
+     * MethodHandle callFunctionFooWithTwoArgs = Boostrap.createDynamicInvoker("dyn:callMethod:foo", Object.class, Object.class, Object.class, Object.class);
+     * Object obj = ...; // somehow obtain the object
+     * Object foo_retval = callFunctionFooWithTwoArgs.invokeExact(obj, arg1, arg2);
+     *     </pre>
+     *   </li>
+     * </ul>
+     * Few additional remarks:
+     * <ul>
+     * <li>Just as Nashorn works with any Java object, the invokers returned from this method can also be applied to
+     * arbitrary Java objects in addition to Nashorn JavaScript objects.</li>
+     * <li>For invoking a named function on an object, you can also use the {@link InvokeByName} convenience class.</li>
+     * <li>For Nashorn objects {@code getElem}, {@code getProp}, and {@code getMethod} are handled almost identically,
+     * since JavaScript doesn't distinguish between different kinds of properties on an object. Either can be used with
+     * fixed property name or a variable property name. The only significant difference is handling of missing
+     * properties: {@code getMethod} for a missing member will link to a potential invocation of
+     * {@code __noSuchMethod__} on the object, {@code getProp} for a missing member will link to a potential invocation
+     * of {@code __noSuchProperty__}, while {@code getElem} for a missing member will link to an empty getter.</li>
+     * <li>In similar vein, {@code setElem} and {@code setProp} are handled identically on Nashorn objects.</li>
+     * <li>There's no rule that the variable property identifier has to be a {@code String} for {@code getProp/setProp}
+     * and {@code int} for {@code getElem/setElem}. You can declare their type to be {@code int}, {@code double},
+     * {@code Object}, and so on regardless of the kind of the operation.</li>
+     * <li>You can be as specific in parameter types as you want. E.g. if you know that the receiver of the operation
+     * will always be {@code ScriptObject}, you can pass {@code ScriptObject.class} as its parameter type. If you happen
+     * to link to a method that expects different types, (you can use these invokers on POJOs too, after all, and end up
+     * linking with their methods that have strongly-typed signatures), all necessary conversions allowed by either Java
+     * or JavaScript will be applied: if invoked methods specify either primitive or wrapped Java numeric types, or
+     * {@code String} or {@code boolean/Boolean}, then the parameters might be subjected to standard ECMAScript
+     * {@code ToNumber}, {@code ToString}, and {@code ToBoolean} conversion, respectively. Less obviously, if the
+     * expected parameter type is a SAM type, and you pass a JavaScript function, a proxy object implementing the SAM
+     * type and delegating to the function will be passed. Linkage can often be optimized when linkers have more
+     * specific type information than "everything can be an object".</li>
+     * <li>You can also be as specific in return types as you want. For return types any necessary type conversion
+     * available in either Java or JavaScript will be automatically applied, similar to the process described for
+     * parameters, only in reverse direction:  if you specify any either primitive or wrapped Java numeric type, or
+     * {@code String} or {@code boolean/Boolean}, then the return values will be subjected to standard ECMAScript
+     * {@code ToNumber}, {@code ToString}, and {@code ToBoolean} conversion, respectively. Less obviously, if the return
+     * type is a SAM type, and the return value is a JavaScript function, a proxy object implementing the SAM type and
+     * delegating to the function will be returned.</li>
+     * </ul>
+     * @param opDesc Dynalink dynamic operation descriptor.
+     * @param rtype the return type for the operation
+     * @param ptypes the parameter types for the operation
+     * @return MethodHandle for invoking the operation.
+     */
+    public static MethodHandle createDynamicInvoker(final String opDesc, final Class<?> rtype, final Class<?>... ptypes) {
+        return createDynamicInvoker(opDesc, MethodType.methodType(rtype, ptypes));
+    }
+
+    /**
+     * Returns a dynamic invoker for a specified dynamic operation. Similar to
+     * {@link #createDynamicInvoker(String, Class, Class...)} but with return and parameter types composed into a
+     * method type in the signature. See the discussion of that method for details.
+     * @param opDesc Dynalink dynamic operation descriptor.
+     * @param type the method type for the operation
+     * @return MethodHandle for invoking the operation.
+     */
+    public static MethodHandle createDynamicInvoker(final String opDesc, final MethodType type) {
+        return bootstrap(null, opDesc, type, 0).dynamicInvoker();
+    }
+
+    /**
+     * Returns the Nashorn's internally used dynamic linker's services object. Note that in code that is processing a
+     * linking request, you will normally use the {@code LinkerServices} object passed by whatever top-level linker
+     * invoked the linking (if the call site is in Nashorn-generated code, you'll get this object anyway). You should
+     * only resort to retrieving a linker services object using this method when you need some linker services (e.g.
+     * type converter method handles) outside of a code path that is linking a call site.
+     * @return Nashorn's internal dynamic linker's services object.
+     */
+    public static LinkerServices getLinkerServices() {
+        return dynamicLinker.getLinkerServices();
+    }
+
+    /**
+     * Takes a guarded invocation, and ensures its method and guard conform to the type of the call descriptor, using
+     * all type conversions allowed by the linker's services. This method is used by Nashorn's linkers as a last step
+     * before returning guarded invocations to the callers. Most of the code used to produce the guarded invocations
+     * does not make an effort to coordinate types of the methods, and so a final type adjustment before a guarded
+     * invocation is returned is the responsibility of the linkers themselves.
+     * @param inv the guarded invocation that needs to be type-converted. Can be null.
+     * @param linkerServices the linker services object providing the type conversions.
+     * @param desc the call site descriptor to whose method type the invocation needs to conform.
+     * @return the type-converted guarded invocation. If input is null, null is returned. If the input invocation
+     * already conforms to the requested type, it is returned unchanged.
+     */
+    static GuardedInvocation asType(final GuardedInvocation inv, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
+        return inv == null ? null : inv.asType(linkerServices, desc.getMethodType());
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java
new file mode 100644
index 0000000..30e91ec
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java
@@ -0,0 +1,116 @@
+/*
+ * 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;
+
+/**
+ * A tuple of method handles, one for dynamically getting function as a property of an object, and another for invoking
+ * a function with a given signature. A typical use for this class is to create method handles that can be used to
+ * efficiently recreate dynamic invocation of a method on an object from Java code. E.g. if you would have a call site
+ * in JavaScript that says
+ * <pre>
+ *     value = obj.toJSON(key)
+ * </pre>
+ * then the efficient way to code an exact equivalent of this in Java would be:
+ * <pre>
+ *     private static final InvokeByName TO_JSON = new InvokeByName("toJSON", Object.class, Object.class, Object.class);
+ *     ...
+ *     final Object toJSONFn = TO_JSON.getGetter().invokeExact(obj);
+ *     value = TO_JSON.getInvoker().invokeExact(toJSON, obj, key);
+ * </pre>
+ * In practice, you can have stronger type assumptions if it makes sense for your code, just remember that you must use
+ * the same parameter types as the formal types of the arguments for {@code invokeExact} to work:
+ * <pre>
+ *     private static final InvokeByName TO_JSON = new InvokeByName("toJSON", ScriptObject.class, Object.class, Object.class);
+ *     ...
+ *     final ScriptObject sobj = (ScriptObject)obj;
+ *     final Object toJSONFn = TO_JSON.getGetter().invokeExact(sobj);
+ *     if(toJSONFn instanceof ScriptFunction) {
+ *         value = TO_JSON.getInvoker().invokeExact(toJSON, sobj, key);
+ *     }
+ * </pre>
+ * Note that in general you will not want to reuse a single instance of this class for implementing more than one call
+ * site - that would increase the risk of them becoming megamorphic or otherwise hard to optimize by the JVM. Even if
+ * you dynamically invoke a function with the same name from multiple places in your code, it is advisable to create a
+ * separate instance of this class for every place.
+ */
+public class InvokeByName {
+    private final MethodHandle getter;
+    private final MethodHandle invoker;
+
+    /**
+     * Creates a getter and invoker for a function of the given name that takes no arguments and has a return type of
+     * {@code Object}.
+     * @param name the name of the function
+     * @param targetClass the target class it is invoked on; e.g. {@code Object} or {@code ScriptObject}.
+     */
+    public InvokeByName(final String name, final Class<?> targetClass) {
+        this(name, targetClass, Object.class);
+    }
+
+    /**
+     * Creates a getter and invoker for a function of the given name with given parameter types and a given return type
+     * of {@code Object}.
+     * @param name the name of the function
+     * @param targetClass the target class it is invoked on; e.g. {@code Object} or {@code ScriptObject}.
+     * @param rtype the return type of the function
+     * @param ptypes the parameter types of the function.
+     */
+    public InvokeByName(final String name, final Class<?> targetClass, final Class<?> rtype, final Class<?>... ptypes) {
+        getter  = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getItem:" + name, Object.class, targetClass);
+
+        final Class<?>[] finalPtypes;
+        final int plength = ptypes.length;
+        if(plength == 0) {
+            finalPtypes = new Class<?>[] { Object.class, targetClass };
+        } else {
+            finalPtypes = new Class[plength + 2];
+            finalPtypes[0] = Object.class;
+            finalPtypes[1] = targetClass;
+            System.arraycopy(ptypes, 0, finalPtypes, 2, plength);
+        }
+        invoker = Bootstrap.createDynamicInvoker("dyn:call", rtype, finalPtypes);
+    }
+
+    /**
+     * Returns the property getter that can be invoked on an object to retrieve the function object that will be
+     * subsequently invoked by the invoker returned by {@link #getInvoker()}.
+     * @return the property getter method handle for the function.
+     */
+    public MethodHandle getGetter() {
+        return getter;
+    }
+
+    /**
+     * Returns the function invoker that can be used to invoke a function object previously retrieved by invoking
+     * the getter retrieved with {@link #getGetter()} on the target object.
+     * @return the invoker method handle for the function.
+     */
+    public MethodHandle getInvoker() {
+        return invoker;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
new file mode 100644
index 0000000..df9c47f
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
@@ -0,0 +1,234 @@
+/*
+ * 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 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;
+import java.util.Objects;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.nashorn.internal.runtime.JSType;
+import netscape.javascript.JSObject;
+
+/**
+ * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well
+ * as ScriptObjects from other Nashorn contexts.
+ */
+final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
+   /**
+     * Instances of this class are used to represent a method member of a JSObject
+     */
+    private static final class JSObjectMethod {
+        // The name of the JSObject method property
+        private final String name;
+
+        JSObjectMethod(final String name) {
+            this.name = name;
+        }
+
+        String getName() {
+            return name;
+        }
+
+        static GuardedInvocation lookup(final CallSiteDescriptor desc) {
+            final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
+            switch (operator) {
+                case "call": {
+                    // collect everything except the first two - JSObjectMethod instance and the actual 'self'
+                    final int paramCount = desc.getMethodType().parameterCount();
+                    final MethodHandle caller = MH.asCollector(JSOBJECTMETHOD_CALL, Object[].class, paramCount - 2);
+                    return new GuardedInvocation(caller, null, IS_JSOBJECTMETHOD_GUARD);
+                }
+                default:
+                    return null;
+            }
+        }
+    }
+
+    @Override
+    public boolean canLinkType(final Class<?> type) {
+        return canLinkTypeStatic(type);
+    }
+
+    static boolean canLinkTypeStatic(final Class<?> type) {
+        // can link JSObject and JSObjectMethod
+        return JSObject.class.isAssignableFrom(type) || JSObjectMethod.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception {
+        final LinkRequest requestWithoutContext = request.withoutRuntimeContext(); // Nashorn has no runtime context
+        final Object self = requestWithoutContext.getReceiver();
+        final CallSiteDescriptor desc = requestWithoutContext.getCallSiteDescriptor();
+
+        if (desc.getNameTokenCount() < 2 || !"dyn".equals(desc.getNameToken(CallSiteDescriptor.SCHEME))) {
+            // We only support standard "dyn:*[:*]" operations
+            return null;
+        }
+
+        final GuardedInvocation inv;
+        if (self instanceof JSObject) {
+            inv = lookup(desc);
+        } else if (self instanceof JSObjectMethod) {
+            inv = JSObjectMethod.lookup(desc);
+        } else {
+            throw new AssertionError(); // Should never reach here.
+        }
+
+        return Bootstrap.asType(inv, linkerServices, desc);
+    }
+
+    private static GuardedInvocation lookup(final CallSiteDescriptor desc) {
+        final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
+        final int c = desc.getNameTokenCount();
+        switch (operator) {
+            case "getProp":
+            case "getElem":
+            case "getMethod":
+                return c > 2 ? findGetMethod(desc, operator) : findGetIndexMethod();
+            case "setProp":
+            case "setElem":
+                return c > 2 ? findSetMethod(desc) : findSetIndexMethod();
+            case "call":
+            case "callMethod":
+                return findCallMethod(desc, operator);
+            case "new":
+            default:
+                return null;
+        }
+    }
+
+    private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final String operator) {
+        // if "getMethod" then return JSObjectMethod object - which just holds the name of the method
+        // subsequently, link on dyn:call for JSObjectMethod will actually call that method
+        final MethodHandle getter = MH.insertArguments("getMethod".equals(operator)? JSOBJECT_GETMETHOD : JSOBJECT_GET, 1, desc.getNameToken(2));
+        return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD);
+    }
+
+    private static GuardedInvocation findGetIndexMethod() {
+        return new GuardedInvocation(JSOBJECT_GET, null, IS_JSOBJECT_GUARD);
+    }
+
+    private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc) {
+        final MethodHandle getter = MH.insertArguments(JSOBJECT_PUT, 1, desc.getNameToken(2));
+        return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD);
+    }
+
+    private static GuardedInvocation findSetIndexMethod() {
+        return new GuardedInvocation(JSOBJECT_PUT, null, IS_JSOBJECT_GUARD);
+    }
+
+    private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) {
+        // if operator is "call", then 'self' is a JSObject function object already. Use 'call' as the method name
+        final String methodName = "callMethod".equals(operator)? desc.getNameToken(2) : "call";
+        MethodHandle func = MH.insertArguments(JSOBJECT_CALL, 1, methodName);
+        func = MH.asCollector(func, Object[].class, desc.getMethodType().parameterCount() - 1);
+        return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD);
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isJSObjectMethod(final Object self) {
+        return self instanceof JSObjectMethod;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isJSObject(final Object self) {
+        return self instanceof JSObject;
+    }
+
+
+    @SuppressWarnings("unused")
+    private static Object getMethod(final Object jsobj, final Object key) {
+        return new JSObjectMethod(Objects.toString(key));
+    }
+
+    @SuppressWarnings("unused")
+    private static Object get(final Object jsobj, final Object key) {
+        if (key instanceof String) {
+            return ((JSObject)jsobj).getMember((String)key);
+        } else if (key instanceof Number) {
+            final int index = getIndex((Number)key);
+            if (index > -1) {
+                return ((JSObject)jsobj).getSlot(index);
+            }
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    private static void put(final Object jsobj, final Object key, final Object value) {
+        if (key instanceof String) {
+            ((JSObject)jsobj).setMember((String)key, value);
+        } else if (key instanceof Number) {
+            ((JSObject)jsobj).setSlot(getIndex((Number)key), value);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static Object call(final Object jsobj, final Object method, final Object... args) {
+        return ((JSObject)jsobj).call(Objects.toString(method), args);
+    }
+
+    @SuppressWarnings("unused")
+    private static Object jsObjectMethodCall(final Object jsObjMethod, final Object jsobj, final Object... args) {
+        // we have JSObjectMethod, JSObject and args. Get method name from JSObjectMethod instance
+        final String methodName = ((JSObjectMethod)jsObjMethod).getName();
+        // call the method on JSObject
+        return ((JSObject)jsobj).call(methodName, args);
+    }
+
+    private static int getIndex(final Number n) {
+        final double value = n.doubleValue();
+        return JSType.isRepresentableAsInt(value) ? (int)value : -1;
+    }
+
+    private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
+
+    private static final MethodHandle IS_JSOBJECTMETHOD_GUARD = findOwnMH("isJSObjectMethod", boolean.class, Object.class);
+    private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class);
+    private static final MethodHandle JSOBJECT_GETMETHOD = findOwnMH("getMethod", Object.class, Object.class, Object.class);
+    private static final MethodHandle JSOBJECT_GET = findOwnMH("get", Object.class, Object.class, Object.class);
+    private static final MethodHandle JSOBJECT_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class);
+    private static final MethodHandle JSOBJECT_CALL = findOwnMH("call", Object.class, Object.class, Object.class, Object[].class);
+    private static final MethodHandle JSOBJECTMETHOD_CALL = findOwnMH("jsObjectMethodCall", Object.class, Object.class, Object.class, Object[].class);
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        final Class<?>   own = JSObjectLinker.class;
+        final MethodType mt  = MH.type(rtype, types);
+        try {
+            return MH.findStatic(MethodHandles.lookup(), own, name, mt);
+        } catch (final MethodHandleFactory.LookupException e) {
+            return MH.findVirtual(MethodHandles.lookup(), own, name, mt);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
new file mode 100644
index 0000000..a9e4bd0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
@@ -0,0 +1,1335 @@
+/*
+ * 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.internal.org.objectweb.asm.Opcodes.ACC_FINAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_VARARGS;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACONST_NULL;
+import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFNONNULL;
+import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.AllPermission;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.security.SecureClassLoader;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import jdk.internal.dynalink.beans.StaticClass;
+import jdk.internal.dynalink.support.LinkRequestImpl;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.Type;
+import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
+import jdk.nashorn.internal.objects.NativeJava;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ECMAException;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Undefined;
+
+/**
+ * <p>A factory class that generates adapter classes. Adapter classes allow implementation of Java interfaces and
+ * extending of Java classes from JavaScript. For every combination of a superclass to extend and interfaces to
+ * implement (collectively: "original types"), exactly one adapter class is generated that extends the specified
+ * superclass and implements the specified interfaces.
+ * </p><p>
+ * The adapter class is generated in a new secure class loader that inherits Nashorn's protection domain, and has either
+ * one of the original types' class loader or the Nashorn's class loader as its parent - the parent class loader
+ * is chosen so that all the original types and the Nashorn core classes are visible from it (as the adapter will have
+ * constant pool references to ScriptObject and ScriptFunction classes). In case none of the candidate class loaders has
+ * visibility of all the required types, an error is thrown.
+ * </p><p>
+ * For every protected or public constructor in the extended class, the adapter class will have one or two public
+ * constructors (visibility of protected constructors in the extended class is promoted to public). In every case, for
+ * every original constructor, a new constructor taking a trailing ScriptObject argument preceded by original
+ * constructor arguments is present on the adapter class. When such a constructor is invoked, the passed ScriptObject's
+ * member functions are used to implement and/or override methods on the original class, dispatched by name. A single
+ * JavaScript function will act as the implementation for all overloaded methods of the same name. When methods on an
+ * adapter instance are invoked, the functions are invoked having the ScriptObject passed in the instance constructor as
+ * their "this". Subsequent changes to the ScriptObject (reassignment or removal of its functions) are not reflected in
+ * the adapter instance; the method implementations are bound to functions at constructor invocation time.
+ * {@code java.lang.Object} methods {@code equals}, {@code hashCode}, and {@code toString} can also be overridden. The
+ * only restriction is that since every JavaScript object already has a {@code toString} function through the
+ * {@code Object.prototype}, the {@code toString} in the adapter is only overridden if the passed ScriptObject has a
+ * {@code toString} function as its own property, and not inherited from a prototype. All other adapter methods can be
+ * implemented or overridden through a prototype-inherited function of the ScriptObject passed to the constructor too.
+ * </p><p>
+ * If the original types collectively have only one abstract method, or have several of them, but all share the
+ * same name, an additional constructor is provided for every original constructor; this one takes a ScriptFunction as
+ * its last argument preceded by original constructor arguments. This constructor will use the passed function as the
+ * implementation for all abstract methods. For consistency, any concrete methods sharing the single abstract method
+ * name will also be overridden by the function. When methods on the adapter instance are invoked, the ScriptFunction is
+ * invoked with {@code null} as its "this".
+ * </p><p>
+ * For adapter methods that return values, all the JavaScript-to-Java conversions supported by Nashorn will be in effect
+ * to coerce the JavaScript function return value to the expected Java return type.
+ * </p><p>
+ * Since we are adding a trailing argument to the generated constructors in the adapter class, they will never be
+ * declared as variable arity, even if the original constructor in the superclass was declared as variable arity. The
+ * reason we are passing the additional argument at the end of the argument list instead at the front is that the
+ * source-level script expression <code>new X(a, b) { ... }</code> (which is a proprietary syntax extension Nashorn uses
+ * to resemble Java anonymous classes) is actually equivalent to <code>new X(a, b, { ... })</code>.
+ * </p><p>
+ * You normally don't use this class directly, but rather either create adapters from script using
+ * {@link NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
+ * {@link NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
+ * types.
+ * </p>
+ */
+
+public final class JavaAdapterFactory {
+    private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class);
+    private static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class);
+    private static final Type OBJECT_TYPE = Type.getType(Object.class);
+    private static final Type STRING_TYPE = Type.getType(String.class);
+    private static final Type CONTEXT_TYPE = Type.getType(Context.class);
+    private static final Type METHOD_TYPE_TYPE = Type.getType(MethodType.class);
+    private static final Type METHOD_HANDLE_TYPE = Type.getType(MethodHandle.class);
+    private static final String GET_HANDLE_OBJECT_DESCRIPTOR = Type.getMethodDescriptor(METHOD_HANDLE_TYPE,
+            OBJECT_TYPE, STRING_TYPE, METHOD_TYPE_TYPE, Type.BOOLEAN_TYPE);
+    private static final String GET_HANDLE_FUNCTION_DESCRIPTOR = Type.getMethodDescriptor(METHOD_HANDLE_TYPE,
+            SCRIPT_FUNCTION_TYPE, METHOD_TYPE_TYPE, Type.BOOLEAN_TYPE);
+    private static final Type RUNTIME_EXCEPTION_TYPE = Type.getType(RuntimeException.class);
+    private static final Type THROWABLE_TYPE = Type.getType(Throwable.class);
+    private static final Type PRIVILEGED_ACTION_TYPE = Type.getType(PrivilegedAction.class);
+    private static final Type UNSUPPORTED_OPERATION_TYPE = Type.getType(UnsupportedOperationException.class);
+
+    private static final String THIS_CLASS_TYPE_NAME = Type.getInternalName(JavaAdapterFactory.class);
+    private static final String RUNTIME_EXCEPTION_TYPE_NAME = RUNTIME_EXCEPTION_TYPE.getInternalName();
+    private static final String ERROR_TYPE_NAME = Type.getInternalName(Error.class);
+    private static final String THROWABLE_TYPE_NAME = THROWABLE_TYPE.getInternalName();
+    private static final String CONTEXT_TYPE_NAME = CONTEXT_TYPE.getInternalName();
+    private static final String OBJECT_TYPE_NAME = OBJECT_TYPE.getInternalName();
+    private static final String PRIVILEGED_ACTION_TYPE_NAME = PRIVILEGED_ACTION_TYPE.getInternalName();
+    private static final String UNSUPPORTED_OPERATION_TYPE_NAME = UNSUPPORTED_OPERATION_TYPE.getInternalName();
+
+    private static final String METHOD_HANDLE_TYPE_DESCRIPTOR = METHOD_HANDLE_TYPE.getDescriptor();
+    private static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor();
+    private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(SCRIPT_OBJECT_TYPE);
+    private static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, SCRIPT_OBJECT_TYPE);
+    private static final String GET_CLASS_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType(Class.class));
+    private static final String PRIVILEGED_RUN_METHOD_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE);
+
+    // Package used when the adapter can't be defined in the adaptee's package (either because it's sealed, or because
+    // it's a java.* package.
+    private static final String ADAPTER_PACKAGE_PREFIX = "jdk/nashorn/internal/javaadapters/";
+    // Class name suffix used to append to the adaptee class name, when it can be defined in the adaptee's package.
+    private static final String ADAPTER_CLASS_NAME_SUFFIX = "$$NashornJavaAdapter";
+    private static final String JAVA_PACKAGE_PREFIX = "java/";
+    private static final int MAX_GENERATED_TYPE_NAME_LENGTH = 238; //255 - 17; 17 is the maximum possible length for the global setter inner class suffix
+
+    private static final String INIT = "<init>";
+    private static final String VOID_NOARG = Type.getMethodDescriptor(Type.VOID_TYPE);
+    private static final String GLOBAL_FIELD_NAME = "global";
+
+    /**
+     * Contains various outcomes for attempting to generate an adapter class. These are stored in AdapterInfo instances.
+     * We have a successful outcome (adapter class was generated) and four possible error outcomes: superclass is final,
+     * superclass is not public, superclass has no public or protected constructor, more than one superclass was
+     * specified. We don't throw exceptions when we try to generate the adapter, but rather just record these error
+     * conditions as they are still useful as partial outcomes, as Nashorn's linker can still successfully check whether
+     * the class can be autoconverted from a script function even when it is not possible to generate an adapter for it.
+     */
+    private enum AdaptationOutcome {
+        SUCCESS,
+        ERROR_FINAL_CLASS,
+        ERROR_NON_PUBLIC_CLASS,
+        ERROR_NO_ACCESSIBLE_CONSTRUCTOR,
+        ERROR_MULTIPLE_SUPERCLASSES,
+        ERROR_NO_COMMON_LOADER
+    }
+
+    /**
+     * Collection of methods we never override: Object.clone(), Object.finalize().
+     */
+    private static final Collection<MethodInfo> EXCLUDED = getExcludedMethods();
+
+    /**
+     * A mapping from an original Class object to AdapterInfo representing the adapter for the class it represents.
+     */
+    private static final ClassValue<Map<List<Class<?>>, AdapterInfo>> ADAPTER_INFO_MAPS = new ClassValue<Map<List<Class<?>>, AdapterInfo>>() {
+        @Override
+        protected Map<List<Class<?>>, AdapterInfo> computeValue(final Class<?> type) {
+            return new HashMap<>();
+        }
+    };
+
+    private static final Random random = new SecureRandom();
+    private static final ProtectionDomain GENERATED_PROTECTION_DOMAIN = createGeneratedProtectionDomain();
+
+    // This is the superclass for our generated adapter.
+    private final Class<?> superClass;
+    // Class loader used as the parent for the class loader we'll create to load the generated class. It will be a class
+    // loader that has the visibility of all original types (class to extend and interfaces to implement) and of the
+    // Nashorn classes.
+    private final ClassLoader commonLoader;
+
+    // Binary name of the superClass
+    private final String superClassName;
+    // Binary name of the generated class.
+    private final String generatedClassName;
+    // Binary name of the PrivilegedAction inner class that is used to
+    private final String globalSetterClassName;
+    private final Set<String> usedFieldNames = new HashSet<>();
+    private final Set<String> abstractMethodNames = new HashSet<>();
+    private final String samName;
+    private final Set<MethodInfo> finalMethods = new HashSet<>(EXCLUDED);
+    private final Set<MethodInfo> methodInfos = new HashSet<>();
+    private boolean autoConvertibleFromFunction = false;
+
+    private final ClassWriter cw;
+
+    /**
+     * Creates a factory that will produce the adapter type for the specified original type.
+     * @param originalType the type for which this factory will generate the adapter type.
+     * @param definingClassAndLoader the class in whose ClassValue we'll store the generated adapter, and its class loader.
+     * @throws AdaptationException if the adapter can not be generated for some reason.
+     */
+    private JavaAdapterFactory(final Class<?> superType, final List<Class<?>> interfaces, final ClassAndLoader definingClassAndLoader) throws AdaptationException {
+        assert superType != null && !superType.isInterface();
+        assert interfaces != null;
+        assert definingClassAndLoader != null;
+
+        this.superClass = superType;
+        this.commonLoader = findCommonLoader(definingClassAndLoader);
+        cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
+            @Override
+            protected String getCommonSuperClass(final String type1, final String type2) {
+                // We need to override ClassWriter.getCommonSuperClass to use this factory's commonLoader as a class
+                // loader to find the common superclass of two types when needed.
+                return JavaAdapterFactory.this.getCommonSuperClass(type1, type2);
+            }
+        };
+        superClassName = Type.getInternalName(superType);
+        generatedClassName = getGeneratedClassName(superType, interfaces);
+
+        // Randomize the name of the privileged global setter, to make it non-feasible to find.
+        final long l;
+        synchronized(random) {
+            l = random.nextLong();
+        }
+        // NOTE: they way this class name is calculated affects the value of MAX_GENERATED_TYPE_NAME_LENGTH constant. If
+        // you change the calculation of globalSetterClassName, adjust the constant too.
+        globalSetterClassName = generatedClassName.concat("$" + Long.toHexString(l & Long.MAX_VALUE));
+        cw.visit(Opcodes.V1_7, ACC_PUBLIC | ACC_SUPER | ACC_FINAL, generatedClassName, null, superClassName, getInternalTypeNames(interfaces));
+        cw.visitField(ACC_PRIVATE | ACC_FINAL, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, null).visitEnd();
+        usedFieldNames.add(GLOBAL_FIELD_NAME);
+
+        gatherMethods(superType);
+        gatherMethods(interfaces);
+        samName = abstractMethodNames.size() == 1 ? abstractMethodNames.iterator().next() : null;
+        generateFields();
+        generateConstructors();
+        generateMethods();
+        // }
+        cw.visitEnd();
+    }
+
+    private static String getGeneratedClassName(final Class<?> superType, final List<Class<?>> interfaces) {
+        // The class we use to primarily name our adapter is either the superclass, or if it is Object (meaning we're
+        // just implementing interfaces or extending Object), then the first implemented interface or Object.
+        final Class<?> namingType = superType == Object.class ? (interfaces.isEmpty()? Object.class : interfaces.get(0)) : superType;
+        final Package pkg = namingType.getPackage();
+        final String namingTypeName = Type.getInternalName(namingType);
+        final StringBuilder buf = new StringBuilder();
+        if (namingTypeName.startsWith(JAVA_PACKAGE_PREFIX) || pkg == null || pkg.isSealed()) {
+            // Can't define new classes in java.* packages
+            buf.append(ADAPTER_PACKAGE_PREFIX).append(namingTypeName);
+        } else {
+            buf.append(namingTypeName).append(ADAPTER_CLASS_NAME_SUFFIX);
+        }
+        final Iterator<Class<?>> it = interfaces.iterator();
+        if(superType == Object.class && it.hasNext()) {
+            it.next(); // Skip first interface, it was used to primarily name the adapter
+        }
+        // Append interface names to the adapter name
+        while(it.hasNext()) {
+            buf.append("$$").append(it.next().getSimpleName());
+        }
+        return buf.toString().substring(0, Math.min(MAX_GENERATED_TYPE_NAME_LENGTH, buf.length()));
+    }
+
+    /**
+     * Given a list of class objects, return an array with their binary names. Used to generate the array of interface
+     * names to implement.
+     * @param classes the classes
+     * @return an array of names
+     */
+    private static String[] getInternalTypeNames(final List<Class<?>> classes) {
+        final int interfaceCount = classes.size();
+        final String[] interfaceNames = new String[interfaceCount];
+        for(int i = 0; i < interfaceCount; ++i) {
+            interfaceNames[i] = Type.getInternalName(classes.get(i));
+        }
+        return interfaceNames;
+    }
+
+    /**
+     * Utility method used by few other places in the code. Tests if the class has the abstract modifier and is not an
+     * array class. For some reason, array classes have the abstract modifier set in HotSpot JVM, and we don't want to
+     * treat array classes as abstract.
+     * @param clazz the inspected class
+     * @return true if the class is abstract and is not an array type.
+     */
+    static boolean isAbstractClass(final Class<?> clazz) {
+        return Modifier.isAbstract(clazz.getModifiers()) && !clazz.isArray();
+    }
+
+    /**
+     * Returns an adapter class for the specified original types. The adapter class extends/implements the original
+     * class/interfaces.
+     * @param types the original types. The caller must pass at least one Java type representing either a public
+     * interface or a non-final public class with at least one public or protected constructor. If more than one type is
+     * specified, at most one can be a class and the rest have to be interfaces. The class can be in any position in the
+     * array. Invoking the method twice with exactly the same types in the same order will return the same adapter
+     * class, any reordering of types or even addition or removal of redundant types (i.e. interfaces that other types
+     * in the list already implement/extend, or {@code java.lang.Object} in a list of types consisting purely of
+     * interfaces) will result in a different adapter class, even though those adapter classes are functionally
+     * identical; we deliberately don't want to incur the additional processing cost of canonicalizing type lists.
+     * @return an adapter class. See this class' documentation for details on the generated adapter class.
+     * @throws ECMAException with a TypeError if the adapter class can not be generated because the original class is
+     * final, non-public, or has no public or protected constructors.
+     */
+    public static StaticClass getAdapterClassFor(final Class<?>[] types) {
+        assert types != null && types.length > 0;
+        final AdapterInfo adapterInfo = getAdapterInfo(types);
+
+        final StaticClass clazz = adapterInfo.adapterClass;
+        if (clazz != null) {
+            return clazz;
+        }
+        adapterInfo.adaptationOutcome.typeError();
+
+        throw new AssertionError();
+    }
+
+    private static AdapterInfo getAdapterInfo(final Class<?>[] types) {
+        final ClassAndLoader definingClassAndLoader = getDefiningClassAndLoader(types);
+
+        final Map<List<Class<?>>, AdapterInfo> adapterInfoMap = ADAPTER_INFO_MAPS.get(definingClassAndLoader.clazz);
+        final List<Class<?>> typeList = types.length == 1 ? getSingletonClassList(types[0]) : Arrays.asList(types.clone());
+        AdapterInfo adapterInfo;
+        synchronized(adapterInfoMap) {
+            adapterInfo = adapterInfoMap.get(typeList);
+            if(adapterInfo == null) {
+                adapterInfo = createAdapterInfo(types, definingClassAndLoader);
+                adapterInfoMap.put(typeList, adapterInfo);
+            }
+        }
+        return adapterInfo;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private static List<Class<?>> getSingletonClassList(final Class<?> clazz) {
+        return (List)Collections.singletonList(clazz);
+    }
+
+    /**
+     * Returns whether an instance of the specified class/interface can be generated from a ScriptFunction. Returns true
+     * iff: the adapter for the class/interface can be created, it is abstract (this includes interfaces), it has at
+     * least one abstract method, all the abstract methods share the same name, and it has a public or protected default
+     * constructor. Note that invoking this class will most likely result in the adapter class being defined in the JVM
+     * if it hasn't been already.
+     * @param clazz the inspected class
+     * @return true iff an instance of the specified class/interface can be generated from a ScriptFunction.
+     */
+    static boolean isAutoConvertibleFromFunction(final Class<?> clazz) {
+        return getAdapterInfo(new Class<?>[] { clazz }).autoConvertibleFromFunction;
+    }
+
+    /**
+     * Returns a method handle representing a constructor that takes a single argument of the source type (which,
+     * really, should be one of {@link ScriptObject}, {@link ScriptFunction}, or {@link Object}, and returns an instance
+     * of the adapter for the target type. Used to implement the function autoconverters as well as the Nashorn's
+     * JSR-223 script engine's {@code getInterface()} method.
+     * @param sourceType the source type; should be either {@link ScriptObject}, {@link ScriptFunction}, or
+     * {@link Object}. In case of {@code Object}, it will return a method handle that dispatches to either the script
+     * object or function constructor at invocation based on the actual argument.
+     * @param targetType the target type, for which adapter instances will be created
+     * @return the constructor method handle.
+     * @throws Exception if anything goes wrong
+     */
+    public static MethodHandle getConstructor(final Class<?> sourceType, final Class<?> targetType) throws Exception {
+        final StaticClass adapterClass = getAdapterClassFor(new Class<?>[] { targetType });
+        return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(NashornCallSiteDescriptor.get(
+                "dyn:new", MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
+                adapterClass, null)).getInvocation(), adapterClass);
+    }
+
+    /**
+     * Finishes the bytecode generation for the adapter class that was started in the constructor, and loads the
+     * bytecode as a new class into the JVM.
+     * @return the generated adapter class
+     */
+    private Class<?> generateClass() {
+        final String binaryName = generatedClassName.replace('/', '.');
+        try {
+            return Class.forName(binaryName, true, createClassLoader(commonLoader, binaryName, cw.toByteArray(),
+                    globalSetterClassName.replace('/', '.')));
+        } catch (final ClassNotFoundException e) {
+            throw new AssertionError(e); // cannot happen
+        }
+    }
+
+    /**
+     * Tells if the given Class is an adapter or support class
+     * @param clazz Class object
+     * @return true if the Class given is adapter or support class
+     */
+    public static boolean isAdapterClass(Class<?> clazz) {
+        return clazz.getClassLoader() instanceof AdapterLoader;
+    }
+
+    private static class AdapterLoader extends SecureClassLoader {
+        AdapterLoader(ClassLoader parent) {
+            super(parent);
+        }
+    }
+
+    // Creation of class loader is in a separate static method so that it doesn't retain a reference to the factory
+    // instance. Note that the adapter class is created in the protection domain of the class/interface being
+    // extended/implemented, and only the privileged global setter action class is generated in the protection domain
+    // of Nashorn itself. Also note that the creation and loading of the global setter is deferred until it is
+    // required by JVM linker, which will only happen on first invocation of any of the adapted method. We could defer
+    // it even more by separating its invocation into a separate static method on the adapter class, but then someone
+    // with ability to introspect on the class and use setAccessible(true) on it could invoke the method. It's a
+    // security tradeoff...
+    private static ClassLoader createClassLoader(final ClassLoader parentLoader, final String className,
+            final byte[] classBytes, final String privilegedActionClassName) {
+        return new AdapterLoader(parentLoader) {
+            private final ProtectionDomain myProtectionDomain = getClass().getProtectionDomain();
+
+            @Override
+            protected Class<?> findClass(final String name) throws ClassNotFoundException {
+                if(name.equals(className)) {
+                    final byte[] bytes = classBytes;
+                    return defineClass(name, bytes, 0, bytes.length, GENERATED_PROTECTION_DOMAIN);
+                } else if(name.equals(privilegedActionClassName)) {
+                    final byte[] bytes = generatePrivilegedActionClassBytes(privilegedActionClassName.replace('.', '/'));
+                    return defineClass(name, bytes, 0, bytes.length, myProtectionDomain);
+                } else {
+                    throw new ClassNotFoundException(name);
+                }
+            }
+        };
+    }
+
+    /**
+     * Generates a PrivilegedAction implementation class for invoking {@link Context#setGlobal(ScriptObject)} from the
+     * adapter class.
+     */
+    private static byte[] generatePrivilegedActionClassBytes(final String className) {
+        final ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
+        // class GlobalSetter implements PrivilegedAction {
+        w.visit(Opcodes.V1_7, ACC_SUPER | ACC_FINAL, className, null, OBJECT_TYPE_NAME, new String[] {
+                PRIVILEGED_ACTION_TYPE_NAME
+        });
+
+        // private final ScriptObject global;
+        w.visitField(ACC_PRIVATE | ACC_FINAL, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, null).visitEnd();
+
+        // private GlobalSetter(ScriptObject global) {
+        InstructionAdapter mv = new InstructionAdapter(w.visitMethod(ACC_PRIVATE, INIT,
+                SET_GLOBAL_METHOD_DESCRIPTOR, null, new String[0]));
+        mv.visitCode();
+        // super();
+        mv.visitVarInsn(ALOAD, 0);
+        mv.invokespecial(OBJECT_TYPE_NAME, INIT, VOID_NOARG);
+        // this.global = global;
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.putfield(className, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+
+        mv.visitInsn(RETURN);
+        mv.visitEnd();
+        mv.visitMaxs(0, 0);
+
+        // public Object run() {
+        mv = new InstructionAdapter(w.visitMethod(ACC_PUBLIC, "run", PRIVILEGED_RUN_METHOD_DESCRIPTOR, null,
+                new String[0]));
+        mv.visitCode();
+        // Context.setGlobal(this.global);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.getfield(className, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+        mv.invokestatic(CONTEXT_TYPE_NAME, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR);
+        // return null;
+        mv.visitInsn(ACONST_NULL);
+        mv.visitInsn(ARETURN);
+
+        mv.visitEnd();
+        mv.visitMaxs(0, 0);
+
+        // static void setGlobal(ScriptObject global) {
+        mv = new InstructionAdapter(w.visitMethod(ACC_STATIC, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR, null,
+                new String[0]));
+        mv.visitCode();
+        // new GlobalSetter(ScriptObject global)
+        mv.anew(Type.getType("L" + className + ";"));
+        mv.dup();
+        mv.visitVarInsn(ALOAD, 0);
+        mv.invokespecial(className, INIT, SET_GLOBAL_METHOD_DESCRIPTOR);
+        // AccessController.doPrivileged(...)
+        mv.invokestatic(Type.getInternalName(AccessController.class), "doPrivileged", Type.getMethodDescriptor(
+                OBJECT_TYPE, PRIVILEGED_ACTION_TYPE));
+        mv.pop();
+        mv.visitInsn(RETURN);
+
+        mv.visitEnd();
+        mv.visitMaxs(0, 0);
+
+        return w.toByteArray();
+    }
+
+    private void generateFields() {
+        for (final MethodInfo mi: methodInfos) {
+            cw.visitField(ACC_PRIVATE | ACC_FINAL, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR, null, null).visitEnd();
+        }
+    }
+
+    private void generateConstructors() throws AdaptationException {
+        boolean gotCtor = false;
+        for (final Constructor<?> ctor: superClass.getDeclaredConstructors()) {
+            final int modifier = ctor.getModifiers();
+            if((modifier & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) {
+                generateConstructor(ctor);
+                gotCtor = true;
+            }
+        }
+        if(!gotCtor) {
+            throw new AdaptationException(AdaptationOutcome.ERROR_NO_ACCESSIBLE_CONSTRUCTOR, superClass.getCanonicalName());
+        }
+    }
+
+    boolean isAutoConvertibleFromFunction() {
+        return autoConvertibleFromFunction;
+    }
+
+    private void generateConstructor(final Constructor<?> ctor) {
+        // Generate a constructor that delegates to ctor, but takes an additional ScriptObject parameter at the
+        // beginning of its parameter list.
+        generateConstructor(ctor, false);
+
+        if (samName != null) {
+            if (!autoConvertibleFromFunction && ctor.getParameterTypes().length == 0) {
+                // If the original type only has a single abstract method name, as well as a default ctor, then it can
+                // be automatically converted from JS function.
+                autoConvertibleFromFunction = true;
+            }
+            // If all our abstract methods have a single name, generate an additional constructor, one that takes a
+            // ScriptFunction as its first parameter and assigns it as the implementation for all abstract methods.
+            generateConstructor(ctor, true);
+        }
+    }
+
+    /**
+     * Generates a constructor for the adapter class. This constructor will take the same arguments as the supertype
+     * constructor passed as the argument here, and delegate to it. However, it will take an additional argument of
+     * either ScriptObject or ScriptFunction type (based on the value of the "fromFunction" parameter), and initialize
+     * all the method handle fields of the adapter instance with functions from the script object (or the script
+     * function itself, if that's what's passed). There is one method handle field in the adapter class for every method
+     * that can be implemented or overridden; the name of every field is same as the name of the method, with a number
+     * suffix that makes it unique in case of overloaded methods. The generated constructor will invoke
+     * {@link #getHandle(ScriptFunction, MethodType, boolean)} or {@link #getHandle(Object, String, MethodType,
+     * boolean)} to obtain the method handles; these methods make sure to add the necessary conversions and arity
+     * adjustments so that the resulting method handles can be invoked from generated methods using {@code invokeExact}.
+     * The constructor that takes a script function will only initialize the methods with the same name as the single
+     * abstract method. The constructor will also store the Nashorn global that was current at the constructor
+     * invocation time in a field named "global". The generated constructor will be public, regardless of whether the
+     * supertype constructor was public or protected. The generated constructor will not be variable arity, even if the
+     * supertype constructor was.
+     * @param ctor the supertype constructor that is serving as the base for the generated constructor.
+     * @param fromFunction true if we're generating a constructor that initializes SAM types from a single
+     * ScriptFunction passed to it, false if we're generating a constructor that initializes an arbitrary type from a
+     * ScriptObject passed to it.
+     */
+    private void generateConstructor(final Constructor<?> ctor, final boolean fromFunction) {
+        final Type originalCtorType = Type.getType(ctor);
+        final Type[] originalArgTypes = originalCtorType.getArgumentTypes();
+        final int argLen = originalArgTypes.length;
+        final Type[] newArgTypes = new Type[argLen + 1];
+
+        // Insert ScriptFunction|Object as the last argument to the constructor
+        final Type extraArgumentType = fromFunction ? SCRIPT_FUNCTION_TYPE : OBJECT_TYPE;
+        newArgTypes[argLen] = extraArgumentType;
+        System.arraycopy(originalArgTypes, 0, newArgTypes, 0, argLen);
+
+        // All constructors must be public, even if in the superclass they were protected.
+        // Existing super constructor <init>(this, args...) triggers generating <init>(this, scriptObj, args...).
+        final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT,
+                Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null));
+
+        mv.visitCode();
+        // First, invoke super constructor with original arguments. If the form of the constructor we're generating is
+        // <init>(this, args..., scriptFn), then we're invoking super.<init>(this, args...).
+        mv.visitVarInsn(ALOAD, 0);
+        final Class<?>[] argTypes = ctor.getParameterTypes();
+        int offset = 1; // First arg is at position 1, after this.
+        for (int i = 0; i < argLen; ++i) {
+            final Type argType = Type.getType(argTypes[i]);
+            mv.load(offset, argType);
+            offset += argType.getSize();
+        }
+        mv.invokespecial(superClassName, INIT, originalCtorType.getDescriptor());
+
+        // Get a descriptor to the appropriate "JavaAdapterFactory.getHandle" method.
+        final String getHandleDescriptor = fromFunction ? GET_HANDLE_FUNCTION_DESCRIPTOR : GET_HANDLE_OBJECT_DESCRIPTOR;
+
+        // Assign MethodHandle fields through invoking getHandle()
+        for (final MethodInfo mi : methodInfos) {
+            mv.visitVarInsn(ALOAD, 0);
+            if (fromFunction && !mi.getName().equals(samName)) {
+                // Constructors initializing from a ScriptFunction only initialize methods with the SAM name.
+                // NOTE: if there's a concrete overloaded method sharing the SAM name, it'll be overriden too. This
+                // is a deliberate design choice. All other method handles are initialized to null.
+                mv.visitInsn(ACONST_NULL);
+            } else {
+                mv.visitVarInsn(ALOAD, offset);
+                if(!fromFunction) {
+                    mv.aconst(mi.getName());
+                }
+                mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
+                mv.iconst(mi.method.isVarArgs() ? 1 : 0);
+                mv.invokestatic(THIS_CLASS_TYPE_NAME, "getHandle", getHandleDescriptor);
+            }
+            mv.putfield(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
+        }
+
+        // Assign "this.global = Context.getGlobal()"
+        mv.visitVarInsn(ALOAD, 0);
+        invokeGetGlobal(mv);
+        mv.dup();
+        mv.invokevirtual(OBJECT_TYPE_NAME, "getClass", GET_CLASS_METHOD_DESCRIPTOR); // check against null Context
+        mv.pop();
+        mv.putfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+
+        // Wrap up
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private static void invokeGetGlobal(final InstructionAdapter mv) {
+        mv.invokestatic(CONTEXT_TYPE_NAME, "getGlobal", GET_GLOBAL_METHOD_DESCRIPTOR);
+    }
+
+    private void invokeSetGlobal(final InstructionAdapter mv) {
+        mv.invokestatic(globalSetterClassName, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR);
+    }
+
+    /**
+     * Given a JS script function, binds it to null JS "this", and adapts its parameter types, return types, and arity
+     * to the specified type and arity. This method is public mainly for implementation reasons, so the adapter classes
+     * can invoke it from their constructors that take a ScriptFunction in its first argument to obtain the method
+     * handles for their abstract method implementations.
+     * @param fn the script function
+     * @param type the method type it has to conform to
+     * @param varArg if the Java method for which the function is being adapted is a variable arity method
+     * @return the appropriately adapted method handle for invoking the script function.
+     */
+    public static MethodHandle getHandle(final ScriptFunction fn, final MethodType type, final boolean varArg) {
+        // JS "this" will be null for SAMs
+        return adaptHandle(fn.getBoundInvokeHandle(null), type, varArg);
+    }
+
+    /**
+     * Given a JS script object, retrieves a function from it by name, binds it to the script object as its "this", and
+     * adapts its parameter types, return types, and arity to the specified type and arity. This method is public mainly
+     * for implementation reasons, so the adapter classes can invoke it from their constructors that take a Object
+     * in its first argument to obtain the method handles for their method implementations.
+     * @param obj the script obj
+     * @param name the name of the property that contains the function
+     * @param type the method type it has to conform to
+     * @param varArg if the Java method for which the function is being adapted is a variable arity method
+     * @return the appropriately adapted method handle for invoking the script function, or null if the value of the
+     * property is either null or undefined, or "toString" was requested as the name, but the object doesn't directly
+     * define it but just inherits it through prototype.
+     */
+    public static MethodHandle getHandle(final Object obj, final String name, final MethodType type, final boolean varArg) {
+        if (! (obj instanceof ScriptObject)) {
+            throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
+        }
+
+        final ScriptObject sobj = (ScriptObject)obj;
+        // Since every JS Object has a toString, we only override "String toString()" it if it's explicitly specified
+        if ("toString".equals(name) && !sobj.hasOwnProperty("toString")) {
+            return null;
+        }
+
+        final Object fnObj = sobj.get(name);
+        if (fnObj instanceof ScriptFunction) {
+            return adaptHandle(((ScriptFunction)fnObj).getBoundInvokeHandle(sobj), type, varArg);
+        } else if(fnObj == null || fnObj instanceof Undefined) {
+            return null;
+        } else {
+            throw typeError("not.a.function", name);
+        }
+    }
+
+    private static MethodHandle adaptHandle(final MethodHandle handle, final MethodType type, final boolean varArg) {
+        return Bootstrap.getLinkerServices().asType(ScriptObject.pairArguments(handle, type, varArg), type);
+    }
+
+    /**
+     * Encapsulation of the information used to generate methods in the adapter classes. Basically, a wrapper around the
+     * reflective Method object, a cached MethodType, and the name of the field in the adapter class that will hold the
+     * method handle serving as the implementation of this method in adapter instances.
+     *
+     */
+    private static class MethodInfo {
+        private final Method method;
+        private final MethodType type;
+        private String methodHandleFieldName;
+
+        private MethodInfo(final Class<?> clazz, final String name, final Class<?>... argTypes) throws NoSuchMethodException {
+            this(clazz.getDeclaredMethod(name, argTypes));
+        }
+
+        private MethodInfo(final Method method) {
+            this.method = method;
+            this.type   = MH.type(method.getReturnType(), method.getParameterTypes());
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            return obj instanceof MethodInfo && equals((MethodInfo)obj);
+        }
+
+        private boolean equals(final MethodInfo other) {
+            // Only method name and type are used for comparison; method handle field name is not.
+            return getName().equals(other.getName()) && type.equals(other.type);
+        }
+
+        String getName() {
+            return method.getName();
+        }
+
+        @Override
+        public int hashCode() {
+            return getName().hashCode() ^ type.hashCode();
+        }
+
+        void setIsCanonical(final Set<String> usedFieldNames) {
+            int i = 0;
+            String fieldName = getName();
+            while(!usedFieldNames.add(fieldName)) {
+                fieldName = getName() + (i++);
+            }
+            methodHandleFieldName = fieldName;
+        }
+    }
+
+    private void generateMethods() {
+        for(final MethodInfo mi: methodInfos) {
+            generateMethod(mi);
+        }
+    }
+
+    /**
+     * Generates a method in the adapter class that adapts a method from the original class. The generated methods will
+     * inspect the method handle field assigned to them. If it is null (the JS object doesn't provide an implementation
+     * for the method) then it will either invoke its version in the supertype, or if it is abstract, throw an
+     * {@link UnsupportedOperationException}. Otherwise, if the method handle field's value is not null, the handle is
+     * invoked using invokeExact (signature polymorphic invocation as per JLS 15.12.3). Before the invocation, the
+     * current Nashorn {@link Context} is checked, and if it is different than the global used to create the adapter
+     * instance, the creating global is set to be the current global. In this case, the previously current global is
+     * restored after the invocation. If invokeExact results in a Throwable that is not one of the method's declared
+     * exceptions, and is not an unchecked throwable, then it is wrapped into a {@link RuntimeException} and the runtime
+     * exception is thrown. The method handle retrieved from the field is guaranteed to exactly match the signature of
+     * the method; this is guaranteed by the way constructors of the adapter class obtain them using
+     * {@link #getHandle(Object, String, MethodType, boolean)}.
+     * @param mi the method info describing the method to be generated.
+     */
+    private void generateMethod(final MethodInfo mi) {
+        final Method method = mi.method;
+        final int mod = method.getModifiers();
+        final int access = ACC_PUBLIC | (method.isVarArgs() ? ACC_VARARGS : 0);
+        final Class<?>[] exceptions = method.getExceptionTypes();
+        final String[] exceptionNames = new String[exceptions.length];
+        for (int i = 0; i < exceptions.length; ++i) {
+            exceptionNames[i] = Type.getInternalName(exceptions[i]);
+        }
+        final MethodType type = mi.type;
+        final String methodDesc = type.toMethodDescriptorString();
+        final String name = mi.getName();
+
+        final Type asmType = Type.getMethodType(methodDesc);
+        final Type[] asmArgTypes = asmType.getArgumentTypes();
+
+        // Determine the first index for a local variable
+        int nextLocalVar = 1; // this
+        for(final Type t: asmArgTypes) {
+            nextLocalVar += t.getSize();
+        }
+
+        final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(access, name, methodDesc, null,
+                exceptionNames));
+        mv.visitCode();
+
+        final Label methodHandleNotNull = new Label();
+        final Label methodEnd = new Label();
+
+        final Type returnType = Type.getType(type.returnType());
+
+        // Get the method handle
+        mv.visitVarInsn(ALOAD, 0);
+        mv.getfield(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
+        mv.visitInsn(DUP); // It'll remain on the stack all the way until the invocation
+        // Check if the method handle is null
+        mv.visitJumpInsn(IFNONNULL, methodHandleNotNull);
+        if(Modifier.isAbstract(mod)) {
+            // If it's null, and the method is abstract, throw an exception
+            mv.anew(UNSUPPORTED_OPERATION_TYPE);
+            mv.dup();
+            mv.invokespecial(UNSUPPORTED_OPERATION_TYPE_NAME, INIT, VOID_NOARG);
+            mv.athrow();
+        } else {
+            // If it's null, and the method is not abstract, delegate to super method.
+            mv.visitVarInsn(ALOAD, 0);
+            int nextParam = 1;
+            for(final Type t: asmArgTypes) {
+                mv.load(nextParam, t);
+                nextParam += t.getSize();
+            }
+            mv.invokespecial(superClassName, name, methodDesc);
+            mv.areturn(returnType);
+        }
+
+        mv.visitLabel(methodHandleNotNull);
+        final int currentGlobalVar = nextLocalVar++;
+        final int globalsDifferVar = nextLocalVar++;
+
+        // Emit code for switching to the creating global
+        // ScriptObject currentGlobal = Context.getGlobal();
+        invokeGetGlobal(mv);
+        mv.dup();
+        mv.visitVarInsn(ASTORE, currentGlobalVar);
+        // if(this.global == currentGlobal) {
+        loadGlobalOnStack(mv);
+        final Label globalsDiffer = new Label();
+        mv.ifacmpne(globalsDiffer);
+        //     globalsDiffer = false
+        mv.iconst(0); // false
+        final Label proceed = new Label();
+        mv.goTo(proceed);
+        mv.visitLabel(globalsDiffer);
+        // } else {
+        //     Context.setGlobal(this.global);
+        loadGlobalOnStack(mv);
+        invokeSetGlobal(mv);
+        //     globalsDiffer = true
+        mv.iconst(1);
+
+        mv.visitLabel(proceed);
+        mv.visitVarInsn(ISTORE, globalsDifferVar);
+
+        // Load all parameters back on stack for dynamic invocation.
+        int varOffset = 1;
+        for (final Type t : asmArgTypes) {
+            mv.load(varOffset, t);
+            varOffset += t.getSize();
+        }
+
+        // Invoke the target method handle
+        final Label tryBlockStart = new Label();
+        mv.visitLabel(tryBlockStart);
+        mv.invokevirtual(METHOD_HANDLE_TYPE.getInternalName(), "invokeExact", type.toMethodDescriptorString());
+        final Label tryBlockEnd = new Label();
+        mv.visitLabel(tryBlockEnd);
+        emitFinally(mv, currentGlobalVar, globalsDifferVar);
+        mv.areturn(returnType);
+
+        // If Throwable is not declared, we need an adapter from Throwable to RuntimeException
+        final boolean throwableDeclared = isThrowableDeclared(exceptions);
+        final Label throwableHandler;
+        if (!throwableDeclared) {
+            // Add "throw new RuntimeException(Throwable)" handler for Throwable
+            throwableHandler = new Label();
+            mv.visitLabel(throwableHandler);
+            mv.anew(RUNTIME_EXCEPTION_TYPE);
+            mv.dupX1();
+            mv.swap();
+            mv.invokespecial(RUNTIME_EXCEPTION_TYPE_NAME, INIT, Type.getMethodDescriptor(Type.VOID_TYPE, THROWABLE_TYPE));
+            // Fall through to rethrow handler
+        } else {
+            throwableHandler = null;
+        }
+        final Label rethrowHandler = new Label();
+        mv.visitLabel(rethrowHandler);
+        // Rethrow handler for RuntimeException, Error, and all declared exception types
+        emitFinally(mv, currentGlobalVar, globalsDifferVar);
+        mv.athrow();
+        mv.visitLabel(methodEnd);
+
+        mv.visitLocalVariable("currentGlobal", SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, methodHandleNotNull, methodEnd, currentGlobalVar);
+        mv.visitLocalVariable("globalsDiffer", Type.INT_TYPE.getDescriptor(), null, methodHandleNotNull, methodEnd, globalsDifferVar);
+
+        if(throwableDeclared) {
+            mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrowHandler, THROWABLE_TYPE_NAME);
+            assert throwableHandler == null;
+        } else {
+            mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrowHandler, RUNTIME_EXCEPTION_TYPE_NAME);
+            mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrowHandler, ERROR_TYPE_NAME);
+            for(final String excName: exceptionNames) {
+                mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrowHandler, excName);
+            }
+            mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, throwableHandler, THROWABLE_TYPE_NAME);
+        }
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /**
+     * Emit code to restore the previous Nashorn Context when needed.
+     * @param mv the instruction adapter
+     * @param currentGlobalVar index of the local variable holding the reference to the current global at method
+     * entry.
+     * @param globalsDifferVar index of the boolean local variable that is true if the global needs to be restored.
+     */
+    private void emitFinally(final InstructionAdapter mv, final int currentGlobalVar, final int globalsDifferVar) {
+        // Emit code to restore the previous Nashorn global if needed
+        mv.visitVarInsn(ILOAD, globalsDifferVar);
+        final Label skip = new Label();
+        mv.ifeq(skip);
+        mv.visitVarInsn(ALOAD, currentGlobalVar);
+        invokeSetGlobal(mv);
+        mv.visitLabel(skip);
+    }
+
+    private void loadGlobalOnStack(final InstructionAdapter mv) {
+        mv.visitVarInsn(ALOAD, 0);
+        mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+    }
+
+    private static boolean isThrowableDeclared(final Class<?>[] exceptions) {
+        for (final Class<?> exception : exceptions) {
+            if (exception == Throwable.class) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Gathers methods that can be implemented or overridden from the specified type into this factory's
+     * {@link #methodInfos} set. It will add all non-final, non-static methods that are either public or protected from
+     * the type if the type itself is public. If the type is a class, the method will recursively invoke itself for its
+     * superclass and the interfaces it implements, and add further methods that were not directly declared on the
+     * class.
+     * @param type the type defining the methods.
+     */
+    private void gatherMethods(final Class<?> type) {
+        if (Modifier.isPublic(type.getModifiers())) {
+            final Method[] typeMethods = type.isInterface() ? type.getMethods() : type.getDeclaredMethods();
+
+            for (final Method typeMethod: typeMethods) {
+                final int m = typeMethod.getModifiers();
+                if (Modifier.isStatic(m)) {
+                    continue;
+                }
+                if (Modifier.isPublic(m) || Modifier.isProtected(m)) {
+                    final MethodInfo mi = new MethodInfo(typeMethod);
+                    if (Modifier.isFinal(m)) {
+                        finalMethods.add(mi);
+                    } else if (!finalMethods.contains(mi) && methodInfos.add(mi)) {
+                        if (Modifier.isAbstract(m)) {
+                            abstractMethodNames.add(mi.getName());
+                        }
+                        mi.setIsCanonical(usedFieldNames);
+                    }
+                }
+            }
+        }
+        // If the type is a class, visit its superclasses and declared interfaces. If it's an interface, we're done.
+        // Needing to invoke the method recursively for a non-interface Class object is the consequence of needing to
+        // see all declared protected methods, and Class.getDeclaredMethods() doesn't provide those declared in a
+        // superclass. For interfaces, we used Class.getMethods(), as we're only interested in public ones there, and
+        // getMethods() does provide those declared in a superinterface.
+        if (!type.isInterface()) {
+            final Class<?> superType = type.getSuperclass();
+            if (superType != null) {
+                gatherMethods(superType);
+            }
+            for (final Class<?> itf: type.getInterfaces()) {
+                gatherMethods(itf);
+            }
+        }
+    }
+
+    private void gatherMethods(final List<Class<?>> classes) {
+        for(final Class<?> c: classes) {
+            gatherMethods(c);
+        }
+    }
+
+    /**
+     * Creates a collection of methods that are not final, but we still never allow them to be overridden in adapters,
+     * as explicitly declaring them automatically is a bad idea. Currently, this means {@code Object.finalize()} and
+     * {@code Object.clone()}.
+     * @return a collection of method infos representing those methods that we never override in adapter classes.
+     */
+    private static Collection<MethodInfo> getExcludedMethods() {
+        return AccessController.doPrivileged(new PrivilegedAction<Collection<MethodInfo>>() {
+            @Override
+            public Collection<MethodInfo> run() {
+                try {
+                    return Arrays.asList(
+                            new MethodInfo(Object.class, "finalize"),
+                            new MethodInfo(Object.class, "clone"));
+                } catch (final NoSuchMethodException e) {
+                    throw new AssertionError(e);
+                }
+            }
+        });
+    }
+
+    private static ProtectionDomain createGeneratedProtectionDomain() {
+        // Generated classes need to have AllPermission. Since we require the "createClassLoader" RuntimePermission, we
+        // can create a class loader that'll load new classes with any permissions. Our generated classes are just
+        // delegating adapters, so having AllPermission can't cause anything wrong; the effective set of permissions for
+        // the executing script functions will still be limited by the permissions of the caller and the permissions of
+        // the script.
+        final Permissions permissions = new Permissions();
+        permissions.add(new AllPermission());
+        return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
+    }
+
+    private static class AdapterInfo {
+        final StaticClass adapterClass;
+        final boolean autoConvertibleFromFunction;
+        final AnnotatedAdaptationOutcome adaptationOutcome;
+
+        AdapterInfo(final StaticClass adapterClass, final boolean autoConvertibleFromFunction) {
+            this.adapterClass = adapterClass;
+            this.autoConvertibleFromFunction = autoConvertibleFromFunction;
+            this.adaptationOutcome = AnnotatedAdaptationOutcome.SUCCESS;
+        }
+
+        AdapterInfo(final AdaptationOutcome outcome, final String classList) {
+            this(new AnnotatedAdaptationOutcome(outcome, classList));
+        }
+
+        AdapterInfo(final AnnotatedAdaptationOutcome adaptationOutcome) {
+            this.adapterClass = null;
+            this.autoConvertibleFromFunction = false;
+            this.adaptationOutcome = adaptationOutcome;
+        }
+    }
+
+    /**
+     * An adaptation outcome accompanied with a name of a class (or a list of multiple class names) that are the reason
+     * an adapter could not be generated.
+     */
+    private static class AnnotatedAdaptationOutcome {
+        static final AnnotatedAdaptationOutcome SUCCESS = new AnnotatedAdaptationOutcome(AdaptationOutcome.SUCCESS, "");
+
+        private final AdaptationOutcome adaptationOutcome;
+        private final String classList;
+
+        AnnotatedAdaptationOutcome(final AdaptationOutcome adaptationOutcome, final String classList) {
+            this.adaptationOutcome = adaptationOutcome;
+            this.classList = classList;
+        }
+
+        void typeError() {
+            assert adaptationOutcome != AdaptationOutcome.SUCCESS;
+            throw ECMAErrors.typeError("extend." + adaptationOutcome, classList);
+        }
+    }
+
+    /**
+     * For a given class, create its adapter class and associated info.
+     * @param type the class for which the adapter is created
+     * @return the adapter info for the class.
+     */
+    private static AdapterInfo createAdapterInfo(final Class<?>[] types, final ClassAndLoader definingClassAndLoader) {
+        Class<?> superClass = null;
+        final List<Class<?>> interfaces = new ArrayList<>(types.length);
+        for(final Class<?> t: types) {
+            final int mod = t.getModifiers();
+            if(!t.isInterface()) {
+                if(superClass != null) {
+                    return new AdapterInfo(AdaptationOutcome.ERROR_MULTIPLE_SUPERCLASSES, t.getCanonicalName() + " and " + superClass.getCanonicalName());
+                }
+                if (Modifier.isFinal(mod)) {
+                    return new AdapterInfo(AdaptationOutcome.ERROR_FINAL_CLASS, t.getCanonicalName());
+                }
+                superClass = t;
+            } else {
+                interfaces.add(t);
+            }
+            if(!Modifier.isPublic(mod)) {
+                return new AdapterInfo(AdaptationOutcome.ERROR_NON_PUBLIC_CLASS, t.getCanonicalName());
+            }
+        }
+        final Class<?> effectiveSuperClass = superClass == null ? Object.class : superClass;
+        return AccessController.doPrivileged(new PrivilegedAction<AdapterInfo>() {
+            @Override
+            public AdapterInfo run() {
+                try {
+                    final JavaAdapterFactory factory = new JavaAdapterFactory(effectiveSuperClass, interfaces, definingClassAndLoader);
+                    return new AdapterInfo(StaticClass.forClass(factory.generateClass()),
+                            factory.isAutoConvertibleFromFunction());
+                } catch (final AdaptationException e) {
+                    return new AdapterInfo(e.outcome);
+                }
+            }
+        });
+    }
+
+    @SuppressWarnings("serial")
+    private static class AdaptationException extends Exception {
+        private final AnnotatedAdaptationOutcome outcome;
+        AdaptationException(final AdaptationOutcome outcome, final String classList) {
+            this.outcome = new AnnotatedAdaptationOutcome(outcome, classList);
+        }
+    }
+
+    private String getCommonSuperClass(final String type1, final String type2) {
+        try {
+            final Class<?> c1 = Class.forName(type1.replace('/', '.'), false, commonLoader);
+            final Class<?> c2 = Class.forName(type2.replace('/', '.'), false, commonLoader);
+            if (c1.isAssignableFrom(c2)) {
+                return type1;
+            }
+            if (c2.isAssignableFrom(c1)) {
+                return type2;
+            }
+            if (c1.isInterface() || c2.isInterface()) {
+                return "java/lang/Object";
+            }
+            return assignableSuperClass(c1, c2).getName().replace('.', '/');
+        } catch(final ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static Class<?> assignableSuperClass(final Class<?> c1, final Class<?> c2) {
+        final Class<?> superClass = c1.getSuperclass();
+        return superClass.isAssignableFrom(c2) ? superClass : assignableSuperClass(superClass, c2);
+    }
+
+    /**
+     * Choose between the passed class loader and the class loader that defines the ScriptObject class, based on which
+     * of the two can see the classes in both.
+     * @param classAndLoader the loader and a representative class from it that will be used to add the generated
+     * adapter to its ADAPTER_INFO_MAPS.
+     * @return the class loader that sees both the specified class and Nashorn classes.
+     * @throws IllegalStateException if no such class loader is found.
+     */
+    private static ClassLoader findCommonLoader(final ClassAndLoader classAndLoader) throws AdaptationException {
+        final ClassLoader loader = classAndLoader.getLoader();
+        if (canSeeClass(loader, ScriptObject.class)) {
+            return loader;
+        }
+
+        final ClassLoader nashornLoader = ScriptObject.class.getClassLoader();
+        if(canSeeClass(nashornLoader, classAndLoader.clazz)) {
+            return nashornLoader;
+        }
+
+        throw new AdaptationException(AdaptationOutcome.ERROR_NO_COMMON_LOADER, classAndLoader.clazz.getCanonicalName());
+    }
+
+    private static boolean canSeeClass(final ClassLoader cl, final Class<?> clazz) {
+        try {
+            return Class.forName(clazz.getName(), false, cl) == clazz;
+        } catch (final ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Given a list of types that define the superclass/interfaces for an adapter class, returns a single type from the
+     * list that will be used to attach the adapter to its ClassValue. The first type in the array that is defined in a
+     * class loader that can also see all other types is returned. If there is no such loader, an exception is thrown.
+     * @param types the input types
+     * @return the first type from the array that is defined in a class loader that can also see all other types.
+     */
+    private static ClassAndLoader getDefiningClassAndLoader(final Class<?>[] types) {
+        // Short circuit the cheap case
+        if(types.length == 1) {
+            return new ClassAndLoader(types[0], false);
+        }
+
+        return AccessController.doPrivileged(new PrivilegedAction<ClassAndLoader>() {
+            @Override
+            public ClassAndLoader run() {
+                return getDefiningClassAndLoaderPrivileged(types);
+            }
+        });
+    }
+
+    private static ClassAndLoader getDefiningClassAndLoaderPrivileged(final Class<?>[] types) {
+        final Collection<ClassAndLoader> maximumVisibilityLoaders = getMaximumVisibilityLoaders(types);
+
+        final Iterator<ClassAndLoader> it = maximumVisibilityLoaders.iterator();
+        if(maximumVisibilityLoaders.size() == 1) {
+            // Fortunate case - single maximally specific class loader; return its representative class.
+            return it.next();
+        }
+
+        // Ambiguity; throw an error.
+        assert maximumVisibilityLoaders.size() > 1; // basically, can't be zero
+        final StringBuilder b = new StringBuilder();
+        b.append(it.next().clazz.getCanonicalName());
+        while(it.hasNext()) {
+            b.append(", ").append(it.next().clazz.getCanonicalName());
+        }
+        throw typeError("extend.ambiguous.defining.class", b.toString());
+    }
+
+    /**
+     * Given an array of types, return a subset of their class loaders that are maximal according to the
+     * "can see other loaders' classes" relation, which is presumed to be a partial ordering.
+     * @param types types
+     * @return a collection of maximum visibility class loaders. It is guaranteed to have at least one element.
+     */
+    private static Collection<ClassAndLoader> getMaximumVisibilityLoaders(final Class<?>[] types) {
+        final List<ClassAndLoader> maximumVisibilityLoaders = new LinkedList<>();
+        outer:  for(final ClassAndLoader maxCandidate: getClassLoadersForTypes(types)) {
+            final Iterator<ClassAndLoader> it = maximumVisibilityLoaders.iterator();
+            while(it.hasNext()) {
+                final ClassAndLoader existingMax = it.next();
+                final boolean candidateSeesExisting = canSeeClass(maxCandidate.getRetrievedLoader(), existingMax.clazz);
+                final boolean exitingSeesCandidate = canSeeClass(existingMax.getRetrievedLoader(), maxCandidate.clazz);
+                if(candidateSeesExisting) {
+                    if(!exitingSeesCandidate) {
+                        // The candidate sees the the existing maximum, so drop the existing one as it's no longer maximal.
+                        it.remove();
+                    }
+                    // NOTE: there's also the anomalous case where both loaders see each other. Not sure what to do
+                    // about that one, as two distinct class loaders both seeing each other's classes is weird and
+                    // violates the assumption that the relation "sees others' classes" is a partial ordering. We'll
+                    // just not do anything, and treat them as incomparable; hopefully some later class loader that
+                    // comes along can eliminate both of them, if it can not, we'll end up with ambiguity anyway and
+                    // throw an error at the end.
+                } else if(exitingSeesCandidate) {
+                    // Existing sees the candidate, so drop the candidate.
+                    continue outer;
+                }
+            }
+            // If we get here, no existing maximum visibility loader could see the candidate, so the candidate is a new
+            // maximum.
+            maximumVisibilityLoaders.add(maxCandidate);
+        }
+        return maximumVisibilityLoaders;
+    }
+
+    private static Collection<ClassAndLoader> getClassLoadersForTypes(final Class<?>[] types) {
+        final Map<ClassAndLoader, ClassAndLoader> classesAndLoaders = new LinkedHashMap<>();
+        for(final Class<?> c: types) {
+            final ClassAndLoader cl = new ClassAndLoader(c, true);
+            if(!classesAndLoaders.containsKey(cl)) {
+                classesAndLoaders.put(cl, cl);
+            }
+        }
+        return classesAndLoaders.keySet();
+    }
+
+    /**
+     * A tuple of a class loader and a single class representative of the classes that can be loaded through it. Its
+     * equals/hashCode is defined in terms of the identity of the class loader.
+     */
+    private static final class ClassAndLoader {
+        private final Class<?> clazz;
+        // Don't access this directly; most of the time, use getRetrievedLoader(), or if you know what you're doing,
+        // getLoader().
+        private ClassLoader loader;
+        // We have mild affinity against eagerly retrieving the loader, as we need to do it in a privileged block. For
+        // the most basic case of looking up an already-generated adapter info for a single type, we avoid it.
+        private boolean loaderRetrieved;
+
+        ClassAndLoader(final Class<?> clazz, final boolean retrieveLoader) {
+            this.clazz = clazz;
+            if(retrieveLoader) {
+                retrieveLoader();
+            }
+        }
+
+        ClassLoader getLoader() {
+            if(!loaderRetrieved) {
+                retrieveLoader();
+            }
+            return getRetrievedLoader();
+        }
+
+        ClassLoader getRetrievedLoader() {
+            assert loaderRetrieved;
+            return loader;
+        }
+
+        private void retrieveLoader() {
+            loader = clazz.getClassLoader();
+            loaderRetrieved = true;
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            return obj instanceof ClassAndLoader && ((ClassAndLoader)obj).getRetrievedLoader() == getRetrievedLoader();
+        }
+
+        @Override
+        public int hashCode() {
+            return System.identityHashCode(getRetrievedLoader());
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java
new file mode 100644
index 0000000..3d8363e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java
@@ -0,0 +1,301 @@
+/*
+ * 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 static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.internal.dynalink.support.TypeUtilities;
+import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Utility class shared by {@link NashornLinker} and {@code NashornPrimitiveLinker} for converting JS values to Java
+ * types.
+ */
+public class JavaArgumentConverters {
+
+    private static final MethodHandle TO_BOOLEAN        = findOwnMH("toBoolean", Boolean.class, Object.class);
+    private static final MethodHandle TO_STRING         = findOwnMH("toString", String.class, Object.class);
+    private static final MethodHandle TO_DOUBLE         = findOwnMH("toDouble", Double.class, Object.class);
+    private static final MethodHandle TO_NUMBER         = findOwnMH("toNumber", Number.class, Object.class);
+    private static final MethodHandle TO_LONG           = findOwnMH("toLong", Long.class, Object.class);
+    private static final MethodHandle TO_LONG_PRIMITIVE = findOwnMH("toLongPrimitive", long.class, Object.class);
+    private static final MethodHandle TO_CHAR           = findOwnMH("toChar", Character.class, Object.class);
+    private static final MethodHandle TO_CHAR_PRIMITIVE = findOwnMH("toCharPrimitive", char.class, Object.class);
+
+    private JavaArgumentConverters() {
+    }
+
+    static MethodHandle getConverter(final Class<?> targetType) {
+        return CONVERTERS.get(targetType);
+    }
+
+    @SuppressWarnings("unused")
+    private static Boolean toBoolean(final Object obj) {
+        if (obj instanceof Boolean) {
+            return (Boolean) obj;
+        }
+
+        if (obj == null) {
+            // NOTE: FindBugs complains here about the NP_BOOLEAN_RETURN_NULL pattern: we're returning null from a
+            // method that has a return type of Boolean, as it is worried about a NullPointerException if there's a
+            // conversion to a primitive boolean. We know what we're doing, though. We're using a separate method when
+            // we're converting Object to a primitive boolean - see how the CONVERTERS map is populated. We specifically
+            // want to have null and Undefined to be converted to a (Boolean)null when being passed to a Java method
+            // that expects a Boolean argument.
+            // TODO: if/when we're allowed to use FindBugs at build time, we can use annotations to disable this warning
+            return null;
+        }
+
+        if (obj == UNDEFINED) {
+            // NOTE: same reasoning for FindBugs NP_BOOLEAN_RETURN_NUL warning as in the preceding comment.
+            return null;
+        }
+
+        if (obj instanceof Number) {
+            final double num = ((Number) obj).doubleValue();
+            return num != 0 && !Double.isNaN(num);
+        }
+
+        if (obj instanceof String || obj instanceof ConsString) {
+            return ((CharSequence) obj).length() > 0;
+        }
+
+        if (obj instanceof ScriptObject) {
+            return true;
+        }
+
+        throw assertUnexpectedType(obj);
+    }
+
+    private static Character toChar(final Object o) {
+        if (o == null) {
+            return null;
+        }
+
+        if (o instanceof Number) {
+            final int ival = ((Number)o).intValue();
+            if (ival >= Character.MIN_VALUE && ival <= Character.MAX_VALUE) {
+                return Character.valueOf((char) ival);
+            }
+
+            throw typeError("cant.convert.number.to.char");
+        }
+
+        final String s = toString(o);
+        if (s == null) {
+            return null;
+        }
+
+        if (s.length() != 1) {
+            throw typeError("cant.convert.string.to.char");
+        }
+
+        return s.charAt(0);
+    }
+
+    @SuppressWarnings("unused")
+    private static char toCharPrimitive(final Object obj0) {
+        final Character c = toChar(obj0);
+        return c == null ? (char)0 : c;
+    }
+
+    // Almost identical to ScriptRuntime.toString, but doesn't handle StaticClass specially, and it returns null for
+    // null instead of the string "null".
+    private static String toString(final Object obj0) {
+        for (Object obj = obj0; ;) {
+            if (obj == null) {
+                return null;
+            } else if (obj instanceof String) {
+                return (String) obj;
+            } else if (obj instanceof ConsString) {
+                return obj.toString();
+            } else if (obj instanceof Number) {
+                return JSType.toString(((Number)obj).doubleValue());
+            } else if (obj instanceof Boolean) {
+                return ((Boolean) obj).toString();
+            } else if (obj == UNDEFINED) {
+                return "undefined";
+            } else if (obj instanceof ScriptObject) {
+                obj = JSType.toPrimitive(obj, String.class);
+                continue;
+            }
+            throw assertUnexpectedType(obj);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static Double toDouble(final Object obj0) {
+        // TODO - Order tests for performance.
+        for (Object obj = obj0; ;) {
+            if (obj == null) {
+                return null;
+            } else if (obj instanceof Double) {
+                return (Double) obj;
+            } else if (obj instanceof Number) {
+                return ((Number)obj).doubleValue();
+            } else if (obj instanceof String) {
+                return JSType.toNumber((String) obj);
+            } else if (obj instanceof ConsString) {
+                return JSType.toNumber(obj.toString());
+            } else if (obj instanceof Boolean) {
+                return (Boolean) obj ? 1 : +0.0;
+            } else if (obj instanceof ScriptObject) {
+                obj = JSType.toPrimitive(obj, Number.class);
+                continue;
+            } else if (obj == UNDEFINED) {
+                return Double.NaN;
+            }
+            throw assertUnexpectedType(obj);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static Number toNumber(final Object obj0) {
+        // TODO - Order tests for performance.
+        for (Object obj = obj0; ;) {
+            if (obj == null) {
+                return null;
+            } else if (obj instanceof Number) {
+                return (Number) obj;
+            } else if (obj instanceof String) {
+                return JSType.toNumber((String) obj);
+            } else if (obj instanceof ConsString) {
+                return JSType.toNumber(obj.toString());
+            } else if (obj instanceof Boolean) {
+                return (Boolean) obj ? 1 : +0.0;
+            } else if (obj instanceof ScriptObject) {
+                obj = JSType.toPrimitive(obj, Number.class);
+                continue;
+            } else if (obj == UNDEFINED) {
+                return Double.NaN;
+            }
+            throw assertUnexpectedType(obj);
+        }
+    }
+
+    private static Long toLong(final Object obj0) {
+        // TODO - Order tests for performance.
+        for (Object obj = obj0; ;) {
+            if (obj == null) {
+                return null;
+            } else if (obj instanceof Long) {
+                return (Long) obj;
+            } else if (obj instanceof Number) {
+                return ((Number)obj).longValue();
+            } else if (obj instanceof String || obj instanceof ConsString) {
+                return JSType.toLong(obj);
+            } else if (obj instanceof Boolean) {
+                return (Boolean)obj ? 1L : 0L;
+            } else if (obj instanceof ScriptObject) {
+                obj = JSType.toPrimitive(obj, Number.class);
+                continue;
+            } else if (obj == UNDEFINED) {
+                return null; // null or 0L?
+            }
+            throw assertUnexpectedType(obj);
+        }
+    }
+
+    private static AssertionError assertUnexpectedType(final Object obj) {
+        return new AssertionError("Unexpected type" + obj.getClass().getName() + ". Guards should have prevented this");
+    }
+
+    @SuppressWarnings("unused")
+    private static long toLongPrimitive(final Object obj0) {
+        final Long l = toLong(obj0);
+        return l == null ? 0L : l;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), JavaArgumentConverters.class, name, MH.type(rtype, types));
+    }
+
+    private static final Map<Class<?>, MethodHandle> CONVERTERS = new HashMap<>();
+
+    static {
+        CONVERTERS.put(Number.class, TO_NUMBER);
+        CONVERTERS.put(String.class, TO_STRING);
+
+        CONVERTERS.put(boolean.class, JSType.TO_BOOLEAN.methodHandle());
+        CONVERTERS.put(Boolean.class, TO_BOOLEAN);
+
+        CONVERTERS.put(char.class, TO_CHAR_PRIMITIVE);
+        CONVERTERS.put(Character.class, TO_CHAR);
+
+        CONVERTERS.put(double.class, JSType.TO_NUMBER.methodHandle());
+        CONVERTERS.put(Double.class, TO_DOUBLE);
+
+        CONVERTERS.put(long.class, TO_LONG_PRIMITIVE);
+        CONVERTERS.put(Long.class, TO_LONG);
+
+        putLongConverter(Byte.class);
+        putLongConverter(Short.class);
+        putLongConverter(Integer.class);
+        putDoubleConverter(Float.class);
+
+    }
+
+    private static void putDoubleConverter(final Class<?> targetType) {
+        final Class<?> primitive = TypeUtilities.getPrimitiveType(targetType);
+        CONVERTERS.put(primitive,  MH.explicitCastArguments(JSType.TO_NUMBER.methodHandle(), JSType.TO_NUMBER.methodHandle().type().changeReturnType(primitive)));
+        CONVERTERS.put(targetType, MH.filterReturnValue(TO_DOUBLE, findOwnMH(primitive.getName() + "Value", targetType, Double.class)));
+    }
+
+    private static void putLongConverter(final Class<?> targetType) {
+        final Class<?> primitive = TypeUtilities.getPrimitiveType(targetType);
+        CONVERTERS.put(primitive,  MH.explicitCastArguments(TO_LONG_PRIMITIVE, TO_LONG_PRIMITIVE.type().changeReturnType(primitive)));
+        CONVERTERS.put(targetType, MH.filterReturnValue(TO_LONG, findOwnMH(primitive.getName() + "Value", targetType, Long.class)));
+    }
+
+    @SuppressWarnings("unused")
+    private static Byte byteValue(final Long l) {
+        return l == null ? null : l.byteValue();
+    }
+
+    @SuppressWarnings("unused")
+    private static Short shortValue(final Long l) {
+        return l == null ? null : l.shortValue();
+    }
+
+    @SuppressWarnings("unused")
+    private static Integer intValue(final Long l) {
+        return l == null ? null : l.intValue();
+    }
+
+    @SuppressWarnings("unused")
+    private static Float floatValue(final Double d) {
+        return d == null ? null : d.floatValue();
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
new file mode 100644
index 0000000..05b1a93
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
@@ -0,0 +1,547 @@
+/*
+ * 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 jdk.nashorn.internal.lookup.MethodHandleFactory;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import jdk.internal.dynalink.ChainedCallSite;
+import jdk.internal.dynalink.DynamicLinker;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.Debug;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.options.Options;
+
+
+/**
+ * Relinkable form of call site.
+ */
+public class LinkerCallSite extends ChainedCallSite {
+    /** Maximum number of arguments passed directly. */
+    public static final int ARGLIMIT = 250;
+
+    private static final String PROFILEFILE = Options.getStringProperty("nashorn.profilefile", "NashornProfile.txt");
+
+    private static final MethodHandle INCREASE_MISS_COUNTER = findOwnMH("increaseMissCount", Object.class, String.class, Object.class);
+
+    LinkerCallSite(final NashornCallSiteDescriptor descriptor) {
+        super(descriptor);
+        if (Context.DEBUG) {
+            LinkerCallSite.count++;
+        }
+    }
+
+    /**
+     * Construct a new linker call site.
+     * @param name     Name of method.
+     * @param type     Method type.
+     * @param flags    Call site specific flags.
+     * @return New LinkerCallSite.
+     */
+    static LinkerCallSite newLinkerCallSite(final String name, final MethodType type, final int flags) {
+        final NashornCallSiteDescriptor desc = NashornCallSiteDescriptor.get(name, type, flags);
+
+        if (desc.isProfile()) {
+            return ProfilingLinkerCallSite.newProfilingLinkerCallSite(desc);
+        }
+
+        if (desc.isTrace()) {
+            return new TracingLinkerCallSite(desc);
+        }
+
+        return new LinkerCallSite(desc);
+    }
+
+    @Override
+    public String toString() {
+        return getDescriptor().toString();
+    }
+
+    /**
+     * Get the descriptor for this callsite
+     * @return a {@link NashornCallSiteDescriptor}
+     */
+    public NashornCallSiteDescriptor getNashornDescriptor() {
+        return (NashornCallSiteDescriptor)getDescriptor();
+    }
+
+    @Override
+    public void relink(final GuardedInvocation invocation, final MethodHandle relink) {
+        super.relink(invocation, getDebuggingRelink(relink));
+    }
+
+    @Override
+    public void resetAndRelink(final GuardedInvocation invocation, final MethodHandle relink) {
+        super.resetAndRelink(invocation, getDebuggingRelink(relink));
+    }
+
+    private MethodHandle getDebuggingRelink(final MethodHandle relink) {
+        if (Context.DEBUG) {
+            return MH.filterArguments(relink, 0, getIncreaseMissCounter(relink.type().parameterType(0)));
+        }
+        return relink;
+    }
+
+    private MethodHandle getIncreaseMissCounter(final Class<?> type) {
+        final MethodHandle missCounterWithDesc = MH.bindTo(INCREASE_MISS_COUNTER, getDescriptor().getName() + " @ " + getScriptLocation());
+        if (type == Object.class) {
+            return missCounterWithDesc;
+        }
+        return MH.asType(missCounterWithDesc, missCounterWithDesc.type().changeParameterType(0, type).changeReturnType(type));
+    }
+
+    private static String getScriptLocation() {
+        final StackTraceElement caller = DynamicLinker.getRelinkedCallSiteLocation();
+        return caller == null ? "unknown location" : (caller.getFileName() + ":" + caller.getLineNumber());
+    }
+
+    /**
+     * Instrumentation - increase the miss count when a callsite misses. Used as filter
+     * @param desc descriptor for table entry
+     * @param self self reference
+     * @return self reference
+     */
+    public static Object increaseMissCount(final String desc, final Object self) {
+        ++missCount;
+        if(r.nextInt(100) < missSamplingPercentage) {
+            AtomicInteger i = missCounts.get(desc);
+            if(i == null) {
+                i = new AtomicInteger(1);
+                missCounts.put(desc, i);
+            } else {
+                i.incrementAndGet();
+            }
+        }
+        return self;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        try {
+            return MH.findStatic(MethodHandles.lookup(), LinkerCallSite.class, name, MH.type(rtype, types));
+        } catch (final MethodHandleFactory.LookupException e) {
+            return MH.findVirtual(MethodHandles.lookup(), LinkerCallSite.class, name, MH.type(rtype, types));
+        }
+    }
+
+    /*
+     * Debugging call sites.
+     */
+
+    private static class ProfilingLinkerCallSite extends LinkerCallSite {
+        /** List of all profiled call sites. */
+        private static LinkedList<ProfilingLinkerCallSite> profileCallSites = null;
+
+        /** Start time when entered at zero depth. */
+        private long startTime;
+
+        /** Depth of nested calls. */
+        private int depth;
+
+        /** Total time spent in this call site. */
+        private long totalTime;
+
+        /** Total number of times call site entered. */
+        private long hitCount;
+
+        private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+        private static final MethodHandle PROFILEENTRY    = MH.findVirtual(LOOKUP, ProfilingLinkerCallSite.class, "profileEntry",    MH.type(Object.class, Object.class));
+        private static final MethodHandle PROFILEEXIT     = MH.findVirtual(LOOKUP, ProfilingLinkerCallSite.class, "profileExit",     MH.type(Object.class, Object.class));
+        private static final MethodHandle PROFILEVOIDEXIT = MH.findVirtual(LOOKUP, ProfilingLinkerCallSite.class, "profileVoidExit", MH.type(void.class));
+
+        /*
+         * Constructor
+         */
+
+        ProfilingLinkerCallSite(final NashornCallSiteDescriptor desc) {
+           super(desc);
+        }
+
+        public static ProfilingLinkerCallSite newProfilingLinkerCallSite(final NashornCallSiteDescriptor desc) {
+            if (profileCallSites == null) {
+                profileCallSites = new LinkedList<>();
+
+                final Thread profileDumperThread = new Thread(new ProfileDumper());
+                Runtime.getRuntime().addShutdownHook(profileDumperThread);
+            }
+
+            final ProfilingLinkerCallSite callSite = new ProfilingLinkerCallSite(desc);
+            profileCallSites.add(callSite);
+
+            return callSite;
+        }
+
+        @Override
+        public void setTarget(final MethodHandle newTarget) {
+            final MethodType type   = type();
+            final boolean    isVoid = type.returnType() == void.class;
+
+            MethodHandle methodHandle = MH.filterArguments(newTarget, 0, MH.bindTo(PROFILEENTRY, this));
+
+            if (isVoid) {
+                methodHandle = MH.filterReturnValue(methodHandle, MH.bindTo(PROFILEVOIDEXIT, this));
+            } else {
+                final MethodType filter = MH.type(type.returnType(), type.returnType());
+                methodHandle = MH.filterReturnValue(methodHandle, MH.asType(MH.bindTo(PROFILEEXIT, this), filter));
+            }
+
+            super.setTarget(methodHandle);
+        }
+
+        /**
+         * Start the clock for a profile entry and increase depth
+         * @param self argument to filter
+         * @return preserved argument
+         */
+        @SuppressWarnings("unused")
+        public Object profileEntry(final Object self) {
+            if (depth == 0) {
+                startTime = System.nanoTime();
+            }
+
+            depth++;
+            hitCount++;
+
+            return self;
+        }
+
+        /**
+         * Decrease depth and stop the clock for a profile entry
+         * @param result return value to filter
+         * @return preserved argument
+         */
+        @SuppressWarnings("unused")
+        public Object profileExit(final Object result) {
+            depth--;
+
+            if (depth == 0) {
+                totalTime += System.nanoTime() - startTime;
+            }
+
+            return result;
+        }
+
+        /**
+         * Decrease depth without return value filter
+         */
+        @SuppressWarnings("unused")
+        public void profileVoidExit() {
+            depth--;
+
+            if (depth == 0) {
+                totalTime += System.nanoTime() - startTime;
+            }
+        }
+
+        static class ProfileDumper implements Runnable {
+            @SuppressWarnings("resource")
+            @Override
+            public void run() {
+                PrintWriter out = null;
+                boolean fileOutput = false;
+
+                try {
+                    try {
+                        out = new PrintWriter(new FileOutputStream(PROFILEFILE));
+                        fileOutput = true;
+                    } catch (final FileNotFoundException e) {
+                        out = Context.getCurrentErr();
+                    }
+
+                    dump(out);
+                } finally {
+                    if (out != null && fileOutput) {
+                        out.close();
+                    }
+                }
+            }
+
+            private static void dump(final PrintWriter out) {
+                int index = 0;
+                for (final ProfilingLinkerCallSite callSite : profileCallSites) {
+                   out.println("" + (index++) + '\t' +
+                                  callSite.getDescriptor().getName() + '\t' +
+                                  callSite.totalTime + '\t' +
+                                  callSite.hitCount);
+                }
+            }
+        }
+    }
+
+    /**
+     * Debug subclass for LinkerCallSite that allows tracing
+     */
+    private static class TracingLinkerCallSite extends LinkerCallSite {
+
+        private static final MethodHandle TRACEOBJECT = findOwnMH("traceObject", Object.class, MethodHandle.class, Object[].class);
+        private static final MethodHandle TRACEVOID   = findOwnMH("traceVoid", void.class, MethodHandle.class, Object[].class);
+        private static final MethodHandle TRACEMISS   = findOwnMH("traceMiss", void.class, Object[].class);
+
+        TracingLinkerCallSite(final NashornCallSiteDescriptor desc) {
+           super(desc);
+        }
+
+        @Override
+        public void setTarget(final MethodHandle newTarget) {
+            if (!getNashornDescriptor().isTraceEnterExit()) {
+                super.setTarget(newTarget);
+                return;
+            }
+
+            final MethodType type = type();
+            final boolean isVoid = type.returnType() == void.class;
+
+            MethodHandle traceMethodHandle = isVoid ? TRACEVOID : TRACEOBJECT;
+            traceMethodHandle = MH.bindTo(traceMethodHandle, this);
+            traceMethodHandle = MH.bindTo(traceMethodHandle, newTarget);
+            traceMethodHandle = MH.asCollector(traceMethodHandle, Object[].class, type.parameterCount());
+            traceMethodHandle = MH.asType(traceMethodHandle, type);
+
+            super.setTarget(traceMethodHandle);
+        }
+
+        @Override
+        public void initialize(final MethodHandle relinkAndInvoke) {
+            super.initialize(getFallbackLoggingRelink(relinkAndInvoke));
+        }
+
+        @Override
+        public void relink(final GuardedInvocation invocation, final MethodHandle relink) {
+            super.relink(invocation, getFallbackLoggingRelink(relink));
+        }
+
+        @Override
+        public void resetAndRelink(final GuardedInvocation invocation, final MethodHandle relink) {
+            super.resetAndRelink(invocation, getFallbackLoggingRelink(relink));
+        }
+
+        private MethodHandle getFallbackLoggingRelink(final MethodHandle relink) {
+            if (!getNashornDescriptor().isTraceMisses()) {
+                // If we aren't tracing misses, just return relink as-is
+                return relink;
+            }
+            final MethodType type = relink.type();
+            return MH.foldArguments(relink, MH.asType(MH.asCollector(MH.bindTo(TRACEMISS, this), Object[].class, type.parameterCount()), type.changeReturnType(void.class)));
+        }
+
+        private void printObject(final PrintWriter out, final Object arg) {
+            if (!getNashornDescriptor().isTraceObjects()) {
+                out.print((arg instanceof ScriptObject) ? "ScriptObject" : arg);
+                return;
+            }
+
+            if (arg instanceof ScriptObject) {
+                final ScriptObject object = (ScriptObject)arg;
+
+                boolean isFirst = true;
+                final Set<Object> keySet = object.keySet();
+
+                if (keySet.isEmpty()) {
+                    out.print(ScriptRuntime.safeToString(arg));
+                } else {
+                    out.print("{ ");
+
+                    for (final Object key : keySet) {
+                        if (!isFirst) {
+                            out.print(", ");
+                        }
+
+                        out.print(key);
+                        out.print(":");
+
+                        final Object value = object.get(key);
+
+                        if (value instanceof ScriptObject) {
+                            out.print("...");
+                        } else {
+                            printObject(out, value);
+                        }
+
+                        isFirst = false;
+                    }
+
+                    out.print(" }");
+                }
+             } else {
+                out.print(ScriptRuntime.safeToString(arg));
+            }
+        }
+
+        private void tracePrint(final PrintWriter out, final String tag, final Object[] args, final Object result) {
+            //boolean isVoid = type().returnType() == void.class;
+            out.print(Debug.id(this) + " TAG " + tag);
+            out.print(getDescriptor().getName() + "(");
+
+            if (args.length > 0) {
+                printObject(out, args[0]);
+                for (int i = 1; i < args.length; i++) {
+                    final Object arg = args[i];
+                    out.print(", ");
+
+                    if (getNashornDescriptor().isTraceScope() || !(arg instanceof ScriptObject && ((ScriptObject)arg).isScope())) {
+                        printObject(out, arg);
+                    } else {
+                        out.print("SCOPE");
+                    }
+                }
+            }
+
+            out.print(")");
+
+            if (tag.equals("EXIT  ")) {
+                out.print(" --> ");
+                printObject(out, result);
+            }
+
+            out.println();
+        }
+
+        /**
+         * Trace event. Wrap an invocation with a return value
+         *
+         * @param mh     invocation handle
+         * @param args   arguments to call
+         *
+         * @return return value from invocation
+         *
+         * @throws Throwable if invocation fails or throws exception/error
+         */
+        @SuppressWarnings({"unused", "resource"})
+        public Object traceObject(final MethodHandle mh, final Object... args) throws Throwable {
+            final PrintWriter out = Context.getCurrentErr();
+            tracePrint(out, "ENTER ", args, null);
+            final Object result = mh.invokeWithArguments(args);
+            tracePrint(out, "EXIT  ", args, result);
+
+            return result;
+        }
+
+        /**
+         * Trace event. Wrap an invocation that returns void
+         *
+         * @param mh     invocation handle
+         * @param args   arguments to call
+         *
+         * @throws Throwable if invocation fails or throws exception/error
+         */
+        @SuppressWarnings({"unused", "resource"})
+        public void traceVoid(final MethodHandle mh, final Object... args) throws Throwable {
+            final PrintWriter out = Context.getCurrentErr();
+            tracePrint(out, "ENTER ", args, null);
+            mh.invokeWithArguments(args);
+            tracePrint(out, "EXIT  ", args, null);
+        }
+
+        /**
+         * Tracer function that logs a callsite miss
+         *
+         * @param args arguments to function
+         *
+         * @throws Throwable if invocation failes or throws exception/error
+         */
+        @SuppressWarnings("unused")
+        public void traceMiss(final Object... args) throws Throwable {
+            tracePrint(Context.getCurrentErr(), "MISS ", args, null);
+        }
+
+        private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+            try {
+                return MH.findStatic(MethodHandles.lookup(), TracingLinkerCallSite.class, name, MH.type(rtype, types));
+            } catch (final MethodHandleFactory.LookupException e) {
+                return MH.findVirtual(MethodHandles.lookup(), TracingLinkerCallSite.class, name, MH.type(rtype, types));
+            }
+        }
+    }
+
+    // counters updated in debug mode
+    private static int count;
+    private static final HashMap<String, AtomicInteger> missCounts = new HashMap<>();
+    private static int missCount;
+    private static final Random r = new Random();
+    private static final int missSamplingPercentage = Options.getIntProperty("nashorn.tcs.miss.samplePercent", 1);
+
+    /**
+     * Get the callsite count
+     * @return the count
+     */
+    public static int getCount() {
+        return count;
+    }
+
+    /**
+     * Get the callsite miss count
+     * @return the missCount
+     */
+    public static int getMissCount() {
+        return missCount;
+    }
+
+    /**
+     * Get given miss sampling percentage for sampler. Default is 1%. Specified with -Dnashorn.tcs.miss.samplePercent=x
+     * @return miss sampling percentage
+     */
+    public static int getMissSamplingPercentage() {
+        return missSamplingPercentage;
+    }
+
+    /**
+     * Dump the miss counts collected so far to a given output stream
+     * @param out print stream
+     */
+    public static void getMissCounts(final PrintWriter out) {
+        final ArrayList<Entry<String, AtomicInteger>> entries = new ArrayList<>(missCounts.entrySet());
+
+        Collections.sort(entries, new Comparator<Map.Entry<String, AtomicInteger>>() {
+            @Override
+            public int compare(final Entry<String, AtomicInteger> o1, final Entry<String, AtomicInteger> o2) {
+                return o2.getValue().get() - o1.getValue().get();
+            }
+        });
+
+        for (final Entry<String, AtomicInteger> entry : entries) {
+            out.println("  " + entry.getKey() + "\t" + entry.getValue().get());
+        }
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
new file mode 100644
index 0000000..3e73ff1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
@@ -0,0 +1,151 @@
+/*
+ * 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 static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.Guards;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Nashorn bottom linker; used as a last-resort catch-all linker for all linking requests that fall through all other
+ * linkers (see how {@link Bootstrap} class configures the dynamic linker in its static initializer). It will throw
+ * appropriate ECMAScript errors for attempts to invoke operations on {@code null}, link no-op property getters and
+ * setters for Java objects that couldn't be linked by any other linker, and throw appropriate ECMAScript errors for
+ * attempts to invoke arbitrary Java objects as functions or constructors.
+ */
+final class NashornBottomLinker implements GuardingDynamicLinker {
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
+            throws Exception {
+        final Object self = linkRequest.getReceiver();
+
+        if (self == null) {
+            return linkNull(linkRequest);
+        }
+
+        // None of the objects that can be linked by NashornLinker should ever reach here. Basically, anything below
+        // this point is a generic Java bean. Therefore, reaching here with a ScriptObject is a Nashorn bug.
+        assert isExpectedObject(self) : "Couldn't link " + linkRequest.getCallSiteDescriptor() + " for " + self.getClass().getName();
+
+        return linkBean(linkRequest, linkerServices);
+    }
+
+    private static final MethodHandle EMPTY_PROP_GETTER =
+            MH.dropArguments(MH.constant(Object.class, UNDEFINED), 0, Object.class);
+    private static final MethodHandle EMPTY_ELEM_GETTER =
+            MH.dropArguments(EMPTY_PROP_GETTER, 0, Object.class);
+    private static final MethodHandle EMPTY_PROP_SETTER =
+            MH.asType(EMPTY_ELEM_GETTER, EMPTY_ELEM_GETTER.type().changeReturnType(void.class));
+    private static final MethodHandle EMPTY_ELEM_SETTER =
+            MH.dropArguments(EMPTY_PROP_SETTER, 0, Object.class);
+
+    private static GuardedInvocation linkBean(final LinkRequest linkRequest, final LinkerServices linkerServices) {
+        final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor)linkRequest.getCallSiteDescriptor();
+        final Object self = linkRequest.getReceiver();
+        final String operator = desc.getFirstOperator();
+        switch (operator) {
+        case "new":
+            if(BeansLinker.isDynamicMethod(self)) {
+                throw typeError("method.not.constructor", ScriptRuntime.safeToString(self));
+            }
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+        case "call":
+            if(BeansLinker.isDynamicMethod(self)) {
+                throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
+            }
+            throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+        case "callMethod":
+        case "getMethod":
+            throw typeError("no.such.function", getArgument(linkRequest), ScriptRuntime.safeToString(self));
+        case "getProp":
+        case "getElem":
+            if (desc.getOperand() != null) {
+                return getInvocation(EMPTY_PROP_GETTER, self, linkerServices, desc);
+            }
+            return getInvocation(EMPTY_ELEM_GETTER, self, linkerServices, desc);
+        case "setProp":
+        case "setElem":
+            if (desc.getOperand() != null) {
+                return getInvocation(EMPTY_PROP_SETTER, self, linkerServices, desc);
+            }
+            return getInvocation(EMPTY_ELEM_SETTER, self, linkerServices, desc);
+        default:
+            break;
+        }
+        throw new AssertionError("unknown call type " + desc);
+    }
+
+    private static GuardedInvocation getInvocation(final MethodHandle handle, final Object self, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
+        return Bootstrap.asType(new GuardedInvocation(handle, Guards.getClassGuard(self.getClass())), linkerServices, desc);
+    }
+
+    // Used solely in an assertion to figure out if the object we get here is something we in fact expect. Objects
+    // linked by NashornLinker should never reach here.
+    private static boolean isExpectedObject(final Object obj) {
+        return !(NashornLinker.canLinkTypeStatic(obj.getClass()));
+    }
+
+    private static GuardedInvocation linkNull(final LinkRequest linkRequest) {
+        final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor)linkRequest.getCallSiteDescriptor();
+        final String operator = desc.getFirstOperator();
+        switch (operator) {
+        case "new":
+        case "call":
+            throw typeError("not.a.function", "null");
+        case "callMethod":
+        case "getMethod":
+            throw typeError("no.such.function", getArgument(linkRequest), "null");
+        case "getProp":
+        case "getElem":
+            throw typeError("cant.get.property", getArgument(linkRequest), "null");
+        case "setProp":
+        case "setElem":
+            throw typeError("cant.set.property", getArgument(linkRequest), "null");
+        default:
+            break;
+        }
+        throw new AssertionError("unknown call type " + desc);
+    }
+
+    private static String getArgument(final LinkRequest linkRequest) {
+        final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
+        if (desc.getNameTokenCount() > 2) {
+            return desc.getNameToken(2);
+        }
+        return ScriptRuntime.safeToString(linkRequest.getArguments()[1]);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
new file mode 100644
index 0000000..a251391
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
@@ -0,0 +1,285 @@
+/*
+ * 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.MethodType;
+import java.lang.ref.WeakReference;
+import java.util.WeakHashMap;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.support.AbstractCallSiteDescriptor;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+
+/**
+ * Nashorn-specific implementation of Dynalink's {@link CallSiteDescriptor}. The reason we have our own subclass is that
+ * we can have a more compact representation, as we know that we're always only using {@code "dyn:*"} operations; also
+ * we're storing flags in an additional primitive field.
+ */
+public class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor {
+    /** Flags that the call site references a scope variable (it's an identifier reference or a var declaration, not a
+     * property access expression. */
+    public static final int CALLSITE_SCOPE                = 0x01;
+    /** Flags that the call site is in code that uses ECMAScript strict mode. */
+    public static final int CALLSITE_STRICT               = 0x02;
+    /** Flags that a property getter or setter call site references a scope variable that is not in the global scope
+     * (it is in a function lexical scope), and the function's scope object class is fixed and known in advance. Such
+     * getters and setters can often be linked more optimally using these assumptions. */
+    public static final int CALLSITE_FAST_SCOPE    = 0x400;
+
+    /** Flags that the call site is profiled; Contexts that have {@code "profile.callsites"} boolean property set emit
+     * code where call sites have this flag set. */
+    public static final int CALLSITE_PROFILE          = 0x10;
+    /** Flags that the call site is traced; Contexts that have {@code "trace.callsites"} property set emit code where
+     * call sites have this flag set. */
+    public static final int CALLSITE_TRACE            = 0x20;
+    /** Flags that the call site linkage miss (and thus, relinking) is traced; Contexts that have the keyword
+     * {@code "miss"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
+    public static final int CALLSITE_TRACE_MISSES     = 0x40;
+    /** Flags that entry/exit to/from the method linked at call site are traced; Contexts that have the keyword
+     * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag
+     * set. */
+    public static final int CALLSITE_TRACE_ENTEREXIT  = 0x80;
+    /** Flags that values passed as arguments to and returned from the method linked at call site are traced; Contexts
+     * that have the keyword {@code "values"} in their {@code "trace.callsites"} property emit code where call sites
+     * have this flag set. */
+    public static final int CALLSITE_TRACE_VALUES    = 0x100;
+    /** Ordinarily, when {@link #CALLSITE_TRACE_VALUES} is set, scope objects are not printed in the trace but instead
+     * the word {@code "SCOPE"} is printed instead With this flag, scope objects are also printed. Contexts that have
+     * the keyword {@code "scope"} in their {@code "trace.callsites"} property emit code where call sites have this flag
+     * set. */
+    public static final int CALLSITE_TRACE_SCOPE      = 0x200;
+
+    private static final WeakHashMap<NashornCallSiteDescriptor, WeakReference<NashornCallSiteDescriptor>> canonicals =
+            new WeakHashMap<>();
+
+    private final String operator;
+    private final String operand;
+    private final MethodType methodType;
+    private final int flags;
+
+    /**
+     * Retrieves a Nashorn call site descriptor with the specified values. Since call site descriptors are immutable
+     * this method is at liberty to retrieve canonicalized instances (although it is not guaranteed it will do so).
+     * @param name the name at the call site, e.g. {@code "dyn:getProp|getElem|getMethod:color"}.
+     * @param methodType the method type at the call site
+     * @param flags Nashorn-specific call site flags
+     * @return a call site descriptor with the specified values.
+     */
+    public static NashornCallSiteDescriptor get(final String name, final MethodType methodType, final int flags) {
+        final String[] tokenizedName = CallSiteDescriptorFactory.tokenizeName(name);
+        assert tokenizedName.length == 2 || tokenizedName.length == 3;
+        assert "dyn".equals(tokenizedName[0]);
+        assert tokenizedName[1] != null;
+        // TODO: see if we can move mangling/unmangling into Dynalink
+        return get(tokenizedName[1], tokenizedName.length == 3 ? tokenizedName[2].intern() : null,
+                methodType, flags);
+    }
+
+    private static NashornCallSiteDescriptor get(final String operator, final String operand, final MethodType methodType, final int flags) {
+        final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(operator, operand, methodType, flags);
+        // Many of these call site descriptors are identical (e.g. every getter for a property color will be
+        // "dyn:getProp:color(Object)Object", so it makes sense canonicalizing them in a weak map
+        synchronized(canonicals) {
+            final WeakReference<NashornCallSiteDescriptor> ref = canonicals.get(csd);
+            if(ref != null) {
+                final NashornCallSiteDescriptor canonical = ref.get();
+                if(canonical != null) {
+                    return canonical;
+                }
+            }
+            canonicals.put(csd, new WeakReference<>(csd));
+        }
+        return csd;
+    }
+
+    private NashornCallSiteDescriptor(final String operator, final String operand, final MethodType methodType, final int flags) {
+        this.operator = operator;
+        this.operand = operand;
+        this.methodType = methodType;
+        this.flags = flags;
+    }
+
+    @Override
+    public int getNameTokenCount() {
+        return operand == null ? 2 : 3;
+    }
+
+    @Override
+    public String getNameToken(final int i) {
+        switch(i) {
+        case 0: return "dyn";
+        case 1: return operator;
+        case 2:
+            if(operand != null) {
+                return operand;
+            }
+            break;
+        default:
+            break;
+        }
+        throw new IndexOutOfBoundsException(String.valueOf(i));
+    }
+
+    @Override
+    public boolean equals(final CallSiteDescriptor csd) {
+        return super.equals(csd) && flags == getFlags(csd);
+    }
+
+    @Override
+    public MethodType getMethodType() {
+        return methodType;
+    }
+
+    /**
+     * Returns the operator (e.g. {@code "getProp"}) in this call site descriptor's name. Equivalent to
+     * {@code getNameToken(CallSiteDescriptor.OPERATOR)}. The returned operator can be composite.
+     * @return the operator in this call site descriptor's name.
+     */
+    public String getOperator() {
+        return operator;
+    }
+
+    /**
+     * Returns the first operator in this call site descriptor's name. E.g. if this call site descriptor has a composite
+     * operation {@code "getProp|getMethod|getElem"}, it will return {@code "getProp"}. Nashorn - being a ECMAScript
+     * engine - does not distinguish between property, element, and method namespace; ECMAScript objects just have one
+     * single property namespace for all these, therefore it is largely irrelevant what the composite operation is
+     * structured like; if the first operation can't be satisfied, neither can the others. The first operation is
+     * however sometimes used to slightly alter the semantics; for example, a distinction between {@code "getProp"} and
+     * {@code "getMethod"} being the first operation can translate into whether {@code "__noSuchProperty__"} or
+     * {@code "__noSuchMethod__"} will be executed in case the property is not found.
+     * @return the first operator in this call site descriptor's name.
+     */
+    public String getFirstOperator() {
+        final int delim = operator.indexOf(CallSiteDescriptor.OPERATOR_DELIMITER);
+        return delim == -1 ? operator : operator.substring(0, delim);
+    }
+
+    /**
+     * Returns the named operand in this descriptor's name. Equivalent to
+     * {@code getNameToken(CallSiteDescriptor.NAME_OPERAND)}. E.g. for operation {@code "dyn:getProp:color"}, returns
+     * {@code "color"}. For call sites without named operands (e.g. {@code "dyn:new"}) returns null.
+     * @return the named operand in this descriptor's name.
+     */
+    public String getOperand() {
+        return operand;
+    }
+
+    /**
+     * Returns the Nashorn-specific flags for this call site descriptor.
+     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
+     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
+     * generated outside of Nashorn.
+     * @return the Nashorn-specific flags for the call site, or 0 if the passed descriptor is not a Nashorn call site
+     * descriptor.
+     */
+    private static int getFlags(final CallSiteDescriptor desc) {
+        return desc instanceof NashornCallSiteDescriptor ? ((NashornCallSiteDescriptor)desc).flags : 0;
+    }
+
+    /**
+     * Returns true if this descriptor has the specified flag set, see {@code CALLSITE_*} constants in this class.
+     * @param flag the tested flag
+     * @return true if the flag is set, false otherwise
+     */
+    private boolean isFlag(final int flag) {
+        return (flags & flag) != 0;
+    }
+
+    /**
+     * Returns true if this descriptor has the specified flag set, see {@code CALLSITE_*} constants in this class.
+     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
+     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
+     * generated outside of Nashorn.
+     * @param flag the tested flag
+     * @return true if the flag is set, false otherwise (it will be false if the decriptor is not a Nashorn call site
+     * descriptor).
+     */
+    private static boolean isFlag(final CallSiteDescriptor desc, final int flag) {
+        return (getFlags(desc) & flag) != 0;
+    }
+
+    /**
+     * Returns true if this descriptor is a Nashorn call site descriptor and has the {@link  #CALLSITE_SCOPE} flag set.
+     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
+     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
+     * generated outside of Nashorn.
+     * @return true if the descriptor is a Nashorn call site descriptor, and the flag is set, false otherwise.
+     */
+    public static boolean isScope(final CallSiteDescriptor desc) {
+        return isFlag(desc, CALLSITE_SCOPE);
+    }
+
+    /**
+     * Returns true if this descriptor is a Nashorn call site descriptor and has the {@link  #CALLSITE_FAST_SCOPE} flag set.
+     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
+     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
+     * generated outside of Nashorn.
+     * @return true if the descriptor is a Nashorn call site descriptor, and the flag is set, false otherwise.
+     */
+    public static boolean isFastScope(final CallSiteDescriptor desc) {
+        return isFlag(desc, CALLSITE_FAST_SCOPE);
+    }
+
+    /**
+     * Returns true if this descriptor is a Nashorn call site descriptor and has the {@link  #CALLSITE_STRICT} flag set.
+     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
+     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
+     * generated outside of Nashorn.
+     * @return true if the descriptor is a Nashorn call site descriptor, and the flag is set, false otherwise.
+     */
+    public static boolean isStrict(final CallSiteDescriptor desc) {
+        return isFlag(desc, CALLSITE_STRICT);
+    }
+
+    boolean isProfile() {
+        return isFlag(CALLSITE_PROFILE);
+    }
+
+    boolean isTrace() {
+        return isFlag(CALLSITE_TRACE);
+    }
+
+    boolean isTraceMisses() {
+        return isFlag(CALLSITE_TRACE_MISSES);
+    }
+
+    boolean isTraceEnterExit() {
+        return isFlag(CALLSITE_TRACE_ENTEREXIT);
+    }
+
+    boolean isTraceObjects() {
+        return isFlag(CALLSITE_TRACE_VALUES);
+    }
+
+    boolean isTraceScope() {
+        return isFlag(CALLSITE_TRACE_SCOPE);
+    }
+
+    @Override
+    public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
+        return get(operator, operand, newMethodType, flags);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java
new file mode 100644
index 0000000..ed15248
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java
@@ -0,0 +1,151 @@
+/*
+ * 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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Constructor of method handles used to guard call sites.
+ */
+public final class NashornGuards {
+    private static final MethodHandle IS_SCRIPTOBJECT          = findOwnMH("isScriptObject", boolean.class, Object.class);
+    private static final MethodHandle IS_SCRIPTFUNCTION        = findOwnMH("isScriptFunction", boolean.class, Object.class);
+    private static final MethodHandle IS_MAP                   = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
+    private static final MethodHandle IS_FUNCTION_MH           = findOwnMH("isFunctionMH", boolean.class, Object.class, MethodHandle.class);
+    private static final MethodHandle IS_NONSTRICT_FUNCTION    = findOwnMH("isNonStrictFunction", boolean.class, Object.class, Object.class, MethodHandle.class);
+    private static final MethodHandle IS_INSTANCEOF_2          = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
+
+    // don't create me!
+    private NashornGuards() {
+    }
+
+    /**
+     * Get the guard that checks if an item is a {@code ScriptObject}
+     * @return method handle for guard
+     */
+    public static MethodHandle getScriptObjectGuard() {
+        return IS_SCRIPTOBJECT;
+    }
+
+    /**
+     * Get the guard that checks if an item is a {@code ScriptFunction}
+     * @return method handle for guard
+     */
+    public static MethodHandle getScriptFunctionGuard() {
+        return IS_SCRIPTFUNCTION;
+    }
+
+    /**
+     * Get the guard that checks if a {@link PropertyMap} is equal to
+     * a known map, using reference comparison
+     *
+     * @param map The map to check against. This will be bound to the guard method handle
+     *
+     * @return method handle for guard
+     */
+    public static MethodHandle getMapGuard(final PropertyMap map) {
+        return MH.insertArguments(IS_MAP, 1, map);
+    }
+
+    /**
+     * Get a guard that checks if in item is an instance of either of two classes.
+     *
+     * @param class1 the first class
+     * @param class2 the second class
+     * @return method handle for guard
+     */
+    public static MethodHandle getInstanceOf2Guard(final Class<?> class1, final Class<?> class2) {
+        return MH.insertArguments(IS_INSTANCEOF_2, 1, class1, class2);
+    }
+
+    /**
+     * Get the guard that checks if a {@link ScriptFunction} is equal to
+     * a known ScriptFunction, using reference comparison
+     *
+     * @param function The ScriptFunction to check against. This will be bound to the guard method handle
+     *
+     * @return method handle for guard
+     */
+    public static MethodHandle getFunctionGuard(final ScriptFunction function) {
+        assert function.getInvokeHandle() != null;
+        return MH.insertArguments(IS_FUNCTION_MH, 1, function.getInvokeHandle());
+    }
+
+    /**
+     * Get a guard that checks if a {@link ScriptFunction} is equal to
+     * a known ScriptFunction using reference comparison, and whether the type of
+     * the second argument (this-object) is not a JavaScript primitive type.
+     *
+     * @param function The ScriptFunction to check against. This will be bound to the guard method handle
+     *
+     * @return method handle for guard
+     */
+    public static MethodHandle getNonStrictFunctionGuard(final ScriptFunction function) {
+        assert function.getInvokeHandle() != null;
+        return MH.insertArguments(IS_NONSTRICT_FUNCTION, 2, function.getInvokeHandle());
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isScriptObject(final Object self) {
+        return self instanceof ScriptObject;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isScriptFunction(final Object self) {
+        return self instanceof ScriptFunction;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isMap(final Object self, final PropertyMap map) {
+        return self instanceof ScriptObject && ((ScriptObject)self).getMap() == map;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isFunctionMH(final Object self, final MethodHandle mh) {
+        return self instanceof ScriptFunction && ((ScriptFunction)self).getInvokeHandle() == mh;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isNonStrictFunction(final Object self, final Object arg, final MethodHandle mh) {
+        return self instanceof ScriptFunction && ((ScriptFunction)self).getInvokeHandle() == mh && arg instanceof ScriptObject;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isInstanceOf2(final Object self, final Class<?> class1, final Class<?> class2) {
+        return class1.isInstance(self) || class2.isInstance(self);
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), NashornGuards.class, name, MH.type(rtype, types));
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
new file mode 100644
index 0000000..3a4a5d7
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
@@ -0,0 +1,166 @@
+/*
+ * 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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.ConversionComparator;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.Guards;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.Undefined;
+
+/**
+ * This is the main dynamic linker for Nashorn. It is used for linking all {@link ScriptObject} and its subclasses (this
+ * includes {@link ScriptFunction} and its subclasses) as well as {@link Undefined}. This linker is exported to other
+ * language runtimes by being declared in {@code META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker}
+ * file of Nashorn's distribution.
+ */
+final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
+    /**
+     * Returns true if {@code ScriptObject} is assignable from {@code type}, or it is {@code Undefined}.
+     */
+    @Override
+    public boolean canLinkType(final Class<?> type) {
+        return canLinkTypeStatic(type);
+    }
+
+    static boolean canLinkTypeStatic(final Class<?> type) {
+        return ScriptObject.class.isAssignableFrom(type) || Undefined.class == type;
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception {
+        final LinkRequest requestWithoutContext = request.withoutRuntimeContext(); // Nashorn has no runtime context
+        final Object self = requestWithoutContext.getReceiver();
+        final CallSiteDescriptor desc = requestWithoutContext.getCallSiteDescriptor();
+
+        if (desc.getNameTokenCount() < 2 || !"dyn".equals(desc.getNameToken(CallSiteDescriptor.SCHEME))) {
+            // We only support standard "dyn:*[:*]" operations
+            return null;
+        }
+
+        final GuardedInvocation inv;
+        if (self instanceof ScriptObject) {
+            inv = ((ScriptObject)self).lookup(desc, request);
+        } else if (self instanceof Undefined) {
+            inv = Undefined.lookup(desc);
+        } else {
+            throw new AssertionError(); // Should never reach here.
+        }
+
+        return Bootstrap.asType(inv, linkerServices, desc);
+    }
+
+    @Override
+    public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
+        final GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType);
+        return gi == null ? null : gi.asType(MH.type(targetType, sourceType));
+    }
+
+    /**
+     * Main part of the implementation of {@link GuardingTypeConverterFactory#convertToType(Class, Class)} that doesn't
+     * care about adapting the method signature; that's done by the invoking method. Returns either a built-in
+     * conversion to primitive (or primitive wrapper) Java types or to String, or a just-in-time generated converter to
+     * a SAM type (if the target type is a SAM type).
+     * @param sourceType the source type
+     * @param targetType the target type
+     * @return a guarded invocation that converts from the source type to the target type.
+     * @throws Exception if something goes wrong
+     */
+    private static GuardedInvocation convertToTypeNoCast(final Class<?> sourceType, final Class<?> targetType) throws Exception {
+        final MethodHandle mh = JavaArgumentConverters.getConverter(targetType);
+        if (mh != null) {
+            return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE);
+        }
+        return getSamTypeConverter(sourceType, targetType);
+    }
+
+    /**
+     * Returns a guarded invocation that converts from a source type that is ScriptFunction, or a subclass or a
+     * superclass of it) to a SAM type.
+     * @param sourceType the source type (presumably ScriptFunction or a subclass or a superclass of it)
+     * @param targetType the target type (presumably a SAM type)
+     * @return a guarded invocation that converts from the source type to the target SAM type. null is returned if
+     * either the source type is neither ScriptFunction, nor a subclass, nor a superclass of it, or if the target type
+     * is not a SAM type.
+     * @throws Exception if something goes wrong; generally, if there's an issue with creation of the SAM proxy type
+     * constructor.
+     */
+    private static GuardedInvocation getSamTypeConverter(final Class<?> sourceType, final Class<?> targetType) throws Exception {
+        // If source type is more generic than ScriptFunction class, we'll need to use a guard
+        final boolean isSourceTypeGeneric = sourceType.isAssignableFrom(ScriptFunction.class);
+
+        if ((isSourceTypeGeneric || ScriptFunction.class.isAssignableFrom(sourceType)) && isAutoConvertibleFromFunction(targetType)) {
+            final MethodHandle ctor = JavaAdapterFactory.getConstructor(ScriptFunction.class, targetType);
+            assert ctor != null; // if isAutoConvertibleFromFunction() returned true, then ctor must exist.
+            return new GuardedInvocation(ctor, isSourceTypeGeneric ? IS_SCRIPT_FUNCTION : null);
+        }
+        return null;
+    }
+
+    private static boolean isAutoConvertibleFromFunction(final Class<?> clazz) {
+        return JavaAdapterFactory.isAbstractClass(clazz) && !ScriptObject.class.isAssignableFrom(clazz) &&
+                JavaAdapterFactory.isAutoConvertibleFromFunction(clazz);
+    }
+
+    @Override
+    public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
+        if(ScriptObject.class.isAssignableFrom(sourceType)) {
+            if(targetType1.isInterface()) {
+                if(!targetType2.isInterface()) {
+                    return Comparison.TYPE_1_BETTER;
+                }
+            } else if(targetType2.isInterface()) {
+                return Comparison.TYPE_2_BETTER;
+            }
+        }
+        return Comparison.INDETERMINATE;
+    }
+
+    private static final MethodHandle IS_SCRIPT_FUNCTION = Guards.isInstance(ScriptFunction.class, MH.type(Boolean.TYPE, Object.class));
+
+    private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined",
+            Boolean.TYPE, Object.class);
+
+    @SuppressWarnings("unused")
+    private static boolean isNashornTypeOrUndefined(final Object obj) {
+        return obj instanceof ScriptObject || obj instanceof Undefined;
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), NashornLinker.class, name, MH.type(rtype, types));
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java
new file mode 100644
index 0000000..ccd95fd
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java
@@ -0,0 +1,175 @@
+/*
+ * 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.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import jdk.internal.dynalink.linker.ConversionComparator;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.TypeUtilities;
+import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.GlobalObject;
+
+/**
+ * Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other
+ * 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.
+ */
+final class NashornPrimitiveLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
+    @Override
+    public boolean canLinkType(final Class<?> type) {
+        return canLinkTypeStatic(type);
+    }
+
+    private static boolean canLinkTypeStatic(final Class<?> type) {
+        return type == String.class || type == Boolean.class || type == ConsString.class || Number.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(final LinkRequest origRequest, final LinkerServices linkerServices)
+            throws Exception {
+        final LinkRequest request = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
+
+        final Object self = request.getReceiver();
+        final GlobalObject global = (GlobalObject) Context.getGlobal();
+        final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor();
+
+        return Bootstrap.asType(global.primitiveLookup(request, self), linkerServices, desc);
+    }
+
+    /**
+     * This implementation of type converter factory will pretty much allow implicit conversions of anything to anything
+     * else that's allowed among JavaScript primitive types (string to number, boolean to string, etc.)
+     * @param sourceType the type to convert from
+     * @param targetType the type to convert to
+     * @return a conditional converter from source to target type
+     */
+    @Override
+    public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) {
+        final MethodHandle mh = JavaArgumentConverters.getConverter(targetType);
+        if (mh == null) {
+            return null;
+        }
+
+        return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : GUARD_PRIMITIVE).asType(mh.type().changeParameterType(0, sourceType));
+    }
+
+    /**
+     * Implements the somewhat involved prioritization of JavaScript primitive types conversions. Instead of explaining
+     * it here in prose, just follow the source code comments.
+     * @param sourceType the source type to convert from
+     * @param targetType1 one candidate target type
+     * @param targetType2 another candidate target type
+     * @return one of {@link jdk.internal.dynalink.linker.ConversionComparator.Comparison} values signifying which
+     * target type should be favored for conversion.
+     */
+    @Override
+    public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
+        final Class<?> wrapper1 = getWrapperTypeOrSelf(targetType1);
+        if (sourceType == wrapper1) {
+            // Source type exactly matches target 1
+            return Comparison.TYPE_1_BETTER;
+        }
+        final Class<?> wrapper2 = getWrapperTypeOrSelf(targetType2);
+        if (sourceType == wrapper2) {
+            // Source type exactly matches target 2
+            return Comparison.TYPE_2_BETTER;
+        }
+
+        if (Number.class.isAssignableFrom(sourceType)) {
+            // If exactly one of the targets is a number, pick it.
+            if (Number.class.isAssignableFrom(wrapper1)) {
+                if (!Number.class.isAssignableFrom(wrapper2)) {
+                    return Comparison.TYPE_1_BETTER;
+                }
+            } else if (Number.class.isAssignableFrom(wrapper2)) {
+                return Comparison.TYPE_2_BETTER;
+            }
+
+            // If exactly one of the targets is a character, pick it. Numbers can be reasonably converted to chars using
+            // the UTF-16 values.
+            if (Character.class == wrapper1) {
+                return Comparison.TYPE_1_BETTER;
+            } else if (Character.class == wrapper2) {
+                return Comparison.TYPE_2_BETTER;
+            }
+
+            // For all other cases, we fall through to the next if statement - not that we repeat the condition in it
+            // too so if we entered this branch, we'll enter the below if statement too.
+        }
+
+        if (sourceType == String.class || sourceType == Boolean.class || Number.class.isAssignableFrom(sourceType)) {
+            // Treat wrappers as primitives.
+            final Class<?> primitiveType1 = getPrimitiveTypeOrSelf(targetType1);
+            final Class<?> primitiveType2 = getPrimitiveTypeOrSelf(targetType2);
+            // Basically, choose the widest possible primitive type. (First "if" returning TYPE_2_BETTER is correct;
+            // when faced with a choice between double and int, choose double).
+            if (TypeUtilities.isMethodInvocationConvertible(primitiveType1, primitiveType2)) {
+                return Comparison.TYPE_2_BETTER;
+            } else if (TypeUtilities.isMethodInvocationConvertible(primitiveType2, primitiveType1)) {
+                return Comparison.TYPE_1_BETTER;
+            }
+            // Ok, at this point we're out of possible number conversions, so try strings. A String can represent any
+            // value without loss, so if one of the potential targets is string, go for it.
+            if (targetType1 == String.class) {
+                return Comparison.TYPE_1_BETTER;
+            }
+            if (targetType2 == String.class) {
+                return Comparison.TYPE_2_BETTER;
+            }
+        }
+
+        return Comparison.INDETERMINATE;
+    }
+
+    private static Class<?> getPrimitiveTypeOrSelf(final Class<?> type) {
+        final Class<?> primitive = TypeUtilities.getPrimitiveType(type);
+        return primitive == null ? type : primitive;
+    }
+
+    private static Class<?> getWrapperTypeOrSelf(final Class<?> type) {
+        final Class<?> wrapper = TypeUtilities.getWrapperType(type);
+        return wrapper == null ? type : wrapper;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isJavaScriptPrimitive(final Object o) {
+        return o instanceof String || o instanceof Boolean || o instanceof Number || o instanceof ConsString || o == null;
+    }
+
+    private static final MethodHandle GUARD_PRIMITIVE = findOwnMH("isJavaScriptPrimitive", boolean.class, Object.class);
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), NashornPrimitiveLinker.class, name, MH.type(rtype, types));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
new file mode 100644
index 0000000..738162d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
@@ -0,0 +1,100 @@
+/*
+ * 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 jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.beans.StaticClass;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.Guards;
+import jdk.nashorn.internal.runtime.ECMAErrors;
+
+/**
+ * Internal linker for {@link StaticClass} objects, only ever used by Nashorn engine and not exposed to other engines.
+ * It is used for extending the "new" operator on StaticClass in order to be able to instantiate interfaces and abstract
+ * classes by passing a ScriptObject or ScriptFunction as their implementation, e.g.:
+ * <pre>
+ *   var r = new Runnable() { run: function() { print("Hello World" } }
+ * </pre>
+ * or for SAM types, even just passing a function:
+ * <pre>
+ *   var r = new Runnable(function() { print("Hello World" })
+ * </pre>
+ */
+final class NashornStaticClassLinker implements TypeBasedGuardingDynamicLinker {
+    private static final GuardingDynamicLinker staticClassLinker = BeansLinker.getLinkerForClass(StaticClass.class);
+
+    @Override
+    public boolean canLinkType(Class<?> type) {
+        return type == StaticClass.class;
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) throws Exception {
+        final LinkRequest request = linkRequest.withoutRuntimeContext(); // Nashorn has no runtime context
+        final Object self = request.getReceiver();
+        if (self.getClass() != StaticClass.class) {
+            return null;
+        }
+        final CallSiteDescriptor desc = request.getCallSiteDescriptor();
+        // We intercept "new" on StaticClass instances to provide additional capabilities
+        if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
+            final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();
+            // Is the class abstract? (This includes interfaces.)
+            if (JavaAdapterFactory.isAbstractClass(receiverClass)) {
+                // Change this link request into a link request on the adapter class.
+                final Object[] args = request.getArguments();
+                args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass });
+                final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
+                final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
+                // Finally, modify the guard to test for the original abstract class.
+                return gi.replaceMethods(gi.getInvocation(), Guards.getIdentityGuard(self));
+            }
+            // If the class was not abstract, just delegate linking to the standard StaticClass linker. Make an
+            // additional check to ensure we have a constructor. We could just fall through to the next "return"
+            // statement, except we also insert a call to checkNullConstructor() which throws an ECMAScript TypeError
+            // with a more intuitive message when no suitable constructor is found.
+            return checkNullConstructor(delegate(linkerServices, request), receiverClass);
+        }
+        // In case this was not a "new" operation, just delegate to the the standard StaticClass linker.
+        return delegate(linkerServices, request);
+    }
+
+    private static GuardedInvocation delegate(LinkerServices linkerServices, final LinkRequest request) throws Exception {
+        return staticClassLinker.getGuardedInvocation(request, linkerServices);
+    }
+
+    private static GuardedInvocation checkNullConstructor(final GuardedInvocation ctorInvocation, final Class<?> receiverClass) {
+        if(ctorInvocation == null) {
+            throw ECMAErrors.typeError("no.constructor.matches.args", receiverClass.getName());
+        }
+        return ctorInvocation;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
new file mode 100644
index 0000000..968dba9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
@@ -0,0 +1,115 @@
+/*
+ * 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 jdk.nashorn.internal.lookup.Lookup;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.internal.dynalink.support.Guards;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Implements lookup of methods to link for dynamic operations on JavaScript primitive values (booleans, strings, and
+ * numbers). This class is only public so it can be accessed by classes in the {@code jdk.nashorn.internal.objects}
+ * package.
+ */
+public class PrimitiveLookup {
+
+    private PrimitiveLookup() {
+    }
+
+    /**
+     * Returns a guarded invocation representing the linkage for a dynamic operation on a primitive Java value.
+     * @param request the link request for the dynamic call site.
+     * @param receiverClass the class of the receiver value (e.g., {@link java.lang.Boolean}, {@link java.lang.String} etc.)
+     * @param wrappedReceiver a transient JavaScript native wrapper object created as the object proxy for the primitive
+     * value; see ECMAScript 5.1, section 8.7.1 for discussion of using {@code [[Get]]} on a property reference with a
+     * primitive base value. This instance will be used to delegate actual lookup.
+     * @param wrapFilter A method handle that takes a primitive value of type specified in the {@code receiverClass} and
+     * creates a transient native wrapper of the same type as {@code wrappedReceiver} for subsequent invocations of the
+     * method - it will be combined into the returned invocation as an argument filter on the receiver.
+     * @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
+     * type {@code receiverClass}.
+     */
+    public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class<?> receiverClass,
+                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
+        return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter);
+    }
+
+    /**
+     * Returns a guarded invocation representing the linkage for a dynamic operation on a primitive Java value.
+     * @param request the link request for the dynamic call site.
+     * @param guard an explicit guard that will be used for the returned guarded invocation.
+     * @param wrappedReceiver a transient JavaScript native wrapper object created as the object proxy for the primitive
+     * value; see ECMAScript 5.1, section 8.7.1 for discussion of using {@code [[Get]]} on a property reference with a
+     * primitive base value. This instance will be used to delegate actual lookup.
+     * @param wrapFilter A method handle that takes a primitive value of type guarded by the {@code guard} and
+     * creates a transient native wrapper of the same type as {@code wrappedReceiver} for subsequent invocations of the
+     * method - it will be combined into the returned invocation as an argument filter on the receiver.
+     * @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
+     * type (that is implied by both {@code guard} and {@code wrappedReceiver}).
+     */
+    public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
+                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
+        final CallSiteDescriptor desc = request.getCallSiteDescriptor();
+        final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
+        if ("setProp".equals(operator) || "setElem".equals(operator)) {
+            MethodType type = desc.getMethodType();
+            MethodHandle method = MH.asType(Lookup.EMPTY_SETTER, MH.type(void.class, Object.class, type.parameterType(1)));
+            if (type.parameterCount() == 3) {
+                method = MH.dropArguments(method, 2, type.parameterType(2));
+            }
+            return new GuardedInvocation(method, guard);
+        }
+
+        if(desc.getNameTokenCount() > 2) {
+            final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+            if(wrappedReceiver.findProperty(name, true) == null) {
+                // Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
+                return null;
+            }
+        }
+        final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
+        if (link != null) {
+            MethodHandle method = link.getInvocation();
+            final Class<?> receiverType = method.type().parameterType(0);
+            if (receiverType != Object.class) {
+                final MethodType wrapType = wrapFilter.type();
+                assert receiverType.isAssignableFrom(wrapType.returnType());
+                method = MH.filterArguments(method, 0, MH.asType(wrapFilter, wrapType.changeReturnType(receiverType)));
+            }
+            return new GuardedInvocation(method, guard, link.getSwitchPoint());
+        }
+        assert desc.getNameTokenCount() <= 2; // Named operations would hit the return null after findProperty
+        return null;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/KeyValueOption.java b/nashorn/src/jdk/nashorn/internal/runtime/options/KeyValueOption.java
new file mode 100644
index 0000000..aee6caf
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/KeyValueOption.java
@@ -0,0 +1,93 @@
+/*
+ * 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.options;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * Key Value option such as logger. It comes on the format
+ * such as:
+ *
+ * {@code --log=module1:level1,module2:level2... }
+ */
+public class KeyValueOption extends Option<String> {
+    /**
+     * Map of keys given
+     */
+    protected Map<String, String> map;
+
+    KeyValueOption(final String value) {
+        super(value);
+        initialize();
+    }
+
+    Map<String, String> getValues() {
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Check if the key value option has a value or if it has not
+     * been initialized
+     * @param key the key
+     * @return value, or null if not initialized
+     */
+    public boolean hasValue(final String key) {
+        return map != null && map.get(key) != null;
+    }
+
+    String getValue(final String key) {
+        if (map == null) {
+            return null;
+        }
+        final String val = map.get(key);
+        return "".equals(val) ? null : val;
+    }
+
+    private void initialize() {
+        if (getValue() == null) {
+            return;
+        }
+
+        map = new LinkedHashMap<>();
+
+        final StringTokenizer st = new StringTokenizer(getValue(), ",");
+        while (st.hasMoreElements()) {
+            final String   token    = st.nextToken();
+            final String[] keyValue = token.split(":");
+
+            if (keyValue.length == 1) {
+                map.put(keyValue[0], "");
+            } else if (keyValue.length == 2) {
+                map.put(keyValue[0], keyValue[1]);
+            } else {
+                throw new IllegalArgumentException(token);
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/Option.java b/nashorn/src/jdk/nashorn/internal/runtime/options/Option.java
new file mode 100644
index 0000000..ddbeba1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Option.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.options;
+
+/**
+ * This is an option class that at its most primitive level just wraps a
+ * boolean or String. However, it is conceivable that the option, when set
+ * should run some initializations (for example, the logger system) or carry
+ * some other kind of payload, arrays, Collections, etc. In that case, this
+ * should be subclassed
+ *
+ * @param <T> option value type, for example a boolean or something more complex
+ */
+public class Option<T> {
+    /** the option value */
+    protected T value;
+
+    Option(final T value) {
+       this.value = value;
+    }
+
+    void setValue(final T value) {
+        this.value = value;
+    }
+
+    /**
+     * Return the value of an option
+     * @return the option value
+     */
+    public T getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return getValue() + " [" + getValue().getClass() + "]";
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java b/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java
new file mode 100644
index 0000000..82b6edb
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java
@@ -0,0 +1,367 @@
+/*
+ * 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.options;
+
+import java.util.TimeZone;
+import jdk.nashorn.internal.runtime.QuotedStringTokenizer;
+
+/**
+ * This describes the valid input for an option, as read from the resource
+ * bundle file. Metainfo such as parameters and description is here as well
+ * for context sensitive help generation.
+ */
+public class OptionTemplate implements Comparable<OptionTemplate> {
+    /** Resource, e.g. "nashorn" for this option */
+    private final String resource;
+
+    /** Key in the resource bundle */
+    private final String key;
+
+    /** Is this option a help option? */
+    private final boolean isHelp;
+
+    /** Is this option a extended help option? */
+    private final boolean isXHelp;
+
+    /** Name - for example --dump-on-error (usually prefixed with --) */
+    private String name;
+
+    /** Short name - for example -doe (usually prefixed with -) */
+    private String shortName;
+
+    /** Params - a parameter template string */
+    private String params;
+
+    /** Type - e.g. "boolean". */
+    private String type;
+
+    /** Does this option have a default value? */
+    private String defaultValue;
+
+    /** Does this option activate another option when set? */
+    private String dependency;
+
+    /** Does this option conflict with another? */
+    private String conflict;
+
+    /** Is this a documented option that should show up in help? */
+    private boolean isUndocumented;
+
+    /** A longer description of what this option does */
+    private String description;
+
+    /** is the option value specified as next argument? */
+    private boolean valueNextArg;
+
+    OptionTemplate(final String resource, final String key, final String value, final boolean isHelp, final boolean isXHelp) {
+        this.resource = resource;
+        this.key = key;
+        this.isHelp = isHelp;
+        this.isXHelp = isXHelp;
+        parse(value);
+    }
+
+    /**
+     * Is this the special help option, used to generate help for
+     * all the others
+     *
+     * @return true if this is the help option
+     */
+    public boolean isHelp() {
+        return this.isHelp;
+    }
+
+    /**
+     * Is this the special extended help option, used to generate extended help for
+     * all the others
+     *
+     * @return true if this is the extended help option
+     */
+    public boolean isXHelp() {
+        return this.isXHelp;
+    }
+
+    /**
+     * Get the resource name used to prefix this option set, e.g. "nashorn"
+     *
+     * @return the name of the resource
+     */
+    public String getResource() {
+        return this.resource;
+    }
+
+    /**
+     * Get the type of this option
+     *
+     * @return the type of the option
+     */
+    public String getType() {
+        return this.type;
+    }
+
+    /**
+     * Get the key of this option
+     *
+     * @return the key
+     */
+    public String getKey() {
+        return this.key;
+    }
+
+    /**
+     * Get the default value for this option
+     *
+     * @return the default value as a string
+     */
+    public String getDefaultValue() {
+        switch (getType()) {
+        case "boolean":
+            if (this.defaultValue == null) {
+                this.defaultValue = "false";
+            }
+            break;
+        case "integer":
+            if (this.defaultValue == null) {
+                this.defaultValue = "0";
+            }
+            break;
+        case "timezone":
+            this.defaultValue = TimeZone.getDefault().getID();
+            break;
+        default:
+            break;
+        }
+        return this.defaultValue;
+    }
+
+    /**
+     * Does this option automatically enable another option, i.e. a dependency.
+     * @return the dependecy or null if non exists
+     */
+    public String getDependency() {
+        return this.dependency;
+    }
+
+    /**
+     * Is this option in conflict with another option so that both can't be enabled
+     * at the same time
+     *
+     * @return the conflicting option or null if none exists
+     */
+    public String getConflict() {
+        return this.conflict;
+    }
+
+    /**
+     * Is this option undocumented, i.e. should not show up in the standard help output
+     *
+     * @return true if option is undocumented
+     */
+    public boolean isUndocumented() {
+        return this.isUndocumented;
+    }
+
+    /**
+     * Get the short version of this option name if one exists, e.g. "-co" for "--compile-only"
+     *
+     * @return the short name
+     */
+    public String getShortName() {
+        return this.shortName;
+    }
+
+    /**
+     * Get the name of this option, e.g. "--compile-only". A name always exists
+     *
+     * @return the name of the option
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * Get the description of this option.
+     *
+     * @return the description
+     */
+    public String getDescription() {
+        return this.description;
+    }
+
+    /**
+     * Is value of this option passed as next argument?
+     * @return boolean
+     */
+    public boolean isValueNextArg() {
+        return valueNextArg;
+    }
+
+    private static String strip(final String value, final char start, final char end) {
+        final int len = value.length();
+        if (len > 1 && value.charAt(0) == start && value.charAt(len - 1) == end) {
+            return value.substring(1, len - 1);
+        }
+        return null;
+    }
+
+    private void parse(final String origValue) {
+        String value = origValue.trim();
+
+        try {
+            value = OptionTemplate.strip(value, '{', '}');
+            final QuotedStringTokenizer keyValuePairs = new QuotedStringTokenizer(value, ",");
+
+            while (keyValuePairs.hasMoreTokens()) {
+                final String                keyValue = keyValuePairs.nextToken();
+                final QuotedStringTokenizer st       = new QuotedStringTokenizer(keyValue, "=");
+                final String                keyToken = st.nextToken();
+                final String                arg      = st.nextToken();
+
+                switch (keyToken) {
+                case "is_undocumented":
+                    this.isUndocumented = Boolean.parseBoolean(arg);
+                    break;
+                case "name":
+                    if (!arg.startsWith("-")) {
+                        throw new IllegalArgumentException(arg);
+                    }
+                    this.name = arg;
+                    break;
+                case "short_name":
+                    if (!arg.startsWith("-")) {
+                        throw new IllegalArgumentException(arg);
+                    }
+                    this.shortName = arg;
+                    break;
+                case "desc":
+                    this.description = arg;
+                    break;
+                case "params":
+                    this.params = arg;
+                    break;
+                case "type":
+                    this.type = arg.toLowerCase();
+                    break;
+                case "default":
+                    this.defaultValue = arg;
+                    break;
+                case "dependency":
+                    this.dependency = arg;
+                    break;
+                case "conflict":
+                    this.conflict = arg;
+                    break;
+                case "value_next_arg":
+                    this.valueNextArg = Boolean.parseBoolean(arg);
+                    break;
+                default:
+                    throw new IllegalArgumentException();
+                }
+            }
+
+            // default to boolean if no type is given
+            if (this.type == null) {
+                this.type = "boolean";
+            }
+
+            if (this.params == null && "boolean".equals(this.type)) {
+                this.params = "[true|false]";
+            }
+
+        } catch (final Exception e) {
+            throw new IllegalArgumentException(origValue);
+        }
+
+        if (name == null && shortName == null) {
+            throw new IllegalArgumentException(origValue);
+        }
+    }
+
+    boolean matches(final String key0) {
+        return key0.equals(this.shortName) || key0.equals(this.name);
+    }
+
+    private static final int LINE_BREAK = 64;
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+
+        sb.append('\t');
+
+        if (shortName != null) {
+            sb.append(shortName);
+            if (name != null) {
+                sb.append(", ");
+            }
+        }
+
+        if (name != null) {
+            sb.append(name);
+        }
+
+        if (description != null) {
+            final int indent = sb.length();
+            sb.append(' ');
+            sb.append('(');
+            int pos = 0;
+            for (final char c : description.toCharArray()) {
+                sb.append(c);
+                pos++;
+                if (pos >= LINE_BREAK && Character.isWhitespace(c)) {
+                    pos = 0;
+                    sb.append("\n\t");
+                    for (int i = 0; i < indent; i++) {
+                        sb.append(' ');
+                    }
+                }
+            }
+            sb.append(')');
+        }
+
+        if (params != null) {
+            sb.append('\n');
+            sb.append('\t');
+            sb.append('\t');
+            sb.append(Options.getMsg("nashorn.options.param")).append(": ");
+            sb.append(params);
+            sb.append("   ");
+            final Object def = this.getDefaultValue();
+            if (def != null) {
+                sb.append(Options.getMsg("nashorn.options.default")).append(": ");
+                sb.append(this.getDefaultValue());
+            }
+        }
+
+
+        return sb.toString();
+    }
+
+    @Override
+    public int compareTo(final OptionTemplate o) {
+        return this.getKey().compareTo(o.getKey());
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
new file mode 100644
index 0000000..0f30b1a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
@@ -0,0 +1,658 @@
+/*
+ * 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.options;
+
+import java.io.PrintWriter;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import jdk.nashorn.internal.runtime.Logging;
+import jdk.nashorn.internal.runtime.QuotedStringTokenizer;
+
+/**
+ * Manages global runtime options.
+ */
+public final class Options {
+    /** Resource tag. */
+    private final String resource;
+
+    /** Error writer. */
+    private final PrintWriter err;
+
+    /** File list. */
+    private final List<String> files;
+
+    /** Arguments list */
+    private final List<String> arguments;
+
+    /** The options map of enabled options */
+    private final TreeMap<String, Option<?>> options;
+
+    /**
+     * Constructor
+     *
+     * Options will use System.err as the output stream for any errors
+     *
+     * @param resource resource prefix for options e.g. "nashorn"
+     */
+    public Options(final String resource) {
+        this(resource, new PrintWriter(System.err, true));
+    }
+
+    /**
+     * Constructor
+     *
+     * @param resource resource prefix for options e.g. "nashorn"
+     * @param err      error stream for reporting parse errors
+     */
+    public Options(final String resource, final PrintWriter err) {
+        this.resource  = resource;
+        this.err       = err;
+        this.files     = new ArrayList<>();
+        this.arguments = new ArrayList<>();
+        this.options   = new TreeMap<>();
+
+        // set all default values
+        for (final OptionTemplate t : Options.validOptions) {
+            if (t.getDefaultValue() != null) {
+                // populate from system properties
+                final String v = getStringProperty(t.getKey(), null);
+                if (v != null) {
+                    set(t.getKey(), createOption(t, v));
+                } else if (t.getDefaultValue() != null) {
+                    set(t.getKey(), createOption(t, t.getDefaultValue()));
+                 }
+            }
+        }
+    }
+
+    /**
+     * Get the resource for this Options set, e.g. "nashorn"
+     * @return the resource
+     */
+    public String getResource() {
+        return resource;
+    }
+
+    @Override
+    public String toString() {
+        return options.toString();
+    }
+
+    /**
+     * Convenience function for getting system properties in a safe way
+
+     * @param name of boolean property
+     * @return true if set to true, false if unset or set to false
+     */
+    public static boolean getBooleanProperty(final String name) {
+        name.getClass(); // null check
+        if (!name.startsWith("nashorn.")) {
+            throw new IllegalArgumentException(name);
+        }
+
+        return AccessController.doPrivileged(
+                new PrivilegedAction<Boolean>() {
+                    @Override
+                    public Boolean run() {
+                        try {
+                            final String property = System.getProperty(name);
+                            return property != null && !"false".equalsIgnoreCase(property);
+                        } catch (final SecurityException e) {
+                            // if no permission to read, assume false
+                            return false;
+                        }
+                    }
+                });
+    }
+
+    /**
+     * Convenience function for getting system properties in a safe way
+     *
+     * @param name of string property
+     * @param defValue the default value if unset
+     * @return string property if set or default value
+     */
+    public static String getStringProperty(final String name, final String defValue) {
+        name.getClass(); // null check
+        if (! name.startsWith("nashorn.")) {
+            throw new IllegalArgumentException(name);
+        }
+
+        return AccessController.doPrivileged(
+                new PrivilegedAction<String>() {
+                    @Override
+                    public String run() {
+                        try {
+                            return System.getProperty(name, defValue);
+                        } catch (final SecurityException e) {
+                            // if no permission to read, assume the default value
+                            return defValue;
+                        }
+                    }
+                });
+    }
+
+    /**
+     * Convenience function for getting system properties in a safe way
+     *
+     * @param name of integer property
+     * @param defValue the default value if unset
+     * @return integer property if set or default value
+     */
+    public static int getIntProperty(final String name, final int defValue) {
+        name.getClass(); // null check
+        if (! name.startsWith("nashorn.")) {
+            throw new IllegalArgumentException(name);
+        }
+
+        return AccessController.doPrivileged(
+                new PrivilegedAction<Integer>() {
+                    @Override
+                    public Integer run() {
+                        try {
+                            return Integer.getInteger(name, defValue);
+                        } catch (final SecurityException e) {
+                            // if no permission to read, assume the default value
+                            return defValue;
+                        }
+                    }
+                });
+    }
+
+    /**
+     * Return an option given its resource key. If the key doesn't begin with
+     * {@literal <resource>}.option it will be completed using the resource from this
+     * instance
+     *
+     * @param key key for option
+     * @return an option value
+     */
+    public Option<?> get(final String key) {
+        return options.get(key(key));
+    }
+
+    /**
+     * Return an option as a boolean
+     *
+     * @param key key for option
+     * @return an option value
+     */
+    public boolean getBoolean(final String key) {
+        final Option<?> option = get(key);
+        return option != null ? (Boolean)option.getValue() : false;
+    }
+
+    /**
+     * Return an option as a integer
+     *
+     * @param key key for option
+     * @return an option value
+     */
+    public int getInteger(final String key) {
+        final Option<?> option = get(key);
+        return option != null ? (Integer)option.getValue() : 0;
+    }
+
+    /**
+     * Return an option as a String
+     *
+     * @param key key for option
+     * @return an option value
+     */
+    public String getString(final String key) {
+        final Option<?> option = get(key);
+        return option != null ? (String)option.getValue() : null;
+    }
+
+    /**
+     * Set an option, overwriting an existing state if one exists
+     *
+     * @param key    option key
+     * @param option option
+     */
+    public void set(final String key, final Option<?> option) {
+        options.put(key(key), option);
+    }
+
+    /**
+     * Set an option as a boolean value, overwriting an existing state if one exists
+     *
+     * @param key    option key
+     * @param option option
+     */
+    public void set(final String key, final boolean option) {
+        set(key, new Option<>(option));
+    }
+
+    /**
+     * Set an option as a String value, overwriting an existing state if one exists
+     *
+     * @param key    option key
+     * @param option option
+     */
+    public void set(final String key, final String option) {
+        set(key, new Option<>(option));
+    }
+
+    /**
+     * Return the user arguments to the program, i.e. those trailing "--" after
+     * the filename
+     *
+     * @return a list of user arguments
+     */
+    public List<String> getArguments() {
+        return Collections.unmodifiableList(this.arguments);
+    }
+
+    /**
+     * Return the JavaScript files passed to the program
+     *
+     * @return a list of files
+     */
+    public List<String> getFiles() {
+        return Collections.unmodifiableList(files);
+    }
+
+    /**
+     * Return the option templates for all the valid option supported.
+     *
+     * @return a collection of OptionTemplate objects.
+     */
+    public static Collection<OptionTemplate> getValidOptions() {
+        return Collections.unmodifiableCollection(validOptions);
+    }
+
+    /**
+     * Make sure a key is fully qualified for table lookups
+     *
+     * @param shortKey key for option
+     * @return fully qualified key
+     */
+    private String key(final String shortKey) {
+        String key = shortKey;
+        while (key.startsWith("-")) {
+            key = key.substring(1, key.length());
+        }
+        key = key.replace("-", ".");
+        final String keyPrefix = this.resource + ".option.";
+        if (key.startsWith(keyPrefix)) {
+            return key;
+        }
+        return keyPrefix + key;
+    }
+
+    static String getMsg(final String msgId, final String... args) {
+        try {
+            final String msg = Options.bundle.getString(msgId);
+            if (args.length == 0) {
+                return msg;
+            }
+            return new MessageFormat(msg).format(args);
+        } catch (final MissingResourceException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Display context sensitive help
+     *
+     * @param e  exception that caused a parse error
+     */
+    public void displayHelp(final IllegalArgumentException e) {
+        if (e instanceof IllegalOptionException) {
+            final OptionTemplate template = ((IllegalOptionException)e).getTemplate();
+            if (template.isXHelp()) {
+                // display extended help information
+                displayHelp(true);
+            } else {
+                err.println(((IllegalOptionException)e).getTemplate());
+            }
+            return;
+        }
+
+        if (e != null && e.getMessage() != null) {
+            err.println(getMsg("option.error.invalid.option",
+                    e.getMessage(),
+                    helpOptionTemplate.getShortName(),
+                    helpOptionTemplate.getName()));
+            err.println();
+            return;
+        }
+
+        displayHelp(false);
+    }
+
+    /**
+     * Display full help
+     *
+     * @param extended show the extended help for all options, including undocumented ones
+     */
+    public void displayHelp(final boolean extended) {
+        for (final OptionTemplate t : Options.validOptions) {
+            if ((extended || !t.isUndocumented()) && t.getResource().equals(resource)) {
+                err.println(t);
+                err.println();
+            }
+        }
+    }
+
+    /**
+     * Processes the arguments and stores their information. Throws
+     * IllegalArgumentException on error. The message can be analyzed by the
+     * displayHelp function to become more context sensitive
+     *
+     * @param args arguments from command line
+     */
+    public void process(final String[] args) {
+        final LinkedList<String> argList = new LinkedList<>();
+        Collections.addAll(argList, args);
+
+        while (!argList.isEmpty()) {
+            final String arg = argList.remove(0);
+
+            // skip empty args
+            if (arg.isEmpty()) {
+                continue;
+            }
+
+            // user arguments to the script
+            if ("--".equals(arg)) {
+                arguments.addAll(argList);
+                argList.clear();
+                continue;
+            }
+
+            // if it doesn't start with -, it's a file
+            if (!arg.startsWith("-")) {
+                files.add(arg);
+                continue;
+            }
+
+            if (arg.startsWith(definePropPrefix)) {
+                final String value = arg.substring(definePropPrefix.length());
+                final int eq = value.indexOf('=');
+                if (eq != -1) {
+                    // -Dfoo=bar Set System property "foo" with value "bar"
+                    System.setProperty(value.substring(0, eq), value.substring(eq + 1));
+                } else {
+                    // -Dfoo is fine. Set System property "foo" with "" as it's value
+                    if (!value.isEmpty()) {
+                        System.setProperty(value, "");
+                    } else {
+                        // do not allow empty property name
+                        throw new IllegalOptionException(definePropTemplate);
+                    }
+                }
+                continue;
+            }
+
+            // it is an argument,  it and assign key, value and template
+            final ParsedArg parg = new ParsedArg(arg);
+
+            // check if the value of this option is passed as next argument
+            if (parg.template.isValueNextArg()) {
+                if (argList.isEmpty()) {
+                    throw new IllegalOptionException(parg.template);
+                }
+                parg.value = argList.remove(0);
+            }
+
+            // -h [args...]
+            if (parg.template.isHelp()) {
+                // check if someone wants help on an explicit arg
+                if (!argList.isEmpty()) {
+                    try {
+                        final OptionTemplate t = new ParsedArg(argList.get(0)).template;
+                        throw new IllegalOptionException(t);
+                    } catch (final IllegalArgumentException e) {
+                        throw e;
+                    }
+                }
+                throw new IllegalArgumentException(); // show help for
+                // everything
+            }
+
+            if (parg.template.isXHelp()) {
+                throw new IllegalOptionException(parg.template);
+            }
+
+            set(parg.template.getKey(), createOption(parg.template, parg.value));
+
+            // Arg may have a dependency to set other args, e.g.
+            // scripting->anon.functions
+            if (parg.template.getDependency() != null) {
+                argList.addFirst(parg.template.getDependency());
+            }
+        }
+    }
+
+    private static OptionTemplate getOptionTemplate(final String key) {
+        for (final OptionTemplate t : Options.validOptions) {
+            if (t.matches(key)) {
+                return t;
+            }
+        }
+        return null;
+    }
+
+    private static Option<?> createOption(final OptionTemplate t, final String value) {
+        switch (t.getType()) {
+        case "string":
+            // default value null
+            return new Option<>(value);
+        case "timezone":
+            // default value "TimeZone.getDefault()"
+            return new Option<>(TimeZone.getTimeZone(value));
+        case "keyvalues":
+            return new KeyValueOption(value);
+        case "values":
+            return new ValueOption(value);
+        case "log":
+            final KeyValueOption kv = new KeyValueOption(value);
+            Logging.initialize(kv.getValues());
+            return kv;
+        case "boolean":
+            return new Option<>(value != null && Boolean.parseBoolean(value));
+        case "integer":
+            try {
+                return new Option<>((value == null) ? 0 : Integer.parseInt(value));
+            } catch (final NumberFormatException nfe) {
+                throw new IllegalOptionException(t);
+            }
+        case "properties":
+            //swallow the properties and set them
+            initProps(new KeyValueOption(value));
+            return null;
+        default:
+            break;
+        }
+        throw new IllegalArgumentException(value);
+    }
+
+    private static void initProps(final KeyValueOption kv) {
+        for (final Map.Entry<String, String> entry : kv.getValues().entrySet()) {
+            System.setProperty(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Resource name for properties file
+     */
+    private static final String MESSAGES_RESOURCE = "jdk.nashorn.internal.runtime.resources.Options";
+
+    /**
+     * Resource bundle for properties file
+     */
+    private static ResourceBundle bundle;
+
+    /**
+     * Usages per resource from properties file
+     */
+    private static HashMap<Object, Object> usage;
+
+    /**
+     * Valid options from templates in properties files
+     */
+    private static Collection<OptionTemplate> validOptions;
+
+    /**
+     * Help option
+     */
+    private static OptionTemplate helpOptionTemplate;
+
+    /**
+     * Define property option template.
+     */
+    private static OptionTemplate definePropTemplate;
+
+    /**
+     * Prefix of "define property" option.
+     */
+    private static String definePropPrefix;
+
+    static {
+        // Without do privileged, under security manager messages can not be
+        // loaded.
+        Options.bundle = AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
+            @Override
+            public ResourceBundle run() {
+                return ResourceBundle.getBundle(Options.MESSAGES_RESOURCE, Locale.getDefault());
+            }
+        });
+
+        Options.validOptions = new TreeSet<>();
+        Options.usage        = new HashMap<>();
+
+        for (final Enumeration<String> keys = Options.bundle.getKeys(); keys.hasMoreElements(); ) {
+            final String key = keys.nextElement();
+            final StringTokenizer st = new StringTokenizer(key, ".");
+            String resource = null;
+            String type = null;
+
+            if (st.countTokens() > 0) {
+                resource = st.nextToken(); // e.g. "nashorn"
+            }
+
+            if (st.countTokens() > 0) {
+                type = st.nextToken(); // e.g. "option"
+            }
+
+            if ("option".equals(type)) {
+                String helpKey = null;
+                String xhelpKey = null;
+                String definePropKey = null;
+                try {
+                    helpKey = Options.bundle.getString(resource + ".options.help.key");
+                    xhelpKey = Options.bundle.getString(resource + ".options.xhelp.key");
+                    definePropKey = Options.bundle.getString(resource + ".options.D.key");
+                } catch (final MissingResourceException e) {
+                    //ignored: no help
+                }
+                final boolean        isHelp = key.equals(helpKey);
+                final boolean        isXHelp = key.equals(xhelpKey);
+                final OptionTemplate t      = new OptionTemplate(resource, key, Options.bundle.getString(key), isHelp, isXHelp);
+
+                Options.validOptions.add(t);
+                if (isHelp) {
+                    helpOptionTemplate = t;
+                }
+
+                if (key.equals(definePropKey)) {
+                    definePropPrefix = t.getName();
+                    definePropTemplate = t;
+                }
+            } else if (resource != null && "options".equals(type)) {
+                Options.usage.put(resource, Options.bundle.getObject(key));
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    private static class IllegalOptionException extends IllegalArgumentException {
+        private final OptionTemplate template;
+
+        IllegalOptionException(final OptionTemplate t) {
+            super();
+            this.template = t;
+        }
+
+        OptionTemplate getTemplate() {
+            return this.template;
+        }
+    }
+
+    /**
+     * This is a resolved argument of the form key=value
+     */
+    private static class ParsedArg {
+        /** The resolved option template this argument corresponds to */
+        OptionTemplate template;
+
+        /** The value of the argument */
+        String value;
+
+        ParsedArg(final String argument) {
+            final QuotedStringTokenizer st = new QuotedStringTokenizer(argument, "=");
+            if (!st.hasMoreTokens()) {
+                throw new IllegalArgumentException();
+            }
+
+            final String token = st.nextToken();
+            this.template = Options.getOptionTemplate(token);
+            if (this.template == null) {
+                throw new IllegalArgumentException(argument);
+            }
+
+            value = "";
+            if (st.hasMoreTokens()) {
+                while (st.hasMoreTokens()) {
+                    value += st.nextToken();
+                    if (st.hasMoreTokens()) {
+                        value += ':';
+                    }
+                }
+            } else if ("boolean".equals(this.template.getType())) {
+                value = "true";
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/ValueOption.java b/nashorn/src/jdk/nashorn/internal/runtime/options/ValueOption.java
new file mode 100644
index 0000000..2f4461f
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/ValueOption.java
@@ -0,0 +1,59 @@
+/*
+ * 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.options;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.StringTokenizer;
+
+/**
+ * This option represents a collection of comma separated values
+ */
+public class ValueOption extends Option<String> {
+
+    private Collection<String> values;
+
+    ValueOption(final String value) {
+        super(value);
+        if (value != null) {
+            values = new LinkedHashSet<>();
+            final StringTokenizer st = new StringTokenizer(getValue(), ",");
+            while (st.hasMoreElements()) {
+                values.add(st.nextToken());
+            }
+        }
+    }
+
+    /**
+     * Get the values in the option
+     * @return collection of strings
+     */
+    public Collection<String> getValues() {
+        return Collections.unmodifiableCollection(values);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java
new file mode 100644
index 0000000..7c1dd8b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java
@@ -0,0 +1,163 @@
+/*
+ * 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.regexp;
+
+import jdk.nashorn.internal.runtime.ParserException;
+
+import static java.util.regex.Pattern.CASE_INSENSITIVE;
+import static java.util.regex.Pattern.MULTILINE;
+import static java.util.regex.Pattern.UNICODE_CASE;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Default regular expression implementation based on java.util.regex package.
+ *
+ * Note that this class is not thread-safe as it stores the current match result
+ * and the string being matched in instance fields.
+ */
+public class DefaultRegExp extends RegExp {
+
+    /** Java regexp pattern to use for match. We compile to one of these */
+    private Pattern pattern;
+
+    /** The matcher */
+    private RegExpMatcher matcher;
+
+    /**
+     * Construct a Regular expression from the given {@code source} and {@code flags} strings.
+     *
+     * @param source RegExp source string
+     * @param flags RegExp flag string
+     * @throws ParserException if flags is invalid or source string has syntax error.
+     */
+    public DefaultRegExp(final String source, final String flags) throws ParserException {
+        super(source, flags);
+
+        int intFlags = 0;
+
+        if (isIgnoreCase()) {
+            intFlags |= CASE_INSENSITIVE | UNICODE_CASE;
+        }
+        if (isMultiline()) {
+            intFlags |= MULTILINE;
+        }
+
+        try {
+            RegExpScanner parsed;
+
+            try {
+                parsed = RegExpScanner.scan(source);
+            } catch (final PatternSyntaxException e) {
+                // refine the exception with a better syntax error, if this
+                // passes, just rethrow what we have
+                Pattern.compile(source, intFlags);
+                throw e;
+            }
+
+            if (parsed != null) {
+                this.pattern = Pattern.compile(parsed.getJavaPattern(), intFlags);
+                this.groupsInNegativeLookahead = parsed.getGroupsInNegativeLookahead();
+            }
+        } catch (final PatternSyntaxException e2) {
+            throwParserException("syntax", e2.getMessage());
+        }
+    }
+
+    @Override
+    public RegExpMatcher match(final String str) {
+        if (pattern == null) {
+            return null; // never matches or similar, e.g. a[]
+        }
+
+        RegExpMatcher matcher = this.matcher;
+
+        if (matcher == null || matcher.getInput() != str) {
+            matcher = new DefaultMatcher(str);
+            this.matcher = matcher;
+        }
+
+        return matcher;
+    }
+
+    class DefaultMatcher implements RegExpMatcher {
+        final String input;
+        final Matcher matcher;
+
+        DefaultMatcher(final String input) {
+            this.input = input;
+            this.matcher = pattern.matcher(input);
+        }
+
+        @Override
+        public boolean search(final int start) {
+            return matcher.find(start);
+        }
+
+        @Override
+        public String getInput() {
+            return input;
+        }
+
+        @Override
+        public int start() {
+            return matcher.start();
+        }
+
+        @Override
+        public int start(final int group) {
+            return matcher.start(group);
+        }
+
+        @Override
+        public int end() {
+            return matcher.end();
+        }
+
+        @Override
+        public int end(final int group) {
+            return matcher.end(group);
+        }
+
+        @Override
+        public String group() {
+            return matcher.group();
+        }
+
+        @Override
+        public String group(final int group) {
+            return matcher.group(group);
+        }
+
+        @Override
+        public int groupCount() {
+            return matcher.groupCount();
+        }
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java
new file mode 100644
index 0000000..f8c35bf
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java
@@ -0,0 +1,181 @@
+/*
+ * 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.regexp;
+
+import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.regexp.joni.Matcher;
+import jdk.nashorn.internal.runtime.regexp.joni.Option;
+import jdk.nashorn.internal.runtime.regexp.joni.Regex;
+import jdk.nashorn.internal.runtime.regexp.joni.Region;
+import jdk.nashorn.internal.runtime.regexp.joni.Syntax;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
+
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Regular expression implementation based on the Joni engine from the JRuby project.
+ */
+public class JoniRegExp extends RegExp {
+
+    /** Compiled Joni Regex */
+    private Regex regex;
+
+    /** Matcher */
+    private RegExpMatcher matcher;
+
+    /**
+     * Construct a Regular expression from the given {@code pattern} and {@code flags} strings.
+     *
+     * @param pattern RegExp pattern string
+     * @param flags RegExp flag string
+     * @throws ParserException if flags is invalid or pattern string has syntax error.
+     */
+    public JoniRegExp(final String pattern, final String flags) throws ParserException {
+        super(pattern, flags);
+
+        int option = Option.SINGLELINE;
+
+        if (this.isIgnoreCase()) {
+            option |= Option.IGNORECASE;
+        }
+        if (this.isMultiline()) {
+            option &= ~Option.SINGLELINE;
+            option |= Option.NEGATE_SINGLELINE;
+        }
+
+        try {
+            RegExpScanner parsed;
+
+            try {
+                parsed = RegExpScanner.scan(pattern);
+            } catch (final PatternSyntaxException e) {
+                // refine the exception with a better syntax error, if this
+                // passes, just rethrow what we have
+                Pattern.compile(pattern, 0);
+                throw e;
+            }
+
+            if (parsed != null) {
+                char[] javaPattern = parsed.getJavaPattern().toCharArray();
+                this.regex = new Regex(javaPattern, 0, javaPattern.length, option, Syntax.JAVASCRIPT);
+                this.groupsInNegativeLookahead = parsed.getGroupsInNegativeLookahead();
+            }
+        } catch (final PatternSyntaxException e2) {
+            throwParserException("syntax", e2.getMessage());
+        } catch (JOniException e2) {
+            throwParserException("syntax", e2.getMessage());
+        }
+    }
+
+    @Override
+    public RegExpMatcher match(final String input) {
+        if (regex == null) {
+            return null;
+        }
+
+        RegExpMatcher matcher = this.matcher;
+
+        if (matcher == null || input != matcher.getInput()) {
+            matcher = new JoniMatcher(input);
+            this.matcher = matcher;
+        }
+
+        return matcher;
+    }
+
+    /**
+     * RegExp Factory class for Joni regexp engine.
+     */
+    public static class Factory extends RegExpFactory {
+
+        @Override
+        protected RegExp compile(final String pattern, final String flags) throws ParserException {
+            return new JoniRegExp(pattern, flags);
+        }
+
+    }
+
+    class JoniMatcher implements RegExpMatcher {
+        final String input;
+        final Matcher matcher;
+
+        JoniMatcher(final String input) {
+            this.input = input;
+            this.matcher = regex.matcher(input.toCharArray());
+        }
+
+        @Override
+        public boolean search(final int start) {
+            return matcher.search(start, input.length(), Option.NONE) > -1;
+        }
+
+        @Override
+        public String getInput() {
+            return input;
+        }
+
+        @Override
+        public int start() {
+            return matcher.getBegin();
+        }
+
+        @Override
+        public int start(final int group) {
+            return group == 0 ? start() : matcher.getRegion().beg[group];
+        }
+
+        @Override
+        public int end() {
+            return matcher.getEnd();
+        }
+
+        @Override
+        public int end(final int group) {
+            return group == 0 ? end() : matcher.getRegion().end[group];
+        }
+
+        @Override
+        public String group() {
+            return input.substring(matcher.getBegin(), matcher.getEnd());
+        }
+
+        @Override
+        public String group(final int group) {
+            if (group == 0) {
+                return group();
+            }
+            final Region region = matcher.getRegion();
+            return input.substring(region.beg[group], region.end[group]);
+        }
+
+        @Override
+        public int groupCount() {
+            final Region region = matcher.getRegion();
+            return region == null ? 0 : region.numRegs - 1;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java
new file mode 100644
index 0000000..a4274f6
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java
@@ -0,0 +1,164 @@
+/*
+ * 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.regexp;
+
+import jdk.nashorn.internal.runtime.BitVector;
+import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ParserException;
+
+import java.util.regex.MatchResult;
+
+/**
+ * This is the base class for representing a parsed regular expression.
+ *
+ * Instances of this class are created by a {@link RegExpFactory}.
+ */
+public abstract class RegExp {
+
+    /** Pattern string. */
+    private final String source;
+
+    /** Global search flag for this regexp.*/
+    private boolean global;
+
+    /** Case insensitive flag for this regexp */
+    private boolean ignoreCase;
+
+    /** Multi-line flag for this regexp */
+    private boolean multiline;
+
+    /** BitVector that keeps track of groups in negative lookahead */
+    protected BitVector groupsInNegativeLookahead;
+
+    /**
+     * Constructor.
+     *
+     * @param source the source string
+     * @param flags the flags string
+     */
+    protected RegExp(final String source, final String flags) {
+        this.source = source;
+        for (int i = 0; i < flags.length(); i++) {
+            final char ch = flags.charAt(i);
+            switch (ch) {
+            case 'g':
+                if (this.global) {
+                    throwParserException("repeated.flag", "g");
+                }
+                this.global = true;
+                break;
+            case 'i':
+                if (this.ignoreCase) {
+                    throwParserException("repeated.flag", "i");
+                }
+                this.ignoreCase = true;
+                break;
+            case 'm':
+                if (this.multiline) {
+                    throwParserException("repeated.flag", "m");
+                }
+                this.multiline = true;
+                break;
+            default:
+                throwParserException("unsupported.flag", Character.toString(ch));
+            }
+        }
+    }
+
+    /**
+     * Get the source pattern of this regular expression.
+     *
+     * @return the source string
+     */
+    public String getSource() {
+        return source;
+    }
+
+    /**
+     * Set the global flag of this regular expression to {@code global}.
+     *
+     * @param global the new global flag
+     */
+    public void setGlobal(final boolean global) {
+        this.global = global;
+    }
+
+    /**
+     * Get the global flag of this regular expression.
+     *
+     * @return the global flag
+     */
+    public boolean isGlobal() {
+        return global;
+    }
+
+    /**
+     * Get the ignore-case flag of this regular expression.
+     *
+     * @return the ignore-case flag
+     */
+    public boolean isIgnoreCase() {
+        return ignoreCase;
+    }
+
+    /**
+     * Get the multiline flag of this regular expression.
+     *
+     * @return the multiline flag
+     */
+    public boolean isMultiline() {
+        return multiline;
+    }
+
+    /**
+     * Get a bitset indicating which of the groups in this regular expression are inside a negative lookahead.
+     *
+     * @return the groups-in-negative-lookahead bitset
+     */
+    public BitVector getGroupsInNegativeLookahead() {
+        return groupsInNegativeLookahead;
+    }
+
+    /**
+     * Match this regular expression against {@code str}, starting at index {@code start}
+     * and return a {@link MatchResult} with the result.
+     *
+     * @param str the string
+     * @return the matcher
+     */
+    public abstract RegExpMatcher match(String str);
+
+    /**
+     * Throw a regexp parser exception.
+     *
+     * @param key the message key
+     * @param str string argument
+     * @throws jdk.nashorn.internal.runtime.ParserException
+     */
+    protected static void throwParserException(final String key, final String str) throws ParserException {
+        throw new ParserException(ECMAErrors.getMessage("parser.error.regex." + key, str));
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java
new file mode 100644
index 0000000..367cc85
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java
@@ -0,0 +1,103 @@
+/*
+ * 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.regexp;
+
+import jdk.nashorn.internal.parser.Lexer;
+import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Factory class for regular expressions. This class creates instances of {@link DefaultRegExp}.
+ * An alternative factory can be installed using the {@code nashorn.regexp.impl} system property.
+ */
+public class RegExpFactory {
+
+
+    private final static RegExpFactory instance;
+
+    private final static String JDK  = "jdk";
+    private final static String JONI = "joni";
+
+    static {
+        final String impl = Options.getStringProperty("nashorn.regexp.impl", JDK);
+        switch (impl) {
+            case JONI:
+                instance = new JoniRegExp.Factory();
+                break;
+            case JDK:
+                instance = new RegExpFactory();
+                break;
+            default:
+                instance = null;
+                throw new InternalError("Unsupported RegExp factory: " + impl);
+        }
+    }
+
+    /**
+     * Creates a Regular expression from the given {@code pattern} and {@code flags} strings.
+     *
+     * @param pattern RegExp pattern string
+     * @param flags RegExp flags string
+     * @throws ParserException if flags is invalid or pattern string has syntax error.
+     */
+    protected RegExp compile(final String pattern, final String flags) throws ParserException {
+        return new DefaultRegExp(pattern, flags);
+    }
+
+    /**
+     * Compile a regexp with the given {@code source} and {@code flags}.
+     *
+     * @param pattern RegExp pattern string
+     * @param flags  flag string
+     *
+     * @throws ParserException if invalid source or flags
+     */
+    public static RegExp create(final String pattern, final String flags) {
+        return instance.compile(pattern,  flags);
+    }
+
+    /**
+     * Validate a regexp with the given {@code source} and {@code flags}.
+     *
+     * @param pattern RegExp pattern string
+     * @param flags  flag string
+     *
+     * @throws ParserException if invalid source or flags
+     */
+    // @SuppressWarnings({"unused"})
+    public static void validate(final String pattern, final String flags) throws ParserException {
+        instance.compile(pattern, flags);
+    }
+
+    /**
+     * Returns true if the instance uses the JDK's {@code java.util.regex} package.
+     *
+     * @return true if instance uses JDK regex package
+     */
+    public static boolean usesJavaUtilRegex() {
+        return instance != null && instance.getClass() == RegExpFactory.class;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpMatcher.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpMatcher.java
new file mode 100644
index 0000000..2697cdf
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpMatcher.java
@@ -0,0 +1,51 @@
+/*
+ * 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.regexp;
+
+import java.util.regex.MatchResult;
+
+/**
+ * Interface for matching a regular expression against a string and retrieving the
+ * match result. Extends {@link MatchResult}.
+ */
+public interface RegExpMatcher extends MatchResult {
+
+    /**
+     * Searches for pattern starting at {@code start}. Returns {@code true} if a match was found.
+     *
+     * @param start the start index in the input string
+     * @return {@code true} if a match was found
+     */
+    boolean search(int start);
+
+    /**
+     * Get the input string.
+     *
+     * @return the input string
+     */
+    String getInput();
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpResult.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpResult.java
new file mode 100644
index 0000000..ff838b6
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpResult.java
@@ -0,0 +1,98 @@
+/*
+ * 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.regexp;
+
+/**
+ * Match tuple to keep track of ongoing regexp match.
+ */
+public final class RegExpResult {
+    final Object[] groups;
+    final int      index;
+    final String   input;
+
+    /**
+     * Constructor
+     *
+     * @param input  regexp input
+     * @param index  index of match
+     * @param groups groups vector
+     */
+    public RegExpResult(final String input, final int index, final Object[] groups) {
+        this.input  = input;
+        this.index  = index;
+        this.groups = groups;
+    }
+
+    /**
+     * Get the groups for the match
+     * @return group vector
+     */
+    public Object[] getGroups() {
+        return groups;
+    }
+
+    /**
+     * Get the input for the map
+     * @return input
+     */
+    public String getInput() {
+        return input;
+    }
+
+    /**
+     * Get the index for the match
+     * @return index
+     */
+    public int getIndex() {
+        return index;
+    }
+
+    /**
+     * Get the length of the match
+     * @return length
+     */
+    public int length() {
+        return ((String)groups[0]).length();
+    }
+
+    /**
+     * Get the group with the given index or the empty string if group index is not valid.
+     * @param index the group index
+     * @return the group or ""
+     */
+    public Object getGroup(int index) {
+        return index >= 0 && index < groups.length ? groups[index] : "";
+    }
+
+    /**
+     * Get the last parenthesis group, or the empty string if none exists.
+     * @return the last group or ""
+     */
+    public Object getLastParen() {
+        return groups.length > 1 ? groups[groups.length - 1] : "";
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java
new file mode 100644
index 0000000..b579865
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java
@@ -0,0 +1,959 @@
+/*
+ * 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.regexp;
+
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.PatternSyntaxException;
+
+import jdk.nashorn.internal.parser.Lexer;
+import jdk.nashorn.internal.parser.Scanner;
+import jdk.nashorn.internal.runtime.BitVector;
+
+/**
+ * Scan a JavaScript regexp, converting to Java regex if necessary.
+ *
+ */
+final class RegExpScanner extends Scanner {
+
+    /**
+     * String builder used to rewrite the pattern for the currently used regexp factory.
+     */
+    private final StringBuilder sb;
+
+    /** Is this the special case of a regexp that never matches anything */
+    private boolean neverMatches;
+
+    /** Expected token table */
+    private final Map<Character, Integer> expected = new HashMap<>();
+
+    /** Capturing parenthesis that have been found so far. */
+    private final List<Capture> caps = new LinkedList<>();
+
+    /** Forward references to capturing parenthesis to be resolved later.*/
+    private final Set<Integer> forwardReferences = new LinkedHashSet<>();
+
+    /** Current level of zero-width negative lookahead assertions. */
+    private int negativeLookaheadLevel;
+
+    /** Are we currently inside a character class? */
+    private boolean inCharClass = false;
+
+    /** Are we currently inside a negated character class? */
+    private boolean inNegativeClass = false;
+
+    private static final String NON_IDENT_ESCAPES = "$^*+(){}[]|\\.?";
+
+    private static class Capture {
+        /**
+         * Zero-width negative lookaheads enclosing the capture.
+         */
+        private final int negativeLookaheadLevel;
+
+        Capture(final int negativeLookaheadLevel) {
+            this.negativeLookaheadLevel = negativeLookaheadLevel;
+        }
+
+        public int getNegativeLookaheadLevel() {
+            return negativeLookaheadLevel;
+        }
+
+    }
+
+    /**
+     * Constructor
+     * @param string the JavaScript regexp to parse
+     */
+    private RegExpScanner(final String string) {
+        super(string);
+        sb = new StringBuilder(limit);
+        reset(0);
+        expected.put(']', 0);
+        expected.put('}', 0);
+    }
+
+    private void processForwardReferences() {
+        if (neverMatches()) {
+            return;
+        }
+
+        for (final Integer ref : forwardReferences) {
+            if (ref.intValue() > caps.size()) {
+                neverMatches = true;
+                break;
+            }
+        }
+
+        forwardReferences.clear();
+    }
+
+    /**
+     * Scan a JavaScript regexp string returning a Java safe regex string.
+     *
+     * @param string
+     *            JavaScript regexp string.
+     * @return Java safe regex string.
+     */
+    public static RegExpScanner scan(final String string) {
+        final RegExpScanner scanner = new RegExpScanner(string);
+
+        try {
+            scanner.disjunction();
+        } catch (final Exception e) {
+            throw new PatternSyntaxException(e.getMessage(), string, scanner.position);
+        }
+
+        scanner.processForwardReferences();
+        if (scanner.neverMatches()) {
+            return null; // never matches
+        }
+
+        // Throw syntax error unless we parsed the entire JavaScript regexp without syntax errors
+        if (scanner.position != string.length()) {
+            final String p = scanner.getStringBuilder().toString();
+            throw new PatternSyntaxException(string, p, p.length() + 1);
+        }
+
+        return scanner;
+     }
+
+    /**
+     * Does this regexp ever match anything? Use of e.g. [], which is legal in JavaScript,
+     * is an example where we never match
+     *
+     * @return boolean
+     */
+    private boolean neverMatches() {
+        return neverMatches;
+    }
+
+    final StringBuilder getStringBuilder() {
+        return sb;
+    }
+
+    String getJavaPattern() {
+        return sb.toString();
+    }
+
+    BitVector getGroupsInNegativeLookahead() {
+        BitVector vec = null;
+        for (int i = 0; i < caps.size(); i++) {
+            final Capture cap = caps.get(i);
+            if (cap.getNegativeLookaheadLevel() > 0) {
+                if (vec == null) {
+                    vec = new BitVector(caps.size() + 1);
+                }
+                vec.set(i + 1);
+            }
+        }
+        return vec;
+    }
+
+    /**
+     * Commit n characters to the builder and to a given token
+     * @param n     Number of characters.
+     * @return Committed token
+     */
+    private boolean commit(final int n) {
+        final int startIn = position;
+
+        switch (n) {
+        case 1:
+            sb.append(ch0);
+            skip(1);
+            break;
+        case 2:
+            sb.append(ch0);
+            sb.append(ch1);
+            skip(2);
+            break;
+        case 3:
+            sb.append(ch0);
+            sb.append(ch1);
+            sb.append(ch2);
+            skip(3);
+            break;
+        default:
+            assert false : "Should not reach here";
+        }
+
+        return true;
+    }
+
+    /**
+     * Restart the buffers back at an earlier position.
+     *
+     * @param startIn
+     *            Position in the input stream.
+     * @param startOut
+     *            Position in the output stream.
+     */
+    private void restart(final int startIn, final int startOut) {
+        reset(startIn);
+        sb.setLength(startOut);
+    }
+
+    private void push(final char ch) {
+        expected.put(ch, expected.get(ch) + 1);
+    }
+
+    private void pop(final char ch) {
+        expected.put(ch, Math.min(0, expected.get(ch) - 1));
+    }
+
+    /*
+     * Recursive descent tokenizer starts below.
+     */
+
+    /*
+     * Disjunction ::
+     *      Alternative
+     *      Alternative | Disjunction
+     */
+    private void disjunction() {
+        while (true) {
+            alternative();
+
+            if (ch0 == '|') {
+                commit(1);
+            } else {
+                break;
+            }
+        }
+    }
+
+    /*
+     * Alternative ::
+     *      [empty]
+     *      Alternative Term
+     */
+    private void alternative() {
+        while (term()) {
+            // do nothing
+        }
+    }
+
+    /*
+     * Term ::
+     *      Assertion
+     *      Atom
+     *      Atom Quantifier
+     */
+    private boolean term() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        if (assertion()) {
+            return true;
+        }
+
+        if (atom()) {
+            boolean emptyCharacterClass = false;
+            if (sb.toString().endsWith("[]")) {
+                emptyCharacterClass = true;
+            } else if (sb.toString().endsWith("[^]")) {
+                sb.setLength(sb.length() - 2);
+                sb.append("\\s\\S]");
+            }
+
+            boolean quantifier = quantifier();
+
+            if (emptyCharacterClass) {
+                if (!quantifier) {
+                    neverMatches = true; //never matches ever.
+                }
+                // Note: we could check if quantifier has min zero to mark empty character class as dead.
+            }
+
+            return true;
+        }
+
+        restart(startIn, startOut);
+        return false;
+    }
+
+    /*
+     * Assertion ::
+     *      ^
+     *      $
+     *      \b
+     *      \B
+     *      ( ? = Disjunction )
+     *      ( ? ! Disjunction )
+     */
+    private boolean assertion() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        switch (ch0) {
+        case '^':
+        case '$':
+            return commit(1);
+
+        case '\\':
+            if (ch1 == 'b' || ch1 == 'B') {
+                return commit(2);
+            }
+            break;
+
+        case '(':
+            if (ch1 != '?') {
+                break;
+            }
+            if (ch2 != '=' && ch2 != '!') {
+                break;
+            }
+            final boolean isNegativeLookahead = (ch2 == '!');
+            commit(3);
+
+            if (isNegativeLookahead) {
+                negativeLookaheadLevel++;
+            }
+            disjunction();
+            if (isNegativeLookahead) {
+                negativeLookaheadLevel--;
+            }
+
+            if (ch0 == ')') {
+                return commit(1);
+            }
+            break;
+
+        default:
+            break;
+        }
+
+        restart(startIn, startOut);
+        return false;
+    }
+
+    /*
+     * Quantifier ::
+     *      QuantifierPrefix
+     *      QuantifierPrefix ?
+     */
+    private boolean quantifier() {
+        if (quantifierPrefix()) {
+            if (ch0 == '?') {
+                commit(1);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * QuantifierPrefix ::
+     *      *
+     *      +
+     *      ?
+     *      { DecimalDigits }
+     *      { DecimalDigits , }
+     *      { DecimalDigits , DecimalDigits }
+     */
+    private boolean quantifierPrefix() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        switch (ch0) {
+        case '*':
+        case '+':
+        case '?':
+            return commit(1);
+
+        case '{':
+            commit(1);
+
+            if (!decimalDigits()) {
+                break; // not a quantifier - back out
+            }
+            push('}');
+
+            if (ch0 == ',') {
+                commit(1);
+                decimalDigits();
+            }
+
+            if (ch0 == '}') {
+                pop('}');
+                commit(1);
+            }
+
+            return true;
+
+        default:
+            break;
+        }
+
+        restart(startIn, startOut);
+        return false;
+    }
+
+    /*
+     * Atom ::
+     *      PatternCharacter
+     *      .
+     *      \ AtomEscape
+     *      CharacterClass
+     *      ( Disjunction )
+     *      ( ? : Disjunction )
+     *
+     */
+    private boolean atom() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        if (patternCharacter()) {
+            return true;
+        }
+
+        if (ch0 == '.') {
+            return commit(1);
+        }
+
+        if (ch0 == '\\') {
+            commit(1);
+
+            if (atomEscape()) {
+                return true;
+            }
+        }
+
+        if (characterClass()) {
+            return true;
+        }
+
+        if (ch0 == '(') {
+            boolean capturingParens = true;
+            commit(1);
+            if (ch0 == '?' && ch1 == ':') {
+                capturingParens = false;
+                commit(2);
+            }
+
+            disjunction();
+
+            if (ch0 == ')') {
+                commit(1);
+                if (capturingParens) {
+                    caps.add(new Capture(negativeLookaheadLevel));
+                }
+                return true;
+            }
+        }
+
+        restart(startIn, startOut);
+        return false;
+    }
+
+    /*
+     * PatternCharacter ::
+     *      SourceCharacter but not any of: ^$\.*+?()[]{}|
+     */
+    @SuppressWarnings("fallthrough")
+    private boolean patternCharacter() {
+        if (atEOF()) {
+            return false;
+        }
+
+        switch (ch0) {
+        case '^':
+        case '$':
+        case '\\':
+        case '.':
+        case '*':
+        case '+':
+        case '?':
+        case '(':
+        case ')':
+        case '[':
+        case '|':
+            return false;
+
+        case '}':
+        case ']':
+            final int n = expected.get(ch0);
+            if (n != 0) {
+                return false;
+            }
+
+       case '{':
+           // if not a valid quantifier escape curly brace to match itself
+           // this ensures compatibility with other JS implementations
+           if (!quantifierPrefix()) {
+               sb.append('\\');
+               return commit(1);
+           }
+           return false;
+
+        default:
+            return commit(1); // SOURCECHARACTER
+        }
+    }
+
+    /*
+     * AtomEscape ::
+     *      DecimalEscape
+     *      CharacterEscape
+     *      CharacterClassEscape
+     */
+    private boolean atomEscape() {
+        // Note that contrary to ES 5.1 spec we put identityEscape() last because it acts as a catch-all
+        return decimalEscape() || characterClassEscape() || characterEscape() || identityEscape();
+    }
+
+    /*
+     * CharacterEscape ::
+     *      ControlEscape
+     *      c ControlLetter
+     *      HexEscapeSequence
+     *      UnicodeEscapeSequence
+     *      IdentityEscape
+     */
+    private boolean characterEscape() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        if (controlEscape()) {
+            return true;
+        }
+
+        if (ch0 == 'c') {
+            commit(1);
+            if (controlLetter()) {
+                return true;
+            }
+            restart(startIn, startOut);
+        }
+
+        if (hexEscapeSequence() || unicodeEscapeSequence()) {
+            return true;
+        }
+
+        restart(startIn, startOut);
+        return false;
+    }
+
+    private boolean scanEscapeSequence(final char leader, final int length) {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        if (ch0 != leader) {
+            return false;
+        }
+
+        commit(1);
+        for (int i = 0; i < length; i++) {
+            final char ch0l = Character.toLowerCase(ch0);
+            if ((ch0l >= 'a' && ch0l <= 'f') || isDecimalDigit(ch0)) {
+                commit(1);
+            } else {
+                restart(startIn, startOut);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private boolean hexEscapeSequence() {
+        return scanEscapeSequence('x', 2);
+    }
+
+    private boolean unicodeEscapeSequence() {
+        return scanEscapeSequence('u', 4);
+    }
+
+    /*
+     * ControlEscape ::
+     *      one of fnrtv
+     */
+    private boolean controlEscape() {
+        switch (ch0) {
+        case 'f':
+        case 'n':
+        case 'r':
+        case 't':
+        case 'v':
+            return commit(1);
+
+        default:
+            return false;
+        }
+    }
+
+    /*
+     * ControlLetter ::
+     *      one of abcdefghijklmnopqrstuvwxyz
+     *      ABCDEFGHIJKLMNOPQRSTUVWXYZ
+     */
+    private boolean controlLetter() {
+        final char c = Character.toUpperCase(ch0);
+        if (c >= 'A' && c <= 'Z') {
+            // for some reason java regexps don't like control characters on the
+            // form "\\ca".match([string with ascii 1 at char0]). Translating
+            // them to unicode does it though.
+            sb.setLength(sb.length() - 1);
+            unicode(c - 'A' + 1);
+            skip(1);
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * IdentityEscape ::
+     *      SourceCharacter but not IdentifierPart
+     *      <ZWJ>  (200c)
+     *      <ZWNJ> (200d)
+     */
+    private boolean identityEscape() {
+        if (atEOF()) {
+            throw new RuntimeException("\\ at end of pattern"); // will be converted to PatternSyntaxException
+        }
+        // ES 5.1 A.7 requires "not IdentifierPart" here but all major engines accept any character here.
+        if (NON_IDENT_ESCAPES.indexOf(ch0) == -1) {
+            sb.setLength(sb.length() - 1);
+        }
+        return commit(1);
+    }
+
+    /*
+     * DecimalEscape ::
+     *      DecimalIntegerLiteral [lookahead DecimalDigit]
+     */
+    private boolean decimalEscape() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        if (ch0 == '0' && !isDecimalDigit(ch1)) {
+            skip(1);
+            //  DecimalEscape :: 0. If i is zero, return the EscapeValue consisting of a <NUL> character (Unicodevalue0000);
+            sb.append("\u0000");
+            return true;
+        }
+
+        if (isDecimalDigit(ch0)) {
+            final int num = ch0 - '0';
+
+            // Single digit escape, treat as backreference.
+            if (!isDecimalDigit(ch1)) {
+                if (num <= caps.size() && caps.get(num - 1).getNegativeLookaheadLevel() > 0) {
+                    //  Captures that live inside a negative lookahead are dead after the
+                    //  lookahead and will be undefined if referenced from outside.
+                    if (caps.get(num - 1).getNegativeLookaheadLevel() > negativeLookaheadLevel) {
+                        sb.setLength(sb.length() - 1);
+                    } else {
+                        sb.append(ch0);
+                    }
+                    skip(1);
+                    return true;
+                } else if (num > caps.size()) {
+                    // Forward reference to a capture group. Forward references are always undefined so we
+                    // can omit it from the output buffer. Additionally, if the capture group does not exist
+                    // the whole regexp becomes invalid, so register the reference for later processing.
+                    forwardReferences.add(num);
+                    sb.setLength(sb.length() - 1);
+                    skip(1);
+                    return true;
+                }
+            }
+
+            if (inCharClass) {
+                // Convert octal escape to unicode escape if inside character class.
+                StringBuilder digit = new StringBuilder(4);
+                while (isDecimalDigit(ch0)) {
+                    digit.append(ch0);
+                    skip(1);
+                }
+
+                int value = Integer.parseInt(digit.toString(), 8); //throws exception that leads to SyntaxError if not octal
+                if (value > 0xff) {
+                    throw new NumberFormatException(digit.toString());
+                }
+
+                unicode(value);
+
+            } else {
+                // Copy decimal escape as-is
+                decimalDigits();
+            }
+            return true;
+        }
+
+        restart(startIn, startOut);
+        return false;
+    }
+
+    /*
+     * CharacterClassEscape ::
+     *  one of dDsSwW
+     */
+    private boolean characterClassEscape() {
+        switch (ch0) {
+        // java.util.regex requires translation of \s and \S to explicit character list
+        case 's':
+            if (RegExpFactory.usesJavaUtilRegex()) {
+                sb.setLength(sb.length() - 1);
+                // No nested class required if we already are inside a character class
+                if (inCharClass) {
+                    sb.append(Lexer.getWhitespaceRegExp());
+                } else {
+                    sb.append('[').append(Lexer.getWhitespaceRegExp()).append(']');
+                }
+                skip(1);
+                return true;
+            }
+            return commit(1);
+        case 'S':
+            if (RegExpFactory.usesJavaUtilRegex()) {
+                sb.setLength(sb.length() - 1);
+                // In negative class we must use intersection to get double negation ("not anything else than space")
+                sb.append(inNegativeClass ? "&&[" : "[^").append(Lexer.getWhitespaceRegExp()).append(']');
+                skip(1);
+                return true;
+            }
+            return commit(1);
+        case 'd':
+        case 'D':
+        case 'w':
+        case 'W':
+            return commit(1);
+
+        default:
+            return false;
+        }
+    }
+
+    /*
+     * CharacterClass ::
+     *      [ [lookahead {^}] ClassRanges ]
+     *      [ ^ ClassRanges ]
+     */
+    private boolean characterClass() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        if (ch0 == '[') {
+            try {
+                inCharClass = true;
+                push(']');
+                commit(1);
+
+                if (ch0 == '^') {
+                    inNegativeClass = true;
+                    commit(1);
+                }
+
+                if (classRanges() && ch0 == ']') {
+                    pop(']');
+                    return commit(1);
+                }
+            } finally {
+                inCharClass = false;  // no nested character classes in JavaScript
+                inNegativeClass = false;
+            }
+        }
+
+        restart(startIn, startOut);
+        return false;
+    }
+
+    /*
+     * ClassRanges ::
+     *      [empty]
+     *      NonemptyClassRanges
+     */
+    private boolean classRanges() {
+        nonemptyClassRanges();
+        return true;
+    }
+
+    /*
+     * NonemptyClassRanges ::
+     *      ClassAtom
+     *      ClassAtom NonemptyClassRangesNoDash
+     *      ClassAtom - ClassAtom ClassRanges
+     */
+    private boolean nonemptyClassRanges() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        if (classAtom()) {
+
+            if (ch0 == '-') {
+                commit(1);
+
+                if (classAtom() && classRanges()) {
+                    return true;
+                }
+            }
+
+            nonemptyClassRangesNoDash();
+
+            return true;
+        }
+
+        restart(startIn, startOut);
+        return false;
+    }
+
+    /*
+     * NonemptyClassRangesNoDash ::
+     *      ClassAtom
+     *      ClassAtomNoDash NonemptyClassRangesNoDash
+     *      ClassAtomNoDash - ClassAtom ClassRanges
+     */
+    private boolean nonemptyClassRangesNoDash() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        if (classAtomNoDash()) {
+
+            // need to check dash first, as for e.g. [a-b|c-d] will otherwise parse - as an atom
+            if (ch0 == '-') {
+               commit(1);
+
+               if (classAtom() && classRanges()) {
+                   return true;
+               }
+               //fallthru
+           }
+
+            nonemptyClassRangesNoDash();
+            return true; // still a class atom
+        }
+
+        if (classAtom()) {
+            return true;
+        }
+
+        restart(startIn, startOut);
+        return false;
+    }
+
+    /*
+     * ClassAtom : - ClassAtomNoDash
+     */
+    private boolean classAtom() {
+
+        if (ch0 == '-') {
+            return commit(1);
+        }
+
+        return classAtomNoDash();
+    }
+
+    /*
+     * ClassAtomNoDash ::
+     *      SourceCharacter but not one of \ or ] or -
+     *      \ ClassEscape
+     */
+    private boolean classAtomNoDash() {
+        final int startIn  = position;
+        final int startOut = sb.length();
+
+        switch (ch0) {
+        case ']':
+        case '-':
+        case '\0':
+            return false;
+
+        case '[':
+            // unescaped left square bracket - add escape
+            sb.append('\\');
+            return commit(1);
+
+        case '\\':
+            commit(1);
+            if (classEscape()) {
+                return true;
+            }
+
+            restart(startIn, startOut);
+            return false;
+
+        default:
+            return commit(1);
+        }
+    }
+
+    /*
+     * ClassEscape ::
+     *      DecimalEscape
+     *      b
+     *      CharacterEscape
+     *      CharacterClassEscape
+     */
+    private boolean classEscape() {
+
+        if (decimalEscape()) {
+            return true;
+        }
+
+        if (ch0 == 'b') {
+            sb.setLength(sb.length() - 1);
+            sb.append('\b');
+            skip(1);
+            return true;
+        }
+
+        // Note that contrary to ES 5.1 spec we put identityEscape() last because it acts as a catch-all
+        return characterEscape() || characterClassEscape() || identityEscape();
+    }
+
+    /*
+     * DecimalDigits
+     */
+    private boolean decimalDigits() {
+        if (!isDecimalDigit(ch0)) {
+            return false;
+        }
+
+        while (isDecimalDigit(ch0)) {
+            commit(1);
+        }
+
+        return true;
+    }
+
+    private void unicode(final int value) {
+        final String hex = Integer.toHexString(value);
+        sb.append('u');
+        for (int i = 0; i < 4 - hex.length(); i++) {
+            sb.append('0');
+        }
+        sb.append(hex);
+    }
+
+    private static boolean isDecimalDigit(final char ch) {
+        return ch >= '0' && ch <= '9';
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java
new file mode 100644
index 0000000..65d3fcd
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java
@@ -0,0 +1,2162 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAll;
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsClear;
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAt;
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAtSimple;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isCaptureGroup;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindCondition;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isMultiline;
+import static jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode.newAltNode;
+import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.isRepeatInfinite;
+
+import java.util.HashSet;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.ObjPtr;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
+
+final class Analyser extends Parser {
+
+    protected Analyser(ScanEnvironment env, char[] chars, int p, int end) {
+        super(env, chars, p, end);
+    }
+
+    protected final void compile() {
+        regex.state = RegexState.COMPILING;
+
+        if (Config.DEBUG) {
+            Config.log.println(new String(chars, getBegin(), getEnd()));
+        }
+
+        reset();
+
+        regex.numMem = 0;
+        regex.numRepeat = 0;
+        regex.numNullCheck = 0;
+        //regex.repeatRangeAlloc = 0;
+        regex.repeatRangeLo = null;
+        regex.repeatRangeHi = null;
+        regex.numCombExpCheck = 0;
+
+        if (Config.USE_COMBINATION_EXPLOSION_CHECK) regex.numCombExpCheck = 0;
+
+        parse();
+
+        if (Config.USE_NAMED_GROUP) {
+            /* mixed use named group and no-named group */
+            if (env.numNamed > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(regex.options)) {
+                if (env.numNamed != env.numMem) {
+                    root = disableNoNameGroupCapture(root);
+                } else {
+                    numberedRefCheck(root);
+                }
+            }
+        } // USE_NAMED_GROUP
+
+        if (Config.USE_NAMED_GROUP) {
+            if (env.numCall > 0) {
+                env.unsetAddrList = new UnsetAddrList(env.numCall);
+                setupSubExpCall(root);
+                // r != 0 ???
+                subexpRecursiveCheckTrav(root);
+                // r < 0 -< err, FOUND_CALLED_NODE = 1
+                subexpInfRecursiveCheckTrav(root);
+                // r != 0  recursion infinite ???
+                regex.numCall = env.numCall;
+            } else {
+                regex.numCall = 0;
+            }
+        } // USE_NAMED_GROUP
+
+        if (Config.DEBUG_PARSE_TREE_RAW && Config.DEBUG_PARSE_TREE) {
+            Config.log.println("<RAW TREE>");
+            Config.log.println(root + "\n");
+        }
+
+        root = setupTree(root, 0);
+        if (Config.DEBUG_PARSE_TREE) {
+            if (Config.DEBUG_PARSE_TREE_RAW) Config.log.println("<TREE>");
+            root.verifyTree(new HashSet<Node>(), env.reg.warnings);
+            Config.log.println(root + "\n");
+        }
+
+        regex.captureHistory = env.captureHistory;
+        regex.btMemStart = env.btMemStart;
+        regex.btMemEnd = env.btMemEnd;
+
+        if (isFindCondition(regex.options)) {
+            regex.btMemEnd = bsAll();
+        } else {
+            regex.btMemEnd = env.btMemEnd;
+            regex.btMemEnd |= regex.captureHistory;
+        }
+
+        if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+            if (env.backrefedMem == 0 || (Config.USE_SUBEXP_CALL && env.numCall == 0)) {
+                setupCombExpCheck(root, 0);
+
+                if (Config.USE_SUBEXP_CALL && env.hasRecursion) {
+                    env.numCombExpCheck = 0;
+                } else { // USE_SUBEXP_CALL
+                    if (env.combExpMaxRegNum > 0) {
+                        for (int i=1; i<env.combExpMaxRegNum; i++) {
+                            if (bsAt(env.backrefedMem, i)) {
+                                env.numCombExpCheck = 0;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+            } // USE_SUBEXP_CALL
+            regex.numCombExpCheck = env.numCombExpCheck;
+        } // USE_COMBINATION_EXPLOSION_CHECK
+
+        regex.clearOptimizeInfo();
+
+        if (!Config.DONT_OPTIMIZE) setOptimizedInfoFromTree(root);
+
+        env.memNodes = null;
+
+        new ArrayCompiler(this).compile();
+        //new AsmCompiler(this).compile();
+
+        if (regex.numRepeat != 0 || regex.btMemEnd != 0) {
+            regex.stackPopLevel = StackPopLevel.ALL;
+        } else {
+            if (regex.btMemStart != 0) {
+                regex.stackPopLevel = StackPopLevel.MEM_START;
+            } else {
+                regex.stackPopLevel = StackPopLevel.FREE;
+            }
+        }
+
+        if (Config.DEBUG_COMPILE) {
+            if (Config.USE_NAMED_GROUP) Config.log.print(regex.nameTableToString());
+            Config.log.println("stack used: " + regex.stackNeeded);
+            if (Config.USE_STRING_TEMPLATES) Config.log.print("templates: " + regex.templateNum + "\n");
+            Config.log.println(new ByteCodePrinter(regex).byteCodeListToString());
+
+        } // DEBUG_COMPILE
+
+        regex.state = RegexState.NORMAL;
+    }
+
+    private void noNameDisableMapFor_cosAlt(Node node, int[]map, Ptr counter) {
+        ConsAltNode can = (ConsAltNode)node;
+        do {
+            can.setCar(noNameDisableMap(can.car, map, counter));
+        } while ((can = can.cdr) != null);
+    }
+
+    private void noNameDisableMapFor_quantifier(Node node, int[]map, Ptr counter) {
+        QuantifierNode qn = (QuantifierNode)node;
+        Node target = qn.target;
+        Node old = target;
+        target = noNameDisableMap(target, map, counter);
+
+        if (target != old) {
+            qn.setTarget(target);
+            if (target.getType() == NodeType.QTFR) qn.reduceNestedQuantifier((QuantifierNode)target);
+        }
+    }
+
+    private Node noNameDisableMapFor_enclose(Node node, int[]map, Ptr counter) {
+        EncloseNode en = (EncloseNode)node;
+        if (en.type == EncloseType.MEMORY) {
+            if (en.isNamedGroup()) {
+                counter.p++;
+                map[en.regNum] = counter.p;
+                en.regNum = counter.p;
+                //en.target = noNameDisableMap(en.target, map, counter);
+                en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
+            } else {
+                node = en.target;
+                en.target = null; // remove first enclose: /(a)(?<b>c)/
+                node = noNameDisableMap(node, map, counter);
+            }
+        } else {
+            //en.target = noNameDisableMap(en.target, map, counter);
+            en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
+        }
+        return node;
+    }
+
+    private void noNameDisableMapFor_anchor(Node node, int[]map, Ptr counter) {
+        AnchorNode an = (AnchorNode)node;
+        switch (an.type) {
+            case AnchorNode.PREC_READ:
+            case AnchorNode.PREC_READ_NOT:
+            case AnchorNode.LOOK_BEHIND:
+            case AnchorNode.LOOK_BEHIND_NOT:
+                an.setTarget(noNameDisableMap(an.target, map, counter));
+        }
+    }
+
+    private Node noNameDisableMap(Node node, int[]map, Ptr counter) {
+        switch (node.getType()) {
+        case NodeType.LIST:
+        case NodeType.ALT:
+            noNameDisableMapFor_cosAlt(node, map, counter);
+            break;
+        case NodeType.QTFR:
+            noNameDisableMapFor_quantifier(node, map, counter);
+            break;
+        case NodeType.ENCLOSE:
+            node = noNameDisableMapFor_enclose(node, map, counter);
+            break;
+        case NodeType.ANCHOR:
+            noNameDisableMapFor_anchor(node, map, counter);
+            break;
+        } // switch
+        return node;
+    }
+
+    private void renumberByMap(Node node, int[]map) {
+        switch (node.getType()) {
+        case NodeType.LIST:
+        case NodeType.ALT:
+            ConsAltNode can = (ConsAltNode)node;
+            do {
+                renumberByMap(can.car, map);
+            } while ((can = can.cdr) != null);
+            break;
+
+        case NodeType.QTFR:
+            renumberByMap(((QuantifierNode)node).target, map);
+            break;
+
+        case NodeType.ENCLOSE:
+            renumberByMap(((EncloseNode)node).target, map);
+            break;
+
+        case NodeType.BREF:
+            ((BackRefNode)node).renumber(map);
+            break;
+        } // switch
+    }
+
+    protected final void numberedRefCheck(Node node) {
+        switch (node.getType()) {
+        case NodeType.LIST:
+        case NodeType.ALT:
+            ConsAltNode can = (ConsAltNode)node;
+            do {
+                numberedRefCheck(can.car);
+            } while ((can = can.cdr) != null);
+            break;
+
+        case NodeType.QTFR:
+            numberedRefCheck(((QuantifierNode)node).target);
+            break;
+
+        case NodeType.ENCLOSE:
+            numberedRefCheck(((EncloseNode)node).target);
+            break;
+
+        case NodeType.BREF:
+            BackRefNode br = (BackRefNode)node;
+            if (!br.isNameRef()) newValueException(ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
+            break;
+        } // switch
+    }
+
+    protected final Node disableNoNameGroupCapture(Node root) {
+        int[]map = new int[env.numMem + 1];
+
+        for (int i=1; i<=env.numMem; i++) map[i] = 0;
+
+        root = noNameDisableMap(root, map, new Ptr(0));
+        renumberByMap(root, map);
+
+        for (int i=1, pos=1; i<=env.numMem; i++) {
+            if (map[i] > 0) {
+                env.memNodes[pos] = env.memNodes[i];
+                pos++;
+            }
+        }
+
+        int loc = env.captureHistory;
+        env.captureHistory = bsClear();
+
+        for (int i=1; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
+            if (bsAt(loc, i)) {
+                env.captureHistory = bsOnAtSimple(env.captureHistory, map[i]);
+            }
+        }
+
+        env.numMem = env.numNamed;
+        regex.numMem = env.numNamed;
+
+        regex.renumberNameTable(map);
+
+        return root;
+    }
+
+    private void swap(Node a, Node b) {
+        a.swap(b);
+
+        if (root == b) {
+            root = a;
+        } else if (root == a) {
+            root = b;
+        }
+    }
+
+    // USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
+    private int quantifiersMemoryInfo(Node node) {
+        int info = 0;
+
+        switch(node.getType()) {
+        case NodeType.LIST:
+        case NodeType.ALT:
+            ConsAltNode can = (ConsAltNode)node;
+            do {
+                int v = quantifiersMemoryInfo(can.car);
+                if (v > info) info = v;
+            } while ((can = can.cdr) != null);
+            break;
+
+        case NodeType.CALL:
+            if (Config.USE_SUBEXP_CALL) {
+                CallNode cn = (CallNode)node;
+                if (cn.isRecursion()) {
+                    return TargetInfo.IS_EMPTY_REC; /* tiny version */
+                } else {
+                    info = quantifiersMemoryInfo(cn.target);
+                }
+            } // USE_SUBEXP_CALL
+            break;
+
+        case NodeType.QTFR:
+            QuantifierNode qn = (QuantifierNode)node;
+            if (qn.upper != 0) {
+                info = quantifiersMemoryInfo(qn.target);
+            }
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            switch (en.type) {
+            case EncloseType.MEMORY:
+                return TargetInfo.IS_EMPTY_MEM;
+
+            case EncloseType.OPTION:
+            case EncloseNode.STOP_BACKTRACK:
+                info = quantifiersMemoryInfo(en.target);
+                break;
+
+            default:
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.BREF:
+        case NodeType.STR:
+        case NodeType.CTYPE:
+        case NodeType.CCLASS:
+        case NodeType.CANY:
+        case NodeType.ANCHOR:
+        default:
+            break;
+        } // switch
+
+        return info;
+    }
+
+    private int getMinMatchLength(Node node) {
+        int min = 0;
+
+        switch (node.getType()) {
+        case NodeType.BREF:
+            BackRefNode br = (BackRefNode)node;
+            if (br.isRecursion()) break;
+
+            if (br.back[0] > env.numMem) newValueException(ERR_INVALID_BACKREF);
+            min = getMinMatchLength(env.memNodes[br.back[0]]);
+
+            for (int i=1; i<br.backNum; i++) {
+                if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
+                int tmin = getMinMatchLength(env.memNodes[br.back[i]]);
+                if (min > tmin) min = tmin;
+            }
+            break;
+
+        case NodeType.CALL:
+            if (Config.USE_SUBEXP_CALL) {
+                CallNode cn = (CallNode)node;
+                if (cn.isRecursion()) {
+                    EncloseNode en = (EncloseNode)cn.target;
+                    if (en.isMinFixed()) min = en.minLength;
+                } else {
+                    min = getMinMatchLength(cn.target);
+                }
+            } // USE_SUBEXP_CALL
+            break;
+
+        case NodeType.LIST:
+            ConsAltNode can = (ConsAltNode)node;
+            do {
+                min += getMinMatchLength(can.car);
+            } while ((can = can.cdr) != null);
+            break;
+
+        case NodeType.ALT:
+            ConsAltNode y = (ConsAltNode)node;
+            do {
+                Node x = y.car;
+                int tmin = getMinMatchLength(x);
+                if (y == node) {
+                    min = tmin;
+                } else if (min > tmin) {
+                    min = tmin;
+                }
+            } while ((y = y.cdr) != null);
+            break;
+
+        case NodeType.STR:
+            min = ((StringNode)node).length();
+            break;
+
+        case NodeType.CTYPE:
+            min = 1;
+            break;
+
+        case NodeType.CCLASS:
+        case NodeType.CANY:
+            min = 1;
+            break;
+
+        case NodeType.QTFR:
+            QuantifierNode qn = (QuantifierNode)node;
+            if (qn.lower > 0) {
+                min = getMinMatchLength(qn.target);
+                min = MinMaxLen.distanceMultiply(min, qn.lower);
+            }
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            switch (en.type) {
+            case EncloseType.MEMORY:
+                if (Config.USE_SUBEXP_CALL) {
+                    if (en.isMinFixed()) {
+                        min = en.minLength;
+                    } else {
+                        min = getMinMatchLength(en.target);
+                        en.minLength = min;
+                        en.setMinFixed();
+                    }
+                } // USE_SUBEXP_CALL
+                break;
+
+            case EncloseType.OPTION:
+            case EncloseType.STOP_BACKTRACK:
+                min = getMinMatchLength(en.target);
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.ANCHOR:
+        default:
+            break;
+        } // switch
+
+        return min;
+    }
+
+    private int getMaxMatchLength(Node node) {
+        int max = 0;
+
+        switch (node.getType()) {
+        case NodeType.LIST:
+            ConsAltNode ln = (ConsAltNode)node;
+            do {
+                int tmax = getMaxMatchLength(ln.car);
+                max = MinMaxLen.distanceAdd(max, tmax);
+            } while ((ln = ln.cdr) != null);
+            break;
+
+        case NodeType.ALT:
+            ConsAltNode an = (ConsAltNode)node;
+            do {
+                int tmax = getMaxMatchLength(an.car);
+                if (max < tmax) max = tmax;
+            } while ((an = an.cdr) != null);
+            break;
+
+        case NodeType.STR:
+            max = ((StringNode)node).length();
+            break;
+
+        case NodeType.CTYPE:
+            max = 1;
+            break;
+
+        case NodeType.CCLASS:
+        case NodeType.CANY:
+            max = 1;
+            break;
+
+        case NodeType.BREF:
+            BackRefNode br = (BackRefNode)node;
+            if (br.isRecursion()) {
+                max = MinMaxLen.INFINITE_DISTANCE;
+                break;
+            }
+
+            for (int i=0; i<br.backNum; i++) {
+                if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
+                int tmax = getMaxMatchLength(env.memNodes[br.back[i]]);
+                if (max < tmax) max = tmax;
+            }
+            break;
+
+        case NodeType.CALL:
+            if (Config.USE_SUBEXP_CALL) {
+                CallNode cn = (CallNode)node;
+                if (!cn.isRecursion()) {
+                    max = getMaxMatchLength(cn.target);
+                } else {
+                    max = MinMaxLen.INFINITE_DISTANCE;
+                }
+            } // USE_SUBEXP_CALL
+            break;
+
+        case NodeType.QTFR:
+            QuantifierNode qn = (QuantifierNode)node;
+            if (qn.upper != 0) {
+                max = getMaxMatchLength(qn.target);
+                if (max != 0) {
+                    if (!isRepeatInfinite(qn.upper)) {
+                        max = MinMaxLen.distanceMultiply(max, qn.upper);
+                    } else {
+                        max = MinMaxLen.INFINITE_DISTANCE;
+                    }
+                }
+            }
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            switch (en.type) {
+            case EncloseType.MEMORY:
+                if (Config.USE_SUBEXP_CALL) {
+                    if (en.isMaxFixed()) {
+                        max = en.maxLength;
+                    } else {
+                        max = getMaxMatchLength(en.target);
+                        en.maxLength = max;
+                        en.setMaxFixed();
+                    }
+                } // USE_SUBEXP_CALL
+                break;
+
+            case EncloseType.OPTION:
+            case EncloseType.STOP_BACKTRACK:
+                max = getMaxMatchLength(en.target);
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.ANCHOR:
+        default:
+            break;
+        } // switch
+
+        return max;
+    }
+
+    private static final int GET_CHAR_LEN_VARLEN            = -1;
+    private static final int GET_CHAR_LEN_TOP_ALT_VARLEN    = -2;
+    protected final int getCharLengthTree(Node node) {
+        return getCharLengthTree(node, 0);
+    }
+
+    private int getCharLengthTree(Node node, int level) {
+        level++;
+
+        int len = 0;
+        returnCode = 0;
+
+        switch(node.getType()) {
+        case NodeType.LIST:
+            ConsAltNode ln = (ConsAltNode)node;
+            do {
+                int tlen = getCharLengthTree(ln.car, level);
+                if (returnCode == 0) len = MinMaxLen.distanceAdd(len, tlen);
+            } while (returnCode == 0 && (ln = ln.cdr) != null);
+            break;
+
+        case NodeType.ALT:
+            ConsAltNode an = (ConsAltNode)node;
+            boolean varLen = false;
+
+            int tlen = getCharLengthTree(an.car, level);
+            while (returnCode == 0 && (an = an.cdr) != null) {
+                int tlen2 = getCharLengthTree(an.car, level);
+                if (returnCode == 0) {
+                    if (tlen != tlen2) varLen = true;
+                }
+            }
+
+            if (returnCode == 0) {
+                if (varLen) {
+                    if (level == 1) {
+                        returnCode = GET_CHAR_LEN_TOP_ALT_VARLEN;
+                    } else {
+                        returnCode = GET_CHAR_LEN_VARLEN;
+                    }
+                } else {
+                    len = tlen;
+                }
+            }
+            break;
+
+        case NodeType.STR:
+            StringNode sn = (StringNode)node;
+            len = sn.length();
+            break;
+
+        case NodeType.QTFR:
+            QuantifierNode qn = (QuantifierNode)node;
+            if (qn.lower == qn.upper) {
+                tlen = getCharLengthTree(qn.target, level);
+                if (returnCode == 0) len = MinMaxLen.distanceMultiply(tlen, qn.lower);
+            } else {
+                returnCode = GET_CHAR_LEN_VARLEN;
+            }
+            break;
+
+        case NodeType.CALL:
+            if (Config.USE_SUBEXP_CALL) {
+                CallNode cn = (CallNode)node;
+                if (!cn.isRecursion()) {
+                    len = getCharLengthTree(cn.target, level);
+                } else {
+                    returnCode = GET_CHAR_LEN_VARLEN;
+                }
+            } // USE_SUBEXP_CALL
+            break;
+
+        case NodeType.CTYPE:
+            len = 1;
+
+        case NodeType.CCLASS:
+        case NodeType.CANY:
+            len = 1;
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            switch(en.type) {
+            case EncloseType.MEMORY:
+                if (Config.USE_SUBEXP_CALL) {
+                    if (en.isCLenFixed()) {
+                        len = en.charLength;
+                    } else {
+                        len = getCharLengthTree(en.target, level);
+                        if (returnCode == 0) {
+                            en.charLength = len;
+                            en.setCLenFixed();
+                        }
+                    }
+                } // USE_SUBEXP_CALL
+                break;
+
+            case EncloseType.OPTION:
+            case EncloseType.STOP_BACKTRACK:
+                len = getCharLengthTree(en.target, level);
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.ANCHOR:
+            break;
+
+        default:
+            returnCode = GET_CHAR_LEN_VARLEN;
+        } // switch
+        return len;
+    }
+
+    /* x is not included y ==>  1 : 0 */
+    private boolean isNotIncluded(Node x, Node y) {
+        Node tmp;
+
+        // !retry:!
+        retry: while(true) {
+
+        int yType = y.getType();
+
+        switch(x.getType()) {
+        case NodeType.CTYPE:
+            switch(yType) {
+            case NodeType.CTYPE:
+                CTypeNode cny = (CTypeNode)y;
+                CTypeNode cnx = (CTypeNode)x;
+                return cny.ctype == cnx.ctype && cny.not != cnx.not;
+
+            case NodeType.CCLASS:
+                // !swap:!
+                tmp = x;
+                x = y;
+                y = tmp;
+                // !goto retry;!
+                continue retry;
+
+            case NodeType.STR:
+                // !goto swap;!
+                tmp = x;
+                x = y;
+                y = tmp;
+                continue retry;
+
+            default:
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.CCLASS:
+            CClassNode xc = (CClassNode)x;
+
+            switch(yType) {
+            case NodeType.CTYPE:
+                switch(((CTypeNode)y).ctype) {
+                case CharacterType.WORD:
+                    if (!((CTypeNode)y).not) {
+                        if (xc.mbuf == null && !xc.isNot()) {
+                            for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
+                                if (xc.bs.at(i)) {
+                                    if (EncodingHelper.isWord(i)) return false;
+                                }
+                            }
+                            return true;
+                        }
+                        return false;
+                    } else {
+                        for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
+                            if (!EncodingHelper.isWord(i)) {
+                                if (!xc.isNot()) {
+                                    if (xc.bs.at(i)) return false;
+                                } else {
+                                    if (!xc.bs.at(i)) return false;
+                                }
+                            }
+                        }
+                        return true;
+                    }
+                    // break; not reached
+
+                default:
+                    break;
+                } // inner switch
+                break;
+
+            case NodeType.CCLASS:
+                CClassNode yc = (CClassNode)y;
+
+                for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
+                    boolean v = xc.bs.at(i);
+                    if ((v && !xc.isNot()) || (!v && xc.isNot())) {
+                        v = yc.bs.at(i);
+                        if ((v && !yc.isNot()) || (!v && yc.isNot())) return false;
+                    }
+                }
+                if ((xc.mbuf == null && !xc.isNot()) || yc.mbuf == null && !yc.isNot()) return true;
+                return false;
+                // break; not reached
+
+            case NodeType.STR:
+                // !goto swap;!
+                tmp = x;
+                x = y;
+                y = tmp;
+                continue retry;
+
+            default:
+                break;
+
+            } // inner switch
+            break; // case NodeType.CCLASS
+
+        case NodeType.STR:
+            StringNode xs = (StringNode)x;
+            if (xs.length() == 0) break;
+
+            switch (yType) {
+            case NodeType.CTYPE:
+                CTypeNode cy = ((CTypeNode)y);
+                switch (cy.ctype) {
+                case CharacterType.WORD:
+                    return !cy.not;
+
+                default:
+                    break;
+
+                } // inner switch
+                break;
+
+            case NodeType.CCLASS:
+                CClassNode cc = (CClassNode)y;
+                int code = xs.chars[xs.p];
+                return !cc.isCodeInCC(code);
+
+            case NodeType.STR:
+                StringNode ys = (StringNode)y;
+                int len = xs.length();
+                if (len > ys.length()) len = ys.length();
+                if (xs.isAmbig() || ys.isAmbig()) {
+                    /* tiny version */
+                    return false;
+                } else {
+                    for (int i=0, p=ys.p, q=xs.p; i<len; i++, p++, q++) {
+                        if (ys.chars[p] != xs.chars[q]) return true;
+                    }
+                }
+                break;
+
+            default:
+                break;
+            } // inner switch
+
+            break; // case NodeType.STR
+
+        } // switch
+
+        break;
+        } // retry: while
+        return false;
+    }
+
+    private Node getHeadValueNode(Node node, boolean exact) {
+        Node n = null;
+
+        switch(node.getType()) {
+        case NodeType.BREF:
+        case NodeType.ALT:
+        case NodeType.CANY:
+            break;
+
+        case NodeType.CALL:
+            break; // if (Config.USE_SUBEXP_CALL)
+
+        case NodeType.CTYPE:
+        case NodeType.CCLASS:
+            if (!exact) n = node;
+            break;
+
+        case NodeType.LIST:
+            n = getHeadValueNode(((ConsAltNode)node).car, exact);
+            break;
+
+        case NodeType.STR:
+            StringNode sn = (StringNode)node;
+            if (sn.end <= sn.p) break; // ???
+
+            if (exact && !sn.isRaw() && isIgnoreCase(regex.options)){
+                // nothing
+            } else {
+                n = node;
+            }
+            break;
+
+        case NodeType.QTFR:
+            QuantifierNode qn = (QuantifierNode)node;
+            if (qn.lower > 0) {
+                if (qn.headExact != null) {
+                    n = qn.headExact;
+                } else {
+                    n = getHeadValueNode(qn.target, exact);
+                }
+            }
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+
+            switch (en.type) {
+            case EncloseType.OPTION:
+                int options = regex.options;
+                regex.options = en.option;
+                n = getHeadValueNode(en.target, exact);
+                regex.options = options;
+                break;
+
+            case EncloseType.MEMORY:
+            case EncloseType.STOP_BACKTRACK:
+                n = getHeadValueNode(en.target, exact);
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.ANCHOR:
+            AnchorNode an = (AnchorNode)node;
+            if (an.type == AnchorType.PREC_READ) n = getHeadValueNode(an.target, exact);
+            break;
+
+        default:
+            break;
+        } // switch
+
+        return n;
+    }
+
+    // true: invalid
+    private boolean checkTypeTree(Node node, int typeMask, int encloseMask, int anchorMask) {
+        if ((node.getType2Bit() & typeMask) == 0) return true;
+
+        boolean invalid = false;
+
+        switch(node.getType()) {
+        case NodeType.LIST:
+        case NodeType.ALT:
+            ConsAltNode can = (ConsAltNode)node;
+            do {
+                invalid = checkTypeTree(can.car, typeMask, encloseMask, anchorMask);
+            } while (!invalid && (can = can.cdr) != null);
+            break;
+
+        case NodeType.QTFR:
+            invalid = checkTypeTree(((QuantifierNode)node).target, typeMask, encloseMask, anchorMask);
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            if ((en.type & encloseMask) == 0) return true;
+            invalid = checkTypeTree(en.target, typeMask, encloseMask, anchorMask);
+            break;
+
+        case NodeType.ANCHOR:
+            AnchorNode an = (AnchorNode)node;
+            if ((an.type & anchorMask) == 0) return true;
+
+            if (an.target != null) invalid = checkTypeTree(an.target, typeMask, encloseMask, anchorMask);
+            break;
+
+        default:
+            break;
+
+        } // switch
+
+        return invalid;
+    }
+
+    private static final int RECURSION_EXIST       = 1;
+    private static final int RECURSION_INFINITE    = 2;
+    private int subexpInfRecursiveCheck(Node node, boolean head) {
+        int r = 0;
+
+        switch (node.getType()) {
+        case NodeType.LIST:
+            int min;
+            ConsAltNode x = (ConsAltNode)node;
+            do {
+                int ret = subexpInfRecursiveCheck(x.car, head);
+                if (ret == RECURSION_INFINITE) return ret;
+                r |= ret;
+                if (head) {
+                    min = getMinMatchLength(x.car);
+                    if (min != 0) head = false;
+                }
+            } while ((x = x.cdr) != null);
+            break;
+
+        case NodeType.ALT:
+            ConsAltNode can = (ConsAltNode)node;
+            r = RECURSION_EXIST;
+            do {
+                int ret = subexpInfRecursiveCheck(can.car, head);
+                if (ret == RECURSION_INFINITE) return ret;
+                r &= ret;
+            } while ((can = can.cdr) != null);
+            break;
+
+        case NodeType.QTFR:
+            QuantifierNode qn = (QuantifierNode)node;
+            r = subexpInfRecursiveCheck(qn.target, head);
+            if (r == RECURSION_EXIST) {
+                if (qn.lower == 0) r = 0;
+            }
+            break;
+
+        case NodeType.ANCHOR:
+            AnchorNode an = (AnchorNode)node;
+            switch (an.type) {
+            case AnchorType.PREC_READ:
+            case AnchorType.PREC_READ_NOT:
+            case AnchorType.LOOK_BEHIND:
+            case AnchorType.LOOK_BEHIND_NOT:
+                r = subexpInfRecursiveCheck(an.target, head);
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.CALL:
+            r = subexpInfRecursiveCheck(((CallNode)node).target, head);
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            if (en.isMark2()) {
+                return 0;
+            } else if (en.isMark1()) {
+                return !head ? RECURSION_EXIST : RECURSION_INFINITE;
+                // throw exception here ???
+            } else {
+                en.setMark2();
+                r = subexpInfRecursiveCheck(en.target, head);
+                en.clearMark2();
+            }
+            break;
+
+        default:
+            break;
+        } // switch
+        return r;
+    }
+
+    protected final int subexpInfRecursiveCheckTrav(Node node) {
+        int r = 0;
+
+        switch (node.getType()) {
+        case NodeType.LIST:
+        case NodeType.ALT:
+            ConsAltNode can = (ConsAltNode)node;
+            do {
+                r = subexpInfRecursiveCheckTrav(can.car);
+            } while (r == 0 && (can = can.cdr) != null);
+            break;
+
+        case NodeType.QTFR:
+            r = subexpInfRecursiveCheckTrav(((QuantifierNode)node).target);
+            break;
+
+        case NodeType.ANCHOR:
+            AnchorNode an = (AnchorNode)node;
+            switch (an.type) {
+            case AnchorType.PREC_READ:
+            case AnchorType.PREC_READ_NOT:
+            case AnchorType.LOOK_BEHIND:
+            case AnchorType.LOOK_BEHIND_NOT:
+                r = subexpInfRecursiveCheckTrav(an.target);
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            if (en.isRecursion()) {
+                en.setMark1();
+                r = subexpInfRecursiveCheck(en.target, true);
+                if (r > 0) newValueException(ERR_NEVER_ENDING_RECURSION);
+                en.clearMark1();
+            }
+            r = subexpInfRecursiveCheckTrav(en.target);
+            break;
+
+        default:
+            break;
+        } // switch
+
+        return r;
+    }
+
+    private int subexpRecursiveCheck(Node node) {
+        int r = 0;
+
+        switch (node.getType()) {
+        case NodeType.LIST:
+        case NodeType.ALT:
+            ConsAltNode can = (ConsAltNode)node;
+            do {
+                r |= subexpRecursiveCheck(can.car);
+            } while ((can = can.cdr) != null);
+            break;
+
+        case NodeType.QTFR:
+            r = subexpRecursiveCheck(((QuantifierNode)node).target);
+            break;
+
+        case NodeType.ANCHOR:
+            AnchorNode an = (AnchorNode)node;
+            switch (an.type) {
+            case AnchorType.PREC_READ:
+            case AnchorType.PREC_READ_NOT:
+            case AnchorType.LOOK_BEHIND:
+            case AnchorType.LOOK_BEHIND_NOT:
+                r = subexpRecursiveCheck(an.target);
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.CALL:
+            CallNode cn = (CallNode)node;
+            r = subexpRecursiveCheck(cn.target);
+            if (r != 0) cn.setRecursion();
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            if (en.isMark2()) {
+                return 0;
+            } else if (en.isMark1()) {
+                return 1; /* recursion */
+            } else {
+                en.setMark2();
+                r = subexpRecursiveCheck(en.target);
+                en.clearMark2();
+            }
+            break;
+
+        default:
+            break;
+        } // switch
+
+        return r;
+    }
+
+    private static final int FOUND_CALLED_NODE  = 1;
+    protected final int subexpRecursiveCheckTrav(Node node) {
+        int r = 0;
+
+        switch (node.getType()) {
+        case NodeType.LIST:
+        case NodeType.ALT:
+            ConsAltNode can = (ConsAltNode)node;
+            do {
+                int ret = subexpRecursiveCheckTrav(can.car);
+                if (ret == FOUND_CALLED_NODE) {
+                    r = FOUND_CALLED_NODE;
+                }
+                // else if (ret < 0) return ret; ???
+            } while ((can = can.cdr) != null);
+            break;
+
+        case NodeType.QTFR:
+            QuantifierNode qn = (QuantifierNode)node;
+            r = subexpRecursiveCheckTrav(qn.target);
+            if (qn.upper == 0) {
+                if (r == FOUND_CALLED_NODE) qn.isRefered = true;
+            }
+            break;
+
+        case NodeType.ANCHOR:
+            AnchorNode an = (AnchorNode)node;
+            switch (an.type) {
+            case AnchorType.PREC_READ:
+            case AnchorType.PREC_READ_NOT:
+            case AnchorType.LOOK_BEHIND:
+            case AnchorType.LOOK_BEHIND_NOT:
+                r = subexpRecursiveCheckTrav(an.target);
+                break;
+            } // inner switch
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            if (!en.isRecursion()) {
+                if (en.isCalled()) {
+                    en.setMark1();
+                    r = subexpRecursiveCheck(en.target);
+                    if (r != 0) en.setRecursion();
+                    en.clearMark1();
+                }
+            }
+            r = subexpRecursiveCheckTrav(en.target);
+            if (en.isCalled()) r |= FOUND_CALLED_NODE;
+            break;
+
+        default:
+            break;
+        } // switch
+
+        return r;
+    }
+
+    private void setCallAttr(CallNode cn) {
+        cn.target = env.memNodes[cn.groupNum]; // no setTarget in call nodes!
+        if (cn.target == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
+
+        ((EncloseNode)cn.target).setCalled();
+        env.btMemStart = BitStatus.bsOnAt(env.btMemStart, cn.groupNum);
+        cn.unsetAddrList = env.unsetAddrList;
+    }
+
+    protected final void setupSubExpCall(Node node) {
+
+        switch(node.getType()) {
+        case NodeType.LIST:
+            ConsAltNode ln = (ConsAltNode)node;
+            do {
+                setupSubExpCall(ln.car);
+            } while ((ln = ln.cdr) != null);
+            break;
+
+        case NodeType.ALT:
+            ConsAltNode can = (ConsAltNode)node;
+            do {
+                setupSubExpCall(can.car);
+            } while ((can = can.cdr) != null);
+            break;
+
+        case NodeType.QTFR:
+            setupSubExpCall(((QuantifierNode)node).target);
+            break;
+
+        case NodeType.ENCLOSE:
+            setupSubExpCall(((EncloseNode)node).target);
+            break;
+
+        case NodeType.CALL:
+            CallNode cn = (CallNode)node;
+
+            if (cn.groupNum != 0) {
+                int gNum = cn.groupNum;
+
+                if (Config.USE_NAMED_GROUP) {
+                    if (env.numNamed > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(env.option)) {
+                        newValueException(ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
+                    }
+                } // USE_NAMED_GROUP
+                if (gNum > env.numMem) newValueException(ERR_UNDEFINED_GROUP_REFERENCE, cn.nameP, cn.nameEnd);
+                setCallAttr(cn);
+            } else {
+                if (Config.USE_NAMED_GROUP) {
+                    NameEntry ne = regex.nameToGroupNumbers(cn.name, cn.nameP, cn.nameEnd);
+
+                    if (ne == null) {
+                        newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
+                    } else if (ne.backNum > 1) {
+                        newValueException(ERR_MULTIPLEX_DEFINITION_NAME_CALL, cn.nameP, cn.nameEnd);
+                    } else {
+                        cn.groupNum = ne.backRef1; // ne.backNum == 1 ? ne.backRef1 : ne.backRefs[0]; // ??? need to check ?
+                        setCallAttr(cn);
+                    }
+                }
+            }
+            break;
+
+        case NodeType.ANCHOR:
+            AnchorNode an = (AnchorNode)node;
+            switch (an.type) {
+            case AnchorType.PREC_READ:
+            case AnchorType.PREC_READ_NOT:
+            case AnchorType.LOOK_BEHIND:
+            case AnchorType.LOOK_BEHIND_NOT:
+                setupSubExpCall(an.target);
+                break;
+            }
+            break;
+
+        } // switch
+    }
+
+    /* divide different length alternatives in look-behind.
+    (?<=A|B) ==> (?<=A)|(?<=B)
+    (?<!A|B) ==> (?<!A)(?<!B)
+     */
+    private Node divideLookBehindAlternatives(Node node) {
+        AnchorNode an = (AnchorNode)node;
+        int anchorType = an.type;
+        Node head = an.target;
+        Node np = ((ConsAltNode)head).car;
+
+        swap(node, head);
+
+        Node tmp = node;
+        node = head;
+        head = tmp;
+
+        ((ConsAltNode)node).setCar(head);
+        ((AnchorNode)head).setTarget(np);
+        np = node;
+
+        while ((np = ((ConsAltNode)np).cdr) != null) {
+            AnchorNode insert = new AnchorNode(anchorType);
+            insert.setTarget(((ConsAltNode)np).car);
+            ((ConsAltNode)np).setCar(insert);
+        }
+
+        if (anchorType == AnchorType.LOOK_BEHIND_NOT) {
+            np = node;
+            do {
+                ((ConsAltNode)np).toListNode(); /* alt -> list */
+            } while ((np = ((ConsAltNode)np).cdr) != null);
+        }
+
+        return node;
+    }
+
+    private Node setupLookBehind(Node node) {
+        AnchorNode an = (AnchorNode)node;
+        int len = getCharLengthTree(an.target);
+        switch(returnCode) {
+        case 0:
+            an.charLength = len;
+            break;
+        case GET_CHAR_LEN_VARLEN:
+            newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+            break;
+        case GET_CHAR_LEN_TOP_ALT_VARLEN:
+            if (syntax.differentLengthAltLookBehind()) {
+                return divideLookBehindAlternatives(node);
+            } else {
+                newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+            }
+        }
+        return node;
+    }
+
+    private void nextSetup(Node node, Node nextNode) {
+        // retry:
+        retry: while(true) {
+
+        int type = node.getType();
+        if (type == NodeType.QTFR) {
+            QuantifierNode qn = (QuantifierNode)node;
+            if (qn.greedy && isRepeatInfinite(qn.upper)) {
+                if (Config.USE_QTFR_PEEK_NEXT) {
+                    StringNode n = (StringNode)getHeadValueNode(nextNode, true);
+                    /* '\0': for UTF-16BE etc... */
+                    if (n != null && n.chars[n.p] != 0) { // ?????????
+                        qn.nextHeadExact = n;
+                    }
+                } // USE_QTFR_PEEK_NEXT
+                /* automatic posseivation a*b ==> (?>a*)b */
+                if (qn.lower <= 1) {
+                    if (qn.target.isSimple()) {
+                        Node x = getHeadValueNode(qn.target, false);
+                        if (x != null) {
+                            Node y = getHeadValueNode(nextNode, false);
+                            if (y != null && isNotIncluded(x, y)) {
+                                EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); //onig_node_new_enclose
+                                en.setStopBtSimpleRepeat();
+                                //en.setTarget(qn.target); // optimize it ??
+                                swap(node, en);
+
+                                en.setTarget(node);
+                            }
+                        }
+                    }
+                }
+            }
+        } else if (type == NodeType.ENCLOSE) {
+            EncloseNode en = (EncloseNode)node;
+            if (en.isMemory()) {
+                node = en.target;
+                // !goto retry;!
+                continue retry;
+            }
+        }
+
+        break;
+        } // while
+    }
+
+    private void updateStringNodeCaseFoldMultiByte(StringNode sn) {
+        char[] chars = sn.chars;
+        int end = sn.end;
+        value = sn.p;
+        int sp = 0;
+        char buf;
+
+        while (value < end) {
+            int ovalue = value;
+            buf = Character.toLowerCase(chars[value++]);
+
+            if (chars[ovalue] != buf) {
+
+                char[] sbuf = new char[sn.length() << 1];
+                System.arraycopy(chars, sn.p, sbuf, 0, ovalue - sn.p);
+                value = ovalue;
+                while (value < end) {
+                    buf = Character.toLowerCase(chars[value++]);
+                    if (sp >= sbuf.length) {
+                        char[]tmp = new char[sbuf.length << 1];
+                        System.arraycopy(sbuf, 0, tmp, 0, sbuf.length);
+                        sbuf = tmp;
+                    }
+                    sbuf[sp++] = buf;
+                }
+                sn.set(sbuf, 0, sp);
+                return;
+            }
+            sp++;
+        }
+    }
+
+    private void updateStringNodeCaseFold(Node node) {
+        StringNode sn = (StringNode)node;
+        updateStringNodeCaseFoldMultiByte(sn);
+    }
+
+    private Node expandCaseFoldMakeRemString(char[] chars, int p, int end) {
+        StringNode node = new StringNode(chars, p, end);
+
+        updateStringNodeCaseFold(node);
+        node.setAmbig();
+        node.setDontGetOptInfo();
+        return node;
+    }
+
+    private boolean expandCaseFoldStringAlt(int itemNum, char[] items,
+                                              char[] chars, int p, int slen, int end, ObjPtr<Node> node) {
+
+        ConsAltNode altNode;
+        node.p = altNode = newAltNode(null, null);
+
+        StringNode snode = new StringNode(chars, p, p + slen);
+        altNode.setCar(snode);
+
+        for (int i=0; i<itemNum; i++) {
+            snode = new StringNode();
+
+            snode.catCode(items[i]);
+
+            ConsAltNode an = newAltNode(null, null);
+            an.setCar(snode);
+            altNode.setCdr(an);
+            altNode = an;
+        }
+        return false;
+    }
+
+    private static final int THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION = 8;
+    private Node expandCaseFoldString(Node node) {
+        StringNode sn = (StringNode)node;
+
+        if (sn.isAmbig() || sn.length() <= 0) return node;
+
+        char[] chars = sn.chars;
+        int p = sn.p;
+        int end = sn.end;
+        int altNum = 1;
+
+        ConsAltNode topRoot = null, root = null;
+        ObjPtr<Node> prevNode = new ObjPtr<Node>();
+        StringNode stringNode = null;
+
+        while (p < end) {
+            char[] items = EncodingHelper.caseFoldCodesByString(regex.caseFoldFlag, chars[p]);
+
+            if (items.length == 0) {
+                if (stringNode == null) {
+                    if (root == null && prevNode.p != null) {
+                        topRoot = root = ConsAltNode.listAdd(null, prevNode.p);
+                    }
+
+                    prevNode.p = stringNode = new StringNode(); // onig_node_new_str(NULL, NULL);
+
+                    if (root != null) ConsAltNode.listAdd(root, stringNode);
+
+                }
+
+                stringNode.cat(chars, p, p + 1);
+            } else {
+                altNum *= (items.length + 1);
+                if (altNum > THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION) break;
+
+                if (root == null && prevNode.p != null) {
+                    topRoot = root = ConsAltNode.listAdd(null, prevNode.p);
+                }
+
+                expandCaseFoldStringAlt(items.length, items, chars, p, 1, end, prevNode);
+                if (root != null) ConsAltNode.listAdd(root, prevNode.p);
+                stringNode = null;
+            }
+            p++;
+        }
+
+        if (p < end) {
+            Node srem = expandCaseFoldMakeRemString(chars, p, end);
+
+            if (prevNode.p != null && root == null) {
+                topRoot = root = ConsAltNode.listAdd(null, prevNode.p);
+            }
+
+            if (root == null) {
+                prevNode.p = srem;
+            } else {
+                ConsAltNode.listAdd(root, srem);
+            }
+        }
+        /* ending */
+        Node xnode = topRoot != null ? topRoot : prevNode.p;
+
+        swap(node, xnode);
+        return xnode;
+    }
+
+    private static final int CEC_THRES_NUM_BIG_REPEAT       = 512;
+    private static final int CEC_INFINITE_NUM               = 0x7fffffff;
+
+    private static final int CEC_IN_INFINITE_REPEAT         = (1<<0);
+    private static final int CEC_IN_FINITE_REPEAT           = (1<<1);
+    private static final int CEC_CONT_BIG_REPEAT            = (1<<2);
+
+    protected final int setupCombExpCheck(Node node, int state) {
+        int r = state;
+        int ret;
+
+        switch (node.getType()) {
+        case NodeType.LIST:
+            ConsAltNode ln = (ConsAltNode)node;
+
+            do {
+                r = setupCombExpCheck(ln.car, r);
+                //prev = ((ConsAltNode)node).car;
+            } while (r >= 0 && (ln = ln.cdr) != null);
+            break;
+
+        case NodeType.ALT:
+            ConsAltNode an = (ConsAltNode)node;
+            do {
+                ret = setupCombExpCheck(an.car, state);
+                r |= ret;
+            } while (ret >= 0 && (an = an.cdr) != null);
+            break;
+
+        case NodeType.QTFR:
+            QuantifierNode qn = (QuantifierNode)node;
+            int childState = state;
+            int addState = 0;
+            int varNum;
+
+            if (!isRepeatInfinite(qn.upper)) {
+                if (qn.upper > 1) {
+                    /* {0,1}, {1,1} are allowed */
+                    childState |= CEC_IN_FINITE_REPEAT;
+
+                    /* check (a*){n,m}, (a+){n,m} => (a*){n,n}, (a+){n,n} */
+                    if (env.backrefedMem == 0) {
+                        if (qn.target.getType() == NodeType.ENCLOSE) {
+                            EncloseNode en = (EncloseNode)qn.target;
+                            if (en.type == EncloseType.MEMORY) {
+                                if (en.target.getType() == NodeType.QTFR) {
+                                    QuantifierNode q = (QuantifierNode)en.target;
+                                    if (isRepeatInfinite(q.upper) && q.greedy == qn.greedy) {
+                                        qn.upper = qn.lower == 0 ? 1 : qn.lower;
+                                        if (qn.upper == 1) childState = state;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            if ((state & CEC_IN_FINITE_REPEAT) != 0) {
+                qn.combExpCheckNum = -1;
+            } else {
+                if (isRepeatInfinite(qn.upper)) {
+                    varNum = CEC_INFINITE_NUM;
+                    childState |= CEC_IN_INFINITE_REPEAT;
+                } else {
+                    varNum = qn.upper - qn.lower;
+                }
+
+                if (varNum >= CEC_THRES_NUM_BIG_REPEAT) addState |= CEC_CONT_BIG_REPEAT;
+
+                if (((state & CEC_IN_INFINITE_REPEAT) != 0 && varNum != 0) ||
+                   ((state & CEC_CONT_BIG_REPEAT) != 0 && varNum >= CEC_THRES_NUM_BIG_REPEAT)) {
+                    if (qn.combExpCheckNum == 0) {
+                        env.numCombExpCheck++;
+                        qn.combExpCheckNum = env.numCombExpCheck;
+                        if (env.currMaxRegNum > env.combExpMaxRegNum) {
+                            env.combExpMaxRegNum = env.currMaxRegNum;
+                        }
+                    }
+                }
+            }
+            r = setupCombExpCheck(qn.target, childState);
+            r |= addState;
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            switch( en.type) {
+            case EncloseNode.MEMORY:
+                if (env.currMaxRegNum < en.regNum) {
+                    env.currMaxRegNum = en.regNum;
+                }
+                r = setupCombExpCheck(en.target, state);
+                break;
+
+            default:
+                r = setupCombExpCheck(en.target, state);
+            } // inner switch
+            break;
+
+        case NodeType.CALL:
+            if (Config.USE_SUBEXP_CALL) {
+                CallNode cn = (CallNode)node;
+                if (cn.isRecursion()) {
+                    env.hasRecursion = true;
+                } else {
+                    r = setupCombExpCheck(cn.target, state);
+                }
+            } // USE_SUBEXP_CALL
+            break;
+
+        default:
+            break;
+
+        } // switch
+
+        return r;
+    }
+
+    private static final int IN_ALT                     = (1<<0);
+    private static final int IN_NOT                     = (1<<1);
+    private static final int IN_REPEAT                  = (1<<2);
+    private static final int IN_VAR_REPEAT              = (1<<3);
+    private static final int EXPAND_STRING_MAX_LENGTH   = 100;
+
+    /* setup_tree does the following work.
+    1. check empty loop. (set qn->target_empty_info)
+    2. expand ignore-case in char class.
+    3. set memory status bit flags. (reg->mem_stats)
+    4. set qn->head_exact for [push, exact] -> [push_or_jump_exact1, exact].
+    5. find invalid patterns in look-behind.
+    6. expand repeated string.
+    */
+    protected final Node setupTree(Node node, int state) {
+        restart: while (true) {
+        switch (node.getType()) {
+        case NodeType.LIST:
+            ConsAltNode lin = (ConsAltNode)node;
+            Node prev = null;
+            do {
+                setupTree(lin.car, state);
+                if (prev != null) {
+                    nextSetup(prev, lin.car);
+                }
+                prev = lin.car;
+            } while ((lin = lin.cdr) != null);
+            break;
+
+        case NodeType.ALT:
+            ConsAltNode aln = (ConsAltNode)node;
+            do {
+                setupTree(aln.car, (state | IN_ALT));
+            } while ((aln = aln.cdr) != null);
+            break;
+
+        case NodeType.CCLASS:
+            break;
+
+        case NodeType.STR:
+            if (isIgnoreCase(regex.options) && !((StringNode)node).isRaw()) {
+                node = expandCaseFoldString(node);
+            }
+            break;
+
+        case NodeType.CTYPE:
+        case NodeType.CANY:
+            break;
+
+        case NodeType.CALL: // if (Config.USE_SUBEXP_CALL) ?
+            break;
+
+        case NodeType.BREF:
+            BackRefNode br = (BackRefNode)node;
+            for (int i=0; i<br.backNum; i++) {
+                if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
+                env.backrefedMem = bsOnAt(env.backrefedMem, br.back[i]);
+                env.btMemStart = bsOnAt(env.btMemStart, br.back[i]);
+                if (Config.USE_BACKREF_WITH_LEVEL) {
+                    if (br.isNestLevel()) {
+                        env.btMemEnd = bsOnAt(env.btMemEnd, br.back[i]);
+                    }
+                } // USE_BACKREF_AT_LEVEL
+                ((EncloseNode)env.memNodes[br.back[i]]).setMemBackrefed();
+            }
+            break;
+
+        case NodeType.QTFR:
+            QuantifierNode qn = (QuantifierNode)node;
+            Node target = qn.target;
+
+            if ((state & IN_REPEAT) != 0) qn.setInRepeat();
+
+            if (isRepeatInfinite(qn.upper) || qn.lower >= 1) {
+                int d = getMinMatchLength(target);
+                if (d == 0) {
+                    qn.targetEmptyInfo = TargetInfo.IS_EMPTY;
+                    if (Config.USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT) {
+                        int info = quantifiersMemoryInfo(target);
+                        if (info > 0) qn.targetEmptyInfo = info;
+                    } // USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
+                    // strange stuff here (turned off)
+                }
+            }
+
+            state |= IN_REPEAT;
+            if (qn.lower != qn.upper) state |= IN_VAR_REPEAT;
+
+            target = setupTree(target, state);
+
+            /* expand string */
+            if (target.getType() == NodeType.STR) {
+                if (!isRepeatInfinite(qn.lower) && qn.lower == qn.upper &&
+                    qn.lower > 1 && qn.lower <= EXPAND_STRING_MAX_LENGTH) {
+                    StringNode sn = (StringNode)target;
+                    int len = sn.length();
+
+                    if (len * qn.lower <= EXPAND_STRING_MAX_LENGTH) {
+                        StringNode str = qn.convertToString(sn.flag);
+                        int n = qn.lower;
+                        for (int i = 0; i < n; i++) {
+                            str.cat(sn.chars, sn.p, sn.end);
+                        }
+                        break; /* break case NT_QTFR: */
+                    }
+
+                }
+            }
+            if (Config.USE_OP_PUSH_OR_JUMP_EXACT) {
+                if (qn.greedy && qn.targetEmptyInfo != 0) {
+                    if (target.getType() == NodeType.QTFR) {
+                        QuantifierNode tqn = (QuantifierNode)target;
+                        if (tqn.headExact != null) {
+                            qn.headExact = tqn.headExact;
+                            tqn.headExact = null;
+                        }
+                    } else {
+                        qn.headExact = getHeadValueNode(qn.target, true);
+                    }
+                }
+            } // USE_OP_PUSH_OR_JUMP_EXACT
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode en = (EncloseNode)node;
+            switch (en.type) {
+            case EncloseType.OPTION:
+                int options = regex.options;
+                regex.options = en.option;
+                setupTree(en.target, state);
+                regex.options = options;
+                break;
+
+            case EncloseType.MEMORY:
+                if ((state & (IN_ALT | IN_NOT | IN_VAR_REPEAT)) != 0) {
+                    env.btMemStart = bsOnAt(env.btMemStart, en.regNum);
+                    /* SET_ENCLOSE_STATUS(node, NST_MEM_IN_ALT_NOT); */
+
+                }
+                setupTree(en.target, state);
+                break;
+
+            case EncloseType.STOP_BACKTRACK:
+                setupTree(en.target, state);
+                if (en.target.getType() == NodeType.QTFR) {
+                    QuantifierNode tqn = (QuantifierNode)en.target;
+                    if (isRepeatInfinite(tqn.upper) && tqn.lower <= 1 && tqn.greedy) {
+                        /* (?>a*), a*+ etc... */
+                        if (tqn.target.isSimple()) en.setStopBtSimpleRepeat();
+                    }
+                }
+                break;
+
+            } // inner switch
+            break;
+
+        case NodeType.ANCHOR:
+            AnchorNode an = (AnchorNode)node;
+            switch (an.type) {
+            case AnchorType.PREC_READ:
+                setupTree(an.target, state);
+                break;
+
+            case AnchorType.PREC_READ_NOT:
+                setupTree(an.target, (state | IN_NOT));
+                break;
+
+            case AnchorType.LOOK_BEHIND:
+                if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+                node = setupLookBehind(node);
+                if (node.getType() != NodeType.ANCHOR) continue restart;
+                setupTree(((AnchorNode)node).target, state);
+                break;
+
+            case AnchorType.LOOK_BEHIND_NOT:
+                if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+                node = setupLookBehind(node);
+                if (node.getType() != NodeType.ANCHOR) continue restart;
+                setupTree(((AnchorNode)node).target, (state | IN_NOT));
+                break;
+
+            } // inner switch
+            break;
+        } // switch
+        return node;
+        } // restart: while
+    }
+
+    private static final int MAX_NODE_OPT_INFO_REF_COUNT   = 5;
+    private void optimizeNodeLeft(Node node, NodeOptInfo opt, OptEnvironment oenv) { // oenv remove, pass mmd
+        opt.clear();
+        opt.setBoundNode(oenv.mmd);
+
+        switch (node.getType()) {
+        case NodeType.LIST: {
+            OptEnvironment nenv = new OptEnvironment();
+            NodeOptInfo nopt = new NodeOptInfo();
+            nenv.copy(oenv);
+            ConsAltNode lin = (ConsAltNode)node;
+            do {
+                optimizeNodeLeft(lin.car, nopt, nenv);
+                nenv.mmd.add(nopt.length);
+                opt.concatLeftNode(nopt);
+            } while ((lin = lin.cdr) != null);
+            break;
+        }
+
+        case NodeType.ALT: {
+            NodeOptInfo nopt = new NodeOptInfo();
+            ConsAltNode aln = (ConsAltNode)node;
+            do {
+                optimizeNodeLeft(aln.car, nopt, oenv);
+                if (aln == node) {
+                    opt.copy(nopt);
+                } else {
+                    opt.altMerge(nopt, oenv);
+                }
+            } while ((aln = aln.cdr) != null);
+            break;
+        }
+
+        case NodeType.STR: {
+            StringNode sn = (StringNode)node;
+
+            int slen = sn.length();
+
+            if (!sn.isAmbig()) {
+                opt.exb.concatStr(sn.chars, sn.p, sn.end, sn.isRaw());
+
+                if (slen > 0) {
+                    opt.map.addChar(sn.chars[sn.p]);
+                }
+
+                opt.length.set(slen, slen);
+            } else {
+                int max;
+                if (sn.isDontGetOptInfo()) {
+                    max = sn.length();
+                } else {
+                    opt.exb.concatStr(sn.chars, sn.p, sn.end, sn.isRaw());
+                    opt.exb.ignoreCase = true;
+
+                    if (slen > 0) {
+                        opt.map.addCharAmb(sn.chars, sn.p, sn.end, oenv.caseFoldFlag);
+                    }
+
+                    max = slen;
+                }
+                opt.length.set(slen, max);
+            }
+
+            if (opt.exb.length == slen) {
+                opt.exb.reachEnd = true;
+            }
+            break;
+        }
+
+        case NodeType.CCLASS: {
+            CClassNode cc = (CClassNode)node;
+            /* no need to check ignore case. (setted in setup_tree()) */
+            if (cc.mbuf != null || cc.isNot()) {
+                opt.length.set(1, 1);
+            } else {
+                for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
+                    boolean z = cc.bs.at(i);
+                    if ((z && !cc.isNot()) || (!z && cc.isNot())) {
+                        opt.map.addChar(i);
+                    }
+                }
+                opt.length.set(1, 1);
+            }
+            break;
+        }
+
+        case NodeType.CTYPE: {
+            int min;
+            int max = 1;
+            if (max == 1) {
+                min = 1;
+                CTypeNode cn = (CTypeNode)node;
+
+                switch (cn.ctype) {
+                case CharacterType.WORD:
+                    if (cn.not) {
+                        for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
+                            if (!EncodingHelper.isWord(i)) {
+                                opt.map.addChar(i);
+                            }
+                        }
+                    } else {
+                        for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
+                            if (EncodingHelper.isWord(i)) {
+                                opt.map.addChar(i);
+                            }
+                        }
+                    }
+                    break;
+                } // inner switch
+            } else {
+                min = 1;
+            }
+            opt.length.set(min, max);
+            break;
+        }
+
+        case NodeType.CANY: {
+            opt.length.set(1, 1);
+            break;
+        }
+
+        case NodeType.ANCHOR: {
+            AnchorNode an = (AnchorNode)node;
+            switch (an.type) {
+            case AnchorType.BEGIN_BUF:
+            case AnchorType.BEGIN_POSITION:
+            case AnchorType.BEGIN_LINE:
+            case AnchorType.END_BUF:
+            case AnchorType.SEMI_END_BUF:
+            case AnchorType.END_LINE:
+                opt.anchor.add(an.type);
+                break;
+
+            case AnchorType.PREC_READ:
+                NodeOptInfo nopt = new NodeOptInfo();
+                optimizeNodeLeft(an.target, nopt, oenv);
+                if (nopt.exb.length > 0) {
+                    opt.expr.copy(nopt.exb);
+                } else if (nopt.exm.length > 0) {
+                    opt.expr.copy(nopt.exm);
+                }
+                opt.expr.reachEnd = false;
+                if (nopt.map.value > 0) opt.map.copy(nopt.map);
+                break;
+
+            case AnchorType.PREC_READ_NOT:
+            case AnchorType.LOOK_BEHIND:    /* Sorry, I can't make use of it. */
+            case AnchorType.LOOK_BEHIND_NOT:
+                break;
+
+            } // inner switch
+            break;
+        }
+
+        case NodeType.BREF: {
+            BackRefNode br = (BackRefNode)node;
+
+            if (br.isRecursion()) {
+                opt.length.set(0, MinMaxLen.INFINITE_DISTANCE);
+                break;
+            }
+
+            Node[]nodes = oenv.scanEnv.memNodes;
+
+            int min = getMinMatchLength(nodes[br.back[0]]);
+            int max = getMaxMatchLength(nodes[br.back[0]]);
+
+            for (int i=1; i<br.backNum; i++) {
+                int tmin = getMinMatchLength(nodes[br.back[i]]);
+                int tmax = getMaxMatchLength(nodes[br.back[i]]);
+                if (min > tmin) min = tmin;
+                if (max < tmax) max = tmax;
+            }
+            opt.length.set(min, max);
+            break;
+        }
+
+        case NodeType.CALL: {
+            if (Config.USE_SUBEXP_CALL) {
+                CallNode cn = (CallNode)node;
+                if (cn.isRecursion()) {
+                    opt.length.set(0, MinMaxLen.INFINITE_DISTANCE);
+                } else {
+                    int safe = oenv.options;
+                    oenv.options = ((EncloseNode)cn.target).option;
+                    optimizeNodeLeft(cn.target, opt, oenv);
+                    oenv.options = safe;
+                }
+            } // USE_SUBEXP_CALL
+            break;
+        }
+
+        case NodeType.QTFR: {
+            NodeOptInfo nopt = new NodeOptInfo();
+            QuantifierNode qn = (QuantifierNode)node;
+            optimizeNodeLeft(qn.target, nopt, oenv);
+            if (qn.lower == 0 && isRepeatInfinite(qn.upper)) {
+                if (oenv.mmd.max == 0 && qn.target.getType() == NodeType.CANY && qn.greedy) {
+                    if (isMultiline(oenv.options)) {
+                        opt.anchor.add(AnchorType.ANYCHAR_STAR_ML);
+                    } else {
+                        opt.anchor.add(AnchorType.ANYCHAR_STAR);
+                    }
+                }
+            } else {
+                if (qn.lower > 0) {
+                    opt.copy(nopt);
+                    if (nopt.exb.length > 0) {
+                        if (nopt.exb.reachEnd) {
+                            int i;
+                            for (i = 2; i <= qn.lower && !opt.exb.isFull(); i++) {
+                                opt.exb.concat(nopt.exb);
+                            }
+                            if (i < qn.lower) {
+                                opt.exb.reachEnd = false;
+                            }
+                        }
+                    }
+                    if (qn.lower != qn.upper) {
+                        opt.exb.reachEnd = false;
+                        opt.exm.reachEnd = false;
+                    }
+                    if (qn.lower > 1) {
+                        opt.exm.reachEnd = false;
+                    }
+
+                }
+            }
+            int min = MinMaxLen.distanceMultiply(nopt.length.min, qn.lower);
+            int max;
+            if (isRepeatInfinite(qn.upper)) {
+                max = nopt.length.max > 0 ? MinMaxLen.INFINITE_DISTANCE : 0;
+            } else {
+                max = MinMaxLen.distanceMultiply(nopt.length.max, qn.upper);
+            }
+            opt.length.set(min, max);
+            break;
+        }
+
+        case NodeType.ENCLOSE: {
+            EncloseNode en = (EncloseNode)node;
+            switch (en.type) {
+            case EncloseType.OPTION:
+                int save = oenv.options;
+                oenv.options = en.option;
+                optimizeNodeLeft(en.target, opt, oenv);
+                oenv.options = save;
+                break;
+
+            case EncloseType.MEMORY:
+                if (Config.USE_SUBEXP_CALL && ++en.optCount > MAX_NODE_OPT_INFO_REF_COUNT) {
+                    int min = 0;
+                    int max = MinMaxLen.INFINITE_DISTANCE;
+                    if (en.isMinFixed()) min = en.minLength;
+                    if (en.isMaxFixed()) max = en.maxLength;
+                    opt.length.set(min, max);
+                } else { // USE_SUBEXP_CALL
+                    optimizeNodeLeft(en.target, opt, oenv);
+                    if (opt.anchor.isSet(AnchorType.ANYCHAR_STAR_MASK)) {
+                        if (bsAt(oenv.scanEnv.backrefedMem, en.regNum)) {
+                            opt.anchor.remove(AnchorType.ANYCHAR_STAR_MASK);
+                        }
+                    }
+                }
+                break;
+
+            case EncloseType.STOP_BACKTRACK:
+                optimizeNodeLeft(en.target, opt, oenv);
+                break;
+            } // inner switch
+            break;
+        }
+
+        default:
+            newInternalException(ERR_PARSER_BUG);
+        } // switch
+    }
+
+    protected final void setOptimizedInfoFromTree(Node node) {
+        NodeOptInfo opt = new NodeOptInfo();
+        OptEnvironment oenv = new OptEnvironment();
+
+        oenv.options = regex.options;
+        oenv.caseFoldFlag = regex.caseFoldFlag;
+        oenv.scanEnv = env;
+        oenv.mmd.clear(); // ??
+
+        optimizeNodeLeft(node, opt, oenv);
+
+        regex.anchor = opt.anchor.leftAnchor & (AnchorType.BEGIN_BUF |
+                                                AnchorType.BEGIN_POSITION |
+                                                AnchorType.ANYCHAR_STAR |
+                                                AnchorType.ANYCHAR_STAR_ML);
+
+        regex.anchor |= opt.anchor.rightAnchor & (AnchorType.END_BUF |
+                                                  AnchorType.SEMI_END_BUF);
+
+        if ((regex.anchor & (AnchorType.END_BUF | AnchorType.SEMI_END_BUF)) != 0) {
+            regex.anchorDmin = opt.length.min;
+            regex.anchorDmax = opt.length.max;
+        }
+
+        if (opt.exb.length > 0 || opt.exm.length > 0) {
+            opt.exb.select(opt.exm);
+            if (opt.map.value > 0 && opt.exb.compare(opt.map) > 0) {
+                // !goto set_map;!
+                regex.setOptimizeMapInfo(opt.map);
+                regex.setSubAnchor(opt.map.anchor);
+            } else {
+                regex.setExactInfo(opt.exb);
+                regex.setSubAnchor(opt.exb.anchor);
+            }
+        } else if (opt.map.value > 0) {
+            // !set_map:!
+            regex.setOptimizeMapInfo(opt.map);
+            regex.setSubAnchor(opt.map.anchor);
+        } else {
+            regex.subAnchor |= opt.anchor.leftAnchor & AnchorType.BEGIN_LINE;
+            if (opt.length.max == 0) regex.subAnchor |= opt.anchor.rightAnchor & AnchorType.END_LINE;
+        }
+
+        if (Config.DEBUG_COMPILE || Config.DEBUG_MATCH) {
+            Config.log.println(regex.optimizeInfoToString());
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java
new file mode 100644
index 0000000..397b05c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java
@@ -0,0 +1,91 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
+
+final class ApplyCaseFold {
+
+    // i_apply_case_fold
+    public void apply(int from, int[]to, int length, Object o) {
+        ApplyCaseFoldArg arg = (ApplyCaseFoldArg)o;
+
+        ScanEnvironment env = arg.env;
+        CClassNode cc = arg.cc;
+        BitSet bs = cc.bs;
+
+        if (length == 1) {
+            boolean inCC = cc.isCodeInCC(from);
+
+            if (Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS) {
+                if ((inCC && !cc.isNot()) || (!inCC && cc.isNot())) {
+                    if (to[0] >= BitSet.SINGLE_BYTE_SIZE) {
+                        cc.addCodeRange(env, to[0], to[0]);
+                    } else {
+                        /* /(?i:[^A-C])/.match("a") ==> fail. */
+                        bs.set(to[0]);
+                    }
+                }
+            } else {
+                if (inCC) {
+                    if (to[0] >= BitSet.SINGLE_BYTE_SIZE) {
+                        if (cc.isNot()) cc.clearNotFlag();
+                        cc.addCodeRange(env, to[0], to[0]);
+                    } else {
+                        if (cc.isNot()) {
+                            bs.clear(to[0]);
+                        } else {
+                            bs.set(to[0]);
+                        }
+                    }
+                }
+            } // CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
+
+        } else {
+            if (cc.isCodeInCC(from) && (!Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS || !cc.isNot())) {
+                StringNode node = null;
+                for (int i=0; i<length; i++) {
+                    if (i == 0) {
+                        node = new StringNode();
+                        /* char-class expanded multi-char only
+                        compare with string folded at match time. */
+                        node.setAmbig();
+                    }
+                    node.catCode(to[i]);
+                }
+
+                ConsAltNode alt = ConsAltNode.newAltNode(node, null);
+
+                if (arg.tail == null) {
+                    arg.altRoot = alt;
+                } else {
+                    arg.tail.setCdr(alt);
+                }
+                arg.tail = alt;
+            }
+
+        }
+
+    }
+
+    static final ApplyCaseFold INSTANCE = new ApplyCaseFold();
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFoldArg.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFoldArg.java
new file mode 100644
index 0000000..e991aed
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFoldArg.java
@@ -0,0 +1,35 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
+
+public final class ApplyCaseFoldArg {
+    final ScanEnvironment env;
+    final CClassNode cc;
+    ConsAltNode altRoot;
+    ConsAltNode tail;
+
+    public ApplyCaseFoldArg(ScanEnvironment env, CClassNode cc) {
+        this.env = env;
+        this.cc = cc;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java
new file mode 100644
index 0000000..b559916
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java
@@ -0,0 +1,1263 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDynamic;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isMultiline;
+import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.isRepeatInfinite;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.OPSize;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
+
+final class ArrayCompiler extends Compiler {
+    private int[] code;
+    private int codeLength;
+
+    private char[][] templates;
+    private int templateNum;
+
+    ArrayCompiler(Analyser analyser) {
+        super(analyser);
+    }
+
+    @Override
+    protected final void prepare() {
+        int codeSize = Config.USE_STRING_TEMPLATES ? 8 : ((analyser.getEnd() - analyser.getBegin()) * 2 + 2);
+        code = new int[codeSize];
+        codeLength = 0;
+    }
+
+    @Override
+    protected final void finish() {
+        addOpcode(OPCode.END);
+        addOpcode(OPCode.FINISH); // for stack bottom
+
+        regex.code = code;
+        regex.codeLength = codeLength;
+        regex.templates = templates;
+        regex.templateNum = templateNum;
+        regex.factory = MatcherFactory.DEFAULT;
+
+        if (Config.USE_SUBEXP_CALL && analyser.env.unsetAddrList != null) {
+            analyser.env.unsetAddrList.fix(regex);
+            analyser.env.unsetAddrList = null;
+        }
+    }
+
+    @Override
+    protected void compileAltNode(ConsAltNode node) {
+        ConsAltNode aln = node;
+        int len = 0;
+
+        do {
+            len += compileLengthTree(aln.car);
+            if (aln.cdr != null) {
+                len += OPSize.PUSH + OPSize.JUMP;
+            }
+        } while ((aln = aln.cdr) != null);
+
+        int pos = codeLength + len;  /* goal position */
+
+        aln = node;
+        do {
+            len = compileLengthTree(aln.car);
+            if (aln.cdr != null) {
+                addOpcodeRelAddr(OPCode.PUSH, len + OPSize.JUMP);
+            }
+            compileTree(aln.car);
+            if (aln.cdr != null) {
+                len = pos - (codeLength + OPSize.JUMP);
+                addOpcodeRelAddr(OPCode.JUMP, len);
+            }
+        } while ((aln = aln.cdr) != null);
+    }
+
+    private boolean isNeedStrLenOpExact(int op) {
+        return  op == OPCode.EXACTN         ||
+                op == OPCode.EXACTMB2N      ||
+                op == OPCode.EXACTMB3N      ||
+                op == OPCode.EXACTMBN       ||
+                op == OPCode.EXACTN_IC      ||
+                op == OPCode.EXACTN_IC_SB;
+    }
+
+    private boolean opTemplated(int op) {
+        return isNeedStrLenOpExact(op);
+    }
+
+    private int selectStrOpcode(int mbLength, int strLength, boolean ignoreCase) {
+        int op;
+
+        if (ignoreCase) {
+            switch(strLength) {
+            case 1: op = OPCode.EXACT1_IC; break;
+            default:op = OPCode.EXACTN_IC; break;
+            } // switch
+        } else {
+            switch (mbLength) {
+            case 1:
+                switch (strLength) {
+                case 1: op = OPCode.EXACT1; break;
+                case 2: op = OPCode.EXACT2; break;
+                case 3: op = OPCode.EXACT3; break;
+                case 4: op = OPCode.EXACT4; break;
+                case 5: op = OPCode.EXACT5; break;
+                default:op = OPCode.EXACTN; break;
+                } // inner switch
+                break;
+            case 2:
+                switch (strLength) {
+                case 1: op = OPCode.EXACTMB2N1; break;
+                case 2: op = OPCode.EXACTMB2N2; break;
+                case 3: op = OPCode.EXACTMB2N3; break;
+                default:op = OPCode.EXACTMB2N;  break;
+                } // inner switch
+                break;
+            case 3:
+                op = OPCode.EXACTMB3N;
+                break;
+            default:
+                op = OPCode.EXACTMBN;
+            } // switch
+        }
+        return op;
+    }
+
+    private void compileTreeEmptyCheck(Node node, int emptyInfo) {
+        int savedNumNullCheck = regex.numNullCheck;
+
+        if (emptyInfo != 0) {
+            addOpcode(OPCode.NULL_CHECK_START);
+            addMemNum(regex.numNullCheck); /* NULL CHECK ID */
+            regex.numNullCheck++;
+        }
+
+        compileTree(node);
+
+        if (emptyInfo != 0) {
+            switch(emptyInfo) {
+            case TargetInfo.IS_EMPTY:
+                addOpcode(OPCode.NULL_CHECK_END);
+                break;
+            case TargetInfo.IS_EMPTY_MEM:
+                addOpcode(OPCode.NULL_CHECK_END_MEMST);
+                break;
+            case TargetInfo.IS_EMPTY_REC:
+                addOpcode(OPCode.NULL_CHECK_END_MEMST_PUSH);
+                break;
+            } // switch
+
+            addMemNum(savedNumNullCheck); /* NULL CHECK ID */
+        }
+    }
+
+    private int addCompileStringlength(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
+        int op = selectStrOpcode(mbLength, strLength, ignoreCase);
+        int len = OPSize.OPCODE;
+
+        if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
+            // string length, template index, template string pointer
+            len += OPSize.LENGTH + OPSize.INDEX + OPSize.INDEX;
+        } else {
+            if (isNeedStrLenOpExact(op)) len += OPSize.LENGTH;
+            len += mbLength * strLength;
+        }
+        if (op == OPCode.EXACTMBN) len += OPSize.LENGTH;
+        return len;
+    }
+
+    @Override
+    protected final void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
+        int op = selectStrOpcode(mbLength, strLength, ignoreCase);
+        addOpcode(op);
+
+        if (op == OPCode.EXACTMBN) addLength(mbLength);
+
+        if (isNeedStrLenOpExact(op)) {
+            if (op == OPCode.EXACTN_IC || op == OPCode.EXACTN_IC_SB) {
+                addLength(mbLength * strLength);
+            } else {
+                addLength(strLength);
+            }
+        }
+
+        if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
+            addInt(templateNum);
+            addInt(p);
+            addTemplate(chars);
+        } else {
+            addChars(chars, p, mbLength * strLength);
+        }
+    }
+
+    private int compileLengthStringNode(Node node) {
+        StringNode sn = (StringNode)node;
+        if (sn.length() <= 0) return 0;
+        boolean ambig = sn.isAmbig();
+
+        int p, prev;
+        p = prev = sn.p;
+        int end = sn.end;
+        char[] chars = sn.chars;
+        p++;
+
+        int slen = 1;
+        int rlen = 0;
+
+        while (p < end) {
+            slen++;
+            p++;
+        }
+        int r = addCompileStringlength(chars, prev, 1, slen, ambig);
+        rlen += r;
+        return rlen;
+    }
+
+    private int compileLengthStringRawNode(StringNode sn) {
+        if (sn.length() <= 0) return 0;
+        return addCompileStringlength(sn.chars, sn.p, 1 /*sb*/, sn.length(), false);
+    }
+
+    private void addMultiByteCClass(CodeRangeBuffer mbuf) {
+        addLength(mbuf.used);
+        addInts(mbuf.p, mbuf.used);
+    }
+
+    private int compileLengthCClassNode(CClassNode cc) {
+        if (cc.isShare()) return OPSize.OPCODE + OPSize.POINTER;
+
+        int len;
+        if (cc.mbuf == null) {
+            len = OPSize.OPCODE + BitSet.BITSET_SIZE;
+        } else {
+            if (cc.bs.isEmpty()) {
+                len = OPSize.OPCODE;
+            } else {
+                len = OPSize.OPCODE + BitSet.BITSET_SIZE;
+            }
+
+            len += OPSize.LENGTH + cc.mbuf.used;
+        }
+        return len;
+    }
+
+    @Override
+    protected void compileCClassNode(CClassNode cc) {
+        if (cc.isShare()) { // shared char class
+            addOpcode(OPCode.CCLASS_NODE);
+            addPointer(cc);
+            return;
+        }
+
+        if (cc.mbuf == null) {
+            if (cc.isNot()) {
+                addOpcode(OPCode.CCLASS_NOT);
+            } else {
+                addOpcode(OPCode.CCLASS);
+            }
+            addInts(cc.bs.bits, BitSet.BITSET_SIZE); // add_bitset
+        } else {
+            if (cc.bs.isEmpty()) {
+                if (cc.isNot()) {
+                    addOpcode(OPCode.CCLASS_MB_NOT);
+                } else {
+                    addOpcode(OPCode.CCLASS_MB);
+                }
+                addMultiByteCClass(cc.mbuf);
+            } else {
+                if (cc.isNot()) {
+                    addOpcode(OPCode.CCLASS_MIX_NOT);
+                } else {
+                    addOpcode(OPCode.CCLASS_MIX);
+                }
+                // store the bit set and mbuf themself!
+                addInts(cc.bs.bits, BitSet.BITSET_SIZE); // add_bitset
+                addMultiByteCClass(cc.mbuf);
+            }
+        }
+    }
+
+    @Override
+    protected void compileCTypeNode(CTypeNode node) {
+        CTypeNode cn = node;
+        int op;
+        switch (cn.ctype) {
+        case CharacterType.WORD:
+            if (cn.not) {
+                op = OPCode.NOT_WORD;
+            } else {
+                op = OPCode.WORD;
+            }
+            break;
+
+        default:
+            newInternalException(ERR_PARSER_BUG);
+            return; // not reached
+        } // inner switch
+        addOpcode(op);
+    }
+
+    @Override
+    protected void compileAnyCharNode() {
+        if (isMultiline(regex.options)) {
+            addOpcode(OPCode.ANYCHAR_ML);
+        } else {
+            addOpcode(OPCode.ANYCHAR);
+        }
+    }
+
+    @Override
+    protected void compileCallNode(CallNode node) {
+        addOpcode(OPCode.CALL);
+        node.unsetAddrList.add(codeLength, node.target);
+        addAbsAddr(0); /*dummy addr.*/
+    }
+
+    @Override
+    protected void compileBackrefNode(BackRefNode node) {
+        BackRefNode br = node;
+        if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) {
+            addOpcode(OPCode.BACKREF_WITH_LEVEL);
+            addOption(regex.options & Option.IGNORECASE);
+            addLength(br.nestLevel);
+            // !goto add_bacref_mems;!
+            addLength(br.backNum);
+            for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
+            return;
+        } else { // USE_BACKREF_AT_LEVEL
+            if (br.backNum == 1) {
+                if (isIgnoreCase(regex.options)) {
+                    addOpcode(OPCode.BACKREFN_IC);
+                    addMemNum(br.back[0]);
+                } else {
+                    switch (br.back[0]) {
+                    case 1:
+                        addOpcode(OPCode.BACKREF1);
+                        break;
+                    case 2:
+                        addOpcode(OPCode.BACKREF2);
+                        break;
+                    default:
+                        addOpcode(OPCode.BACKREFN);
+                        addOpcode(br.back[0]);
+                        break;
+                    } // switch
+                }
+            } else {
+                if (isIgnoreCase(regex.options)) {
+                    addOpcode(OPCode.BACKREF_MULTI_IC);
+                } else {
+                    addOpcode(OPCode.BACKREF_MULTI);
+                }
+                // !add_bacref_mems:!
+                addLength(br.backNum);
+                for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
+            }
+        }
+    }
+
+    private static final int REPEAT_RANGE_ALLOC = 8;
+    private void entryRepeatRange(int id, int lower, int upper) {
+        if (regex.repeatRangeLo == null) {
+            regex.repeatRangeLo = new int[REPEAT_RANGE_ALLOC];
+            regex.repeatRangeHi = new int[REPEAT_RANGE_ALLOC];
+        } else if (id >= regex.repeatRangeLo.length){
+            int[]tmp = new int[regex.repeatRangeLo.length + REPEAT_RANGE_ALLOC];
+            System.arraycopy(regex.repeatRangeLo, 0, tmp, 0, regex.repeatRangeLo.length);
+            regex.repeatRangeLo = tmp;
+            tmp = new int[regex.repeatRangeHi.length + REPEAT_RANGE_ALLOC];
+            System.arraycopy(regex.repeatRangeHi, 0, tmp, 0, regex.repeatRangeHi.length);
+            regex.repeatRangeHi = tmp;
+        }
+
+        regex.repeatRangeLo[id] = lower;
+        regex.repeatRangeHi[id] = isRepeatInfinite(upper) ? 0x7fffffff : upper;
+    }
+
+    private void compileRangeRepeatNode(QuantifierNode qn, int targetLen, int emptyInfo) {
+        int numRepeat = regex.numRepeat;
+        addOpcode(qn.greedy ? OPCode.REPEAT : OPCode.REPEAT_NG);
+        addMemNum(numRepeat); /* OP_REPEAT ID */
+        regex.numRepeat++;
+        addRelAddr(targetLen + OPSize.REPEAT_INC);
+
+        entryRepeatRange(numRepeat, qn.lower, qn.upper);
+
+        compileTreeEmptyCheck(qn.target, emptyInfo);
+
+        if ((Config.USE_SUBEXP_CALL && regex.numCall > 0) || qn.isInRepeat()) {
+            addOpcode(qn.greedy ? OPCode.REPEAT_INC_SG : OPCode.REPEAT_INC_NG_SG);
+        } else {
+            addOpcode(qn.greedy ? OPCode.REPEAT_INC : OPCode.REPEAT_INC_NG);
+        }
+
+        addMemNum(numRepeat); /* OP_REPEAT ID */
+    }
+
+    private static final int QUANTIFIER_EXPAND_LIMIT_SIZE   = 50; // was 50
+
+    private static boolean cknOn(int ckn) {
+        return ckn > 0;
+    }
+
+    private int compileCECLengthQuantifierNode(QuantifierNode qn) {
+        boolean infinite = isRepeatInfinite(qn.upper);
+        int emptyInfo = qn.targetEmptyInfo;
+
+        int tlen = compileLengthTree(qn.target);
+        int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
+        int cklen = cknOn(ckn) ? OPSize.STATE_CHECK_NUM : 0;
+
+        /* anychar repeat */
+        if (qn.target.getType() == NodeType.CANY) {
+            if (qn.greedy && infinite) {
+                if (qn.nextHeadExact != null && !cknOn(ckn)) {
+                    return OPSize.ANYCHAR_STAR_PEEK_NEXT + tlen * qn.lower + cklen;
+                } else {
+                    return OPSize.ANYCHAR_STAR + tlen * qn.lower + cklen;
+                }
+            }
+        }
+
+        int modTLen;
+        if (emptyInfo != 0) {
+            modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
+        } else {
+            modTLen = tlen;
+        }
+
+        int len;
+        if (infinite && qn.lower <= 1) {
+            if (qn.greedy) {
+                if (qn.lower == 1) {
+                    len = OPSize.JUMP;
+                } else {
+                    len = 0;
+                }
+                len += OPSize.PUSH + cklen + modTLen + OPSize.JUMP;
+            } else {
+                if (qn.lower == 0) {
+                    len = OPSize.JUMP;
+                } else {
+                    len = 0;
+                }
+                len += modTLen + OPSize.PUSH + cklen;
+            }
+        } else if (qn.upper == 0) {
+            if (qn.isRefered) { /* /(?<n>..){0}/ */
+                len = OPSize.JUMP + tlen;
+            } else {
+                len = 0;
+            }
+        } else if (qn.upper == 1 && qn.greedy) {
+            if (qn.lower == 0) {
+                if (cknOn(ckn)) {
+                    len = OPSize.STATE_CHECK_PUSH + tlen;
+                } else {
+                    len = OPSize.PUSH + tlen;
+                }
+            } else {
+                len = tlen;
+            }
+        } else if (!qn.greedy && qn.upper == 1 && qn.lower == 0) { /* '??' */
+            len = OPSize.PUSH + cklen + OPSize.JUMP + tlen;
+        } else {
+            len = OPSize.REPEAT_INC + modTLen + OPSize.OPCODE + OPSize.RELADDR + OPSize.MEMNUM;
+
+            if (cknOn(ckn)) {
+                len += OPSize.STATE_CHECK;
+            }
+        }
+        return len;
+    }
+
+    @Override
+    protected void compileCECQuantifierNode(QuantifierNode qn) {
+        boolean infinite = isRepeatInfinite(qn.upper);
+        int emptyInfo = qn.targetEmptyInfo;
+
+        int tlen = compileLengthTree(qn.target);
+
+        int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
+
+        if (qn.isAnyCharStar()) {
+            compileTreeNTimes(qn.target, qn.lower);
+            if (qn.nextHeadExact != null && !cknOn(ckn)) {
+                if (isMultiline(regex.options)) {
+                    addOpcode(OPCode.ANYCHAR_ML_STAR_PEEK_NEXT);
+                } else {
+                    addOpcode(OPCode.ANYCHAR_STAR_PEEK_NEXT);
+                }
+                if (cknOn(ckn)) {
+                    addStateCheckNum(ckn);
+                }
+                StringNode sn = (StringNode)qn.nextHeadExact;
+                addChars(sn.chars, sn.p, 1);
+                return;
+            } else {
+                if (isMultiline(regex.options)) {
+                    if (cknOn(ckn)) {
+                        addOpcode(OPCode.STATE_CHECK_ANYCHAR_ML_STAR);
+                    } else {
+                        addOpcode(OPCode.ANYCHAR_ML_STAR);
+                    }
+                } else {
+                    if (cknOn(ckn)) {
+                        addOpcode(OPCode.STATE_CHECK_ANYCHAR_STAR);
+                    } else {
+                        addOpcode(OPCode.ANYCHAR_STAR);
+                    }
+                }
+                if (cknOn(ckn)) {
+                    addStateCheckNum(ckn);
+                }
+                return;
+            }
+        }
+
+        int modTLen;
+        if (emptyInfo != 0) {
+            modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
+        } else {
+            modTLen = tlen;
+        }
+        if (infinite && qn.lower <= 1) {
+            if (qn.greedy) {
+                if (qn.lower == 1) {
+                    addOpcodeRelAddr(OPCode.JUMP, cknOn(ckn) ? OPSize.STATE_CHECK_PUSH :
+                                                                     OPSize.PUSH);
+                }
+                if (cknOn(ckn)) {
+                    addOpcode(OPCode.STATE_CHECK_PUSH);
+                    addStateCheckNum(ckn);
+                    addRelAddr(modTLen + OPSize.JUMP);
+                } else {
+                    addOpcodeRelAddr(OPCode.PUSH, modTLen + OPSize.JUMP);
+                }
+                compileTreeEmptyCheck(qn.target, emptyInfo);
+                addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + (cknOn(ckn) ?
+                                                                               OPSize.STATE_CHECK_PUSH :
+                                                                               OPSize.PUSH)));
+            } else {
+                if (qn.lower == 0) {
+                    addOpcodeRelAddr(OPCode.JUMP, modTLen);
+                }
+                compileTreeEmptyCheck(qn.target, emptyInfo);
+                if (cknOn(ckn)) {
+                    addOpcode(OPCode.STATE_CHECK_PUSH_OR_JUMP);
+                    addStateCheckNum(ckn);
+                    addRelAddr(-(modTLen + OPSize.STATE_CHECK_PUSH_OR_JUMP));
+                } else {
+                    addOpcodeRelAddr(OPCode.PUSH, -(modTLen + OPSize.PUSH));
+                }
+            }
+        } else if (qn.upper == 0) {
+            if (qn.isRefered) { /* /(?<n>..){0}/ */
+                addOpcodeRelAddr(OPCode.JUMP, tlen);
+                compileTree(qn.target);
+            } // else r=0 ???
+        } else if (qn.upper == 1 && qn.greedy) {
+            if (qn.lower == 0) {
+                if (cknOn(ckn)) {
+                    addOpcode(OPCode.STATE_CHECK_PUSH);
+                    addStateCheckNum(ckn);
+                    addRelAddr(tlen);
+                } else {
+                    addOpcodeRelAddr(OPCode.PUSH, tlen);
+                }
+            }
+            compileTree(qn.target);
+        } else if (!qn.greedy && qn.upper == 1 && qn.lower == 0){ /* '??' */
+            if (cknOn(ckn)) {
+                addOpcode(OPCode.STATE_CHECK_PUSH);
+                addStateCheckNum(ckn);
+                addRelAddr(OPSize.JUMP);
+            } else {
+                addOpcodeRelAddr(OPCode.PUSH, OPSize.JUMP);
+            }
+
+            addOpcodeRelAddr(OPCode.JUMP, tlen);
+            compileTree(qn.target);
+        } else {
+            compileRangeRepeatNode(qn, modTLen, emptyInfo);
+            if (cknOn(ckn)) {
+                addOpcode(OPCode.STATE_CHECK);
+                addStateCheckNum(ckn);
+            }
+        }
+    }
+
+    private int compileNonCECLengthQuantifierNode(QuantifierNode qn) {
+        boolean infinite = isRepeatInfinite(qn.upper);
+        int emptyInfo = qn.targetEmptyInfo;
+
+        int tlen = compileLengthTree(qn.target);
+
+        /* anychar repeat */
+        if (qn.target.getType() == NodeType.CANY) {
+            if (qn.greedy && infinite) {
+                if (qn.nextHeadExact != null) {
+                    return OPSize.ANYCHAR_STAR_PEEK_NEXT + tlen * qn.lower;
+                } else {
+                    return OPSize.ANYCHAR_STAR + tlen * qn.lower;
+                }
+            }
+        }
+
+        int modTLen = 0;
+        if (emptyInfo != 0) {
+            modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
+        } else {
+            modTLen = tlen;
+        }
+
+        int len;
+        if (infinite && (qn.lower <= 1 || tlen * qn.lower <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
+            if (qn.lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
+                len = OPSize.JUMP;
+            } else {
+                len = tlen * qn.lower;
+            }
+
+            if (qn.greedy) {
+                if (qn.headExact != null) {
+                    len += OPSize.PUSH_OR_JUMP_EXACT1 + modTLen + OPSize.JUMP;
+                } else if (qn.nextHeadExact != null) {
+                    len += OPSize.PUSH_IF_PEEK_NEXT + modTLen + OPSize.JUMP;
+                } else {
+                    len += OPSize.PUSH + modTLen + OPSize.JUMP;
+                }
+            } else {
+                len += OPSize.JUMP + modTLen + OPSize.PUSH;
+            }
+
+        } else if (qn.upper == 0 && qn.isRefered) { /* /(?<n>..){0}/ */
+            len = OPSize.JUMP + tlen;
+        } else if (!infinite && qn.greedy &&
+                  (qn.upper == 1 || (tlen + OPSize.PUSH) * qn.upper <= QUANTIFIER_EXPAND_LIMIT_SIZE )) {
+            len = tlen * qn.lower;
+            len += (OPSize.PUSH + tlen) * (qn.upper - qn.lower);
+        } else if (!qn.greedy && qn.upper == 1 && qn.lower == 0) { /* '??' */
+            len = OPSize.PUSH + OPSize.JUMP + tlen;
+        } else {
+            len = OPSize.REPEAT_INC + modTLen + OPSize.OPCODE + OPSize.RELADDR + OPSize.MEMNUM;
+        }
+        return len;
+    }
+
+    @Override
+    protected void compileNonCECQuantifierNode(QuantifierNode qn) {
+        boolean infinite = isRepeatInfinite(qn.upper);
+        int emptyInfo = qn.targetEmptyInfo;
+
+        int tlen = compileLengthTree(qn.target);
+
+        if (qn.isAnyCharStar()) {
+            compileTreeNTimes(qn.target, qn.lower);
+            if (qn.nextHeadExact != null) {
+                if (isMultiline(regex.options)) {
+                    addOpcode(OPCode.ANYCHAR_ML_STAR_PEEK_NEXT);
+                } else {
+                    addOpcode(OPCode.ANYCHAR_STAR_PEEK_NEXT);
+                }
+                StringNode sn = (StringNode)qn.nextHeadExact;
+                addChars(sn.chars, sn.p, 1);
+                return;
+            } else {
+                if (isMultiline(regex.options)) {
+                    addOpcode(OPCode.ANYCHAR_ML_STAR);
+                } else {
+                    addOpcode(OPCode.ANYCHAR_STAR);
+                }
+                return;
+            }
+        }
+
+        int modTLen;
+        if (emptyInfo != 0) {
+            modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
+        } else {
+            modTLen = tlen;
+        }
+        if (infinite && (qn.lower <= 1 || tlen * qn.lower <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
+            if (qn.lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
+                if (qn.greedy) {
+                    if (qn.headExact != null) {
+                        addOpcodeRelAddr(OPCode.JUMP, OPSize.PUSH_OR_JUMP_EXACT1);
+                    } else if (qn.nextHeadExact != null) {
+                        addOpcodeRelAddr(OPCode.JUMP, OPSize.PUSH_IF_PEEK_NEXT);
+                    } else {
+                        addOpcodeRelAddr(OPCode.JUMP, OPSize.PUSH);
+                    }
+                } else {
+                    addOpcodeRelAddr(OPCode.JUMP, OPSize.JUMP);
+                }
+            } else {
+                compileTreeNTimes(qn.target, qn.lower);
+            }
+
+            if (qn.greedy) {
+                if (qn.headExact != null) {
+                    addOpcodeRelAddr(OPCode.PUSH_OR_JUMP_EXACT1, modTLen + OPSize.JUMP);
+                    StringNode sn = (StringNode)qn.headExact;
+                    addChars(sn.chars, sn.p, 1);
+                    compileTreeEmptyCheck(qn.target, emptyInfo);
+                    addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + OPSize.PUSH_OR_JUMP_EXACT1));
+                } else if (qn.nextHeadExact != null) {
+                    addOpcodeRelAddr(OPCode.PUSH_IF_PEEK_NEXT, modTLen + OPSize.JUMP);
+                    StringNode sn = (StringNode)qn.nextHeadExact;
+                    addChars(sn.chars, sn.p, 1);
+                    compileTreeEmptyCheck(qn.target, emptyInfo);
+                    addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + OPSize.PUSH_IF_PEEK_NEXT));
+                } else {
+                    addOpcodeRelAddr(OPCode.PUSH, modTLen + OPSize.JUMP);
+                    compileTreeEmptyCheck(qn.target, emptyInfo);
+                    addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + OPSize.PUSH));
+                }
+            } else {
+                addOpcodeRelAddr(OPCode.JUMP, modTLen);
+                compileTreeEmptyCheck(qn.target, emptyInfo);
+                addOpcodeRelAddr(OPCode.PUSH, -(modTLen + OPSize.PUSH));
+            }
+        } else if (qn.upper == 0 && qn.isRefered) { /* /(?<n>..){0}/ */
+            addOpcodeRelAddr(OPCode.JUMP, tlen);
+            compileTree(qn.target);
+        } else if (!infinite && qn.greedy &&
+                  (qn.upper == 1 || (tlen + OPSize.PUSH) * qn.upper <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
+            int n = qn.upper - qn.lower;
+            compileTreeNTimes(qn.target, qn.lower);
+
+            for (int i=0; i<n; i++) {
+                addOpcodeRelAddr(OPCode.PUSH, (n - i) * tlen + (n - i - 1) * OPSize.PUSH);
+                compileTree(qn.target);
+            }
+        } else if (!qn.greedy && qn.upper == 1 && qn.lower == 0) { /* '??' */
+            addOpcodeRelAddr(OPCode.PUSH, OPSize.JUMP);
+            addOpcodeRelAddr(OPCode.JUMP, tlen);
+            compileTree(qn.target);
+        } else {
+            compileRangeRepeatNode(qn, modTLen, emptyInfo);
+        }
+    }
+
+    private int compileLengthOptionNode(EncloseNode node) {
+        int prev = regex.options;
+        regex.options = node.option;
+        int tlen = compileLengthTree(node.target);
+        regex.options = prev;
+
+        if (isDynamic(prev ^ node.option)) {
+            return OPSize.SET_OPTION_PUSH + OPSize.SET_OPTION + OPSize.FAIL + tlen + OPSize.SET_OPTION;
+        } else {
+            return tlen;
+        }
+    }
+
+    @Override
+    protected void compileOptionNode(EncloseNode node) {
+        int prev = regex.options;
+
+        if (isDynamic(prev ^ node.option)) {
+            addOpcodeOption(OPCode.SET_OPTION_PUSH, node.option);
+            addOpcodeOption(OPCode.SET_OPTION, prev);
+            addOpcode(OPCode.FAIL);
+        }
+
+        regex.options = node.option;
+        compileTree(node.target);
+        regex.options = prev;
+
+        if (isDynamic(prev ^ node.option)) {
+            addOpcodeOption(OPCode.SET_OPTION, prev);
+        }
+    }
+
+    private int compileLengthEncloseNode(EncloseNode node) {
+        if (node.isOption()) {
+            return compileLengthOptionNode(node);
+        }
+
+        int tlen;
+        if (node.target != null) {
+            tlen = compileLengthTree(node.target);
+        } else {
+            tlen = 0;
+        }
+
+        int len;
+        switch (node.type) {
+        case EncloseType.MEMORY:
+            if (Config.USE_SUBEXP_CALL && node.isCalled()) {
+                len = OPSize.MEMORY_START_PUSH + tlen + OPSize.CALL + OPSize.JUMP + OPSize.RETURN;
+                if (bsAt(regex.btMemEnd, node.regNum)) {
+                    len += node.isRecursion() ? OPSize.MEMORY_END_PUSH_REC : OPSize.MEMORY_END_PUSH;
+                } else {
+                    len += node.isRecursion() ? OPSize.MEMORY_END_REC : OPSize.MEMORY_END;
+                }
+            } else { // USE_SUBEXP_CALL
+                if (bsAt(regex.btMemStart, node.regNum)) {
+                    len = OPSize.MEMORY_START_PUSH;
+                } else {
+                    len = OPSize.MEMORY_START;
+                }
+                len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END);
+            }
+            break;
+
+        case EncloseType.STOP_BACKTRACK:
+            if (node.isStopBtSimpleRepeat()) {
+                QuantifierNode qn = (QuantifierNode)node.target;
+                tlen = compileLengthTree(qn.target);
+                len = tlen * qn.lower + OPSize.PUSH + tlen + OPSize.POP + OPSize.JUMP;
+            } else {
+                len = OPSize.PUSH_STOP_BT + tlen + OPSize.POP_STOP_BT;
+            }
+            break;
+
+        default:
+            newInternalException(ERR_PARSER_BUG);
+            return 0; // not reached
+        } // switch
+        return len;
+    }
+
+    @Override
+    protected void compileEncloseNode(EncloseNode node) {
+        int len;
+        switch (node.type) {
+        case EncloseType.MEMORY:
+            if (Config.USE_SUBEXP_CALL) {
+                if (node.isCalled()) {
+                    addOpcode(OPCode.CALL);
+                    node.callAddr = codeLength + OPSize.ABSADDR + OPSize.JUMP;
+                    node.setAddrFixed();
+                    addAbsAddr(node.callAddr);
+                    len = compileLengthTree(node.target);
+                    len += OPSize.MEMORY_START_PUSH + OPSize.RETURN;
+                    if (bsAt(regex.btMemEnd, node.regNum)) {
+                        len += node.isRecursion() ? OPSize.MEMORY_END_PUSH_REC : OPSize.MEMORY_END_PUSH;
+                    } else {
+                        len += node.isRecursion() ? OPSize.MEMORY_END_REC : OPSize.MEMORY_END;
+                    }
+                    addOpcodeRelAddr(OPCode.JUMP, len);
+                }
+            } // USE_SUBEXP_CALL
+
+            if (bsAt(regex.btMemStart, node.regNum)) {
+                addOpcode(OPCode.MEMORY_START_PUSH);
+            } else {
+                addOpcode(OPCode.MEMORY_START);
+            }
+
+            addMemNum(node.regNum);
+            compileTree(node.target);
+
+            if (Config.USE_SUBEXP_CALL && node.isCalled()) {
+                if (bsAt(regex.btMemEnd, node.regNum)) {
+                    addOpcode(node.isRecursion() ? OPCode.MEMORY_END_PUSH_REC : OPCode.MEMORY_END_PUSH);
+                } else {
+                    addOpcode(node.isRecursion() ? OPCode.MEMORY_END_REC : OPCode.MEMORY_END);
+                }
+                addMemNum(node.regNum);
+                addOpcode(OPCode.RETURN);
+            } else { // USE_SUBEXP_CALL
+                if (bsAt(regex.btMemEnd, node.regNum)) {
+                    addOpcode(OPCode.MEMORY_END_PUSH);
+                } else {
+                    addOpcode(OPCode.MEMORY_END);
+                }
+                addMemNum(node.regNum);
+            }
+            break;
+
+        case EncloseType.STOP_BACKTRACK:
+            if (node.isStopBtSimpleRepeat()) {
+                QuantifierNode qn = (QuantifierNode)node.target;
+
+                compileTreeNTimes(qn.target, qn.lower);
+
+                len = compileLengthTree(qn.target);
+                addOpcodeRelAddr(OPCode.PUSH, len + OPSize.POP + OPSize.JUMP);
+                compileTree(qn.target);
+                addOpcode(OPCode.POP);
+                addOpcodeRelAddr(OPCode.JUMP, -(OPSize.PUSH + len + OPSize.POP + OPSize.JUMP));
+            } else {
+                addOpcode(OPCode.PUSH_STOP_BT);
+                compileTree(node.target);
+                addOpcode(OPCode.POP_STOP_BT);
+            }
+            break;
+
+        default:
+            newInternalException(ERR_PARSER_BUG);
+            break;
+        } // switch
+    }
+
+    private int compileLengthAnchorNode(AnchorNode node) {
+        int tlen;
+        if (node.target != null) {
+            tlen = compileLengthTree(node.target);
+        } else {
+            tlen = 0;
+        }
+
+        int len;
+        switch (node.type) {
+        case AnchorType.PREC_READ:
+            len = OPSize.PUSH_POS + tlen + OPSize.POP_POS;
+            break;
+
+        case AnchorType.PREC_READ_NOT:
+            len = OPSize.PUSH_POS_NOT + tlen + OPSize.FAIL_POS;
+            break;
+
+        case AnchorType.LOOK_BEHIND:
+            len = OPSize.LOOK_BEHIND + tlen;
+            break;
+
+        case AnchorType.LOOK_BEHIND_NOT:
+            len = OPSize.PUSH_LOOK_BEHIND_NOT + tlen + OPSize.FAIL_LOOK_BEHIND_NOT;
+            break;
+
+        default:
+            len = OPSize.OPCODE;
+            break;
+        } // switch
+        return len;
+    }
+
+    @Override
+    protected void compileAnchorNode(AnchorNode node) {
+        int len;
+        int n;
+
+        switch (node.type) {
+        case AnchorType.BEGIN_BUF:          addOpcode(OPCode.BEGIN_BUF);            break;
+        case AnchorType.END_BUF:            addOpcode(OPCode.END_BUF);              break;
+        case AnchorType.BEGIN_LINE:         addOpcode(OPCode.BEGIN_LINE);           break;
+        case AnchorType.END_LINE:           addOpcode(OPCode.END_LINE);             break;
+        case AnchorType.SEMI_END_BUF:       addOpcode(OPCode.SEMI_END_BUF);         break;
+        case AnchorType.BEGIN_POSITION:     addOpcode(OPCode.BEGIN_POSITION);       break;
+
+        case AnchorType.WORD_BOUND:
+            addOpcode(OPCode.WORD_BOUND);
+            break;
+
+        case AnchorType.NOT_WORD_BOUND:
+            addOpcode(OPCode.NOT_WORD_BOUND);
+            break;
+
+        case AnchorType.WORD_BEGIN:
+            if (Config.USE_WORD_BEGIN_END)
+                addOpcode(OPCode.WORD_BEGIN);
+            break;
+
+        case AnchorType.WORD_END:
+            if (Config.USE_WORD_BEGIN_END)
+                addOpcode(OPCode.WORD_END);
+            break;
+
+        case AnchorType.PREC_READ:
+            addOpcode(OPCode.PUSH_POS);
+            compileTree(node.target);
+            addOpcode(OPCode.POP_POS);
+            break;
+
+        case AnchorType.PREC_READ_NOT:
+            len = compileLengthTree(node.target);
+            addOpcodeRelAddr(OPCode.PUSH_POS_NOT, len + OPSize.FAIL_POS);
+            compileTree(node.target);
+            addOpcode(OPCode.FAIL_POS);
+            break;
+
+        case AnchorType.LOOK_BEHIND:
+            addOpcode(OPCode.LOOK_BEHIND);
+            if (node.charLength < 0) {
+                n = analyser.getCharLengthTree(node.target);
+                if (analyser.returnCode != 0) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+            } else {
+                n = node.charLength;
+            }
+            addLength(n);
+            compileTree(node.target);
+            break;
+
+        case AnchorType.LOOK_BEHIND_NOT:
+            len = compileLengthTree(node.target);
+            addOpcodeRelAddr(OPCode.PUSH_LOOK_BEHIND_NOT, len + OPSize.FAIL_LOOK_BEHIND_NOT);
+            if (node.charLength < 0) {
+                n = analyser.getCharLengthTree(node.target);
+                if (analyser.returnCode != 0) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+            } else {
+                n = node.charLength;
+            }
+            addLength(n);
+            compileTree(node.target);
+            addOpcode(OPCode.FAIL_LOOK_BEHIND_NOT);
+            break;
+
+        default:
+            newInternalException(ERR_PARSER_BUG);
+        } // switch
+    }
+
+    private int compileLengthTree(Node node) {
+        int len = 0;
+
+        switch (node.getType()) {
+        case NodeType.LIST:
+            ConsAltNode lin = (ConsAltNode)node;
+            do {
+                len += compileLengthTree(lin.car);
+            } while ((lin = lin.cdr) != null);
+            break;
+
+        case NodeType.ALT:
+            ConsAltNode aln = (ConsAltNode)node;
+            int n = 0;
+            do {
+                len += compileLengthTree(aln.car);
+                n++;
+            } while ((aln = aln.cdr) != null);
+            len += (OPSize.PUSH + OPSize.JUMP) * (n - 1);
+            break;
+
+        case NodeType.STR:
+            StringNode sn = (StringNode)node;
+            if (sn.isRaw()) {
+                len = compileLengthStringRawNode(sn);
+            } else {
+                len = compileLengthStringNode(sn);
+            }
+            break;
+
+        case NodeType.CCLASS:
+            len = compileLengthCClassNode((CClassNode)node);
+            break;
+
+        case NodeType.CTYPE:
+        case NodeType.CANY:
+            len = OPSize.OPCODE;
+            break;
+
+        case NodeType.BREF:
+            BackRefNode br = (BackRefNode)node;
+
+            if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) {
+                len = OPSize.OPCODE + OPSize.OPTION + OPSize.LENGTH +
+                      OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
+            } else { // USE_BACKREF_AT_LEVEL
+                if (br.backNum == 1) {
+                    len = ((!isIgnoreCase(regex.options) && br.back[0] <= 2)
+                            ? OPSize.OPCODE : (OPSize.OPCODE + OPSize.MEMNUM));
+                } else {
+                    len = OPSize.OPCODE + OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
+                }
+            }
+            break;
+
+        case NodeType.CALL:
+            if (Config.USE_SUBEXP_CALL) {
+                len = OPSize.CALL;
+                break;
+            } // USE_SUBEXP_CALL
+            break;
+
+        case NodeType.QTFR:
+            if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+                len = compileCECLengthQuantifierNode((QuantifierNode)node);
+            } else {
+                len = compileNonCECLengthQuantifierNode((QuantifierNode)node);
+            }
+            break;
+
+        case NodeType.ENCLOSE:
+            len = compileLengthEncloseNode((EncloseNode)node);
+            break;
+
+        case NodeType.ANCHOR:
+            len = compileLengthAnchorNode((AnchorNode)node);
+            break;
+
+        default:
+            newInternalException(ERR_PARSER_BUG);
+
+        } //switch
+        return len;
+    }
+
+    private void ensure(int size) {
+        if (size >= code.length) {
+            int length = code.length << 1;
+            while (length <= size) length <<= 1;
+            int[]tmp = new int[length];
+            System.arraycopy(code, 0, tmp, 0, code.length);
+            code = tmp;
+        }
+    }
+
+    private void addInt(int i) {
+        if (codeLength >= code.length) {
+            int[]tmp = new int[code.length << 1];
+            System.arraycopy(code, 0, tmp, 0, code.length);
+            code = tmp;
+        }
+        code[codeLength++] = i;
+    }
+
+    void setInt(int i, int offset) {
+        ensure(offset);
+        regex.code[offset] = i;
+    }
+
+    private void addObject(Object o) {
+        if (regex.operands == null) {
+            regex.operands = new Object[4];
+        } else if (regex.operandLength >= regex.operands.length) {
+            Object[]tmp = new Object[regex.operands.length << 1];
+            System.arraycopy(regex.operands, 0, tmp, 0, regex.operands.length);
+            regex.operands = tmp;
+        }
+        addInt(regex.operandLength);
+        regex.operands[regex.operandLength++] = o;
+    }
+
+    private void addChars(char[] chars, int p ,int length) {
+        ensure(codeLength + length);
+        int end = p + length;
+
+        while (p < end) code[codeLength++] = chars[p++];
+    }
+
+    private void addInts(int[]ints, int length) {
+        ensure(codeLength + length);
+        System.arraycopy(ints, 0, code, codeLength, length);
+        codeLength += length;
+    }
+
+    private void addOpcode(int opcode) {
+        addInt(opcode);
+
+        switch(opcode) {
+        case OPCode.ANYCHAR_STAR:
+        case OPCode.ANYCHAR_STAR_SB:
+        case OPCode.ANYCHAR_ML_STAR:
+        case OPCode.ANYCHAR_ML_STAR_SB:
+        case OPCode.ANYCHAR_STAR_PEEK_NEXT:
+        case OPCode.ANYCHAR_STAR_PEEK_NEXT_SB:
+        case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:
+        case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT_SB:
+        case OPCode.STATE_CHECK_ANYCHAR_STAR:
+        case OPCode.STATE_CHECK_ANYCHAR_STAR_SB:
+        case OPCode.STATE_CHECK_ANYCHAR_ML_STAR:
+        case OPCode.MEMORY_START_PUSH:
+        case OPCode.MEMORY_END_PUSH:
+        case OPCode.MEMORY_END_PUSH_REC:
+        case OPCode.MEMORY_END_REC:
+        case OPCode.NULL_CHECK_START:
+        case OPCode.NULL_CHECK_END_MEMST_PUSH:
+        case OPCode.PUSH:
+        case OPCode.STATE_CHECK_PUSH:
+        case OPCode.STATE_CHECK_PUSH_OR_JUMP:
+        case OPCode.STATE_CHECK:
+        case OPCode.PUSH_OR_JUMP_EXACT1:
+        case OPCode.PUSH_IF_PEEK_NEXT:
+        case OPCode.REPEAT:
+        case OPCode.REPEAT_NG:
+        case OPCode.REPEAT_INC_SG:
+        case OPCode.REPEAT_INC_NG:
+        case OPCode.REPEAT_INC_NG_SG:
+        case OPCode.PUSH_POS:
+        case OPCode.PUSH_POS_NOT:
+        case OPCode.PUSH_STOP_BT:
+        case OPCode.PUSH_LOOK_BEHIND_NOT:
+        case OPCode.CALL:
+        case OPCode.RETURN: // it will appear only with CALL though
+            regex.stackNeeded = true;
+        }
+    }
+
+    private void addStateCheckNum(int num) {
+        addInt(num);
+    }
+
+    private void addRelAddr(int addr) {
+        addInt(addr);
+    }
+
+    private void addAbsAddr(int addr) {
+        addInt(addr);
+    }
+
+    private void addLength(int length) {
+        addInt(length);
+    }
+
+    private void addMemNum(int num) {
+        addInt(num);
+    }
+
+    private void addPointer(Object o) {
+        addObject(o);
+    }
+
+    private void addOption(int option) {
+        addInt(option);
+    }
+
+    private void addOpcodeRelAddr(int opcode, int addr) {
+        addOpcode(opcode);
+        addRelAddr(addr);
+    }
+
+    private void addOpcodeOption(int opcode, int option) {
+        addOpcode(opcode);
+        addOption(option);
+    }
+
+    private void addTemplate(char[] chars) {
+        if (templateNum == 0) {
+            templates = new char[2][];
+        } else if (templateNum == templates.length) {
+            char[][] tmp = new char[templateNum * 2][];
+            System.arraycopy(templates, 0, tmp, 0, templateNum);
+            templates = tmp;
+        }
+        templates[templateNum++] = chars;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompiler.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompiler.java
new file mode 100644
index 0000000..475d659
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompiler.java
@@ -0,0 +1,109 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
+
+final class AsmCompiler extends AsmCompilerSupport {
+
+    public AsmCompiler(Analyser analyser) {
+        super(analyser);
+    }
+
+    @Override
+    protected void prepare() {
+        REG_NUM++;
+        prepareMachine();
+        prepareMachineInit();
+        prepareMachineMatch();
+
+        prepareFactory();
+        prepareFactoryInit();
+    }
+
+    @Override
+    protected void finish() {
+        setupFactoryInit();
+
+        setupMachineInit();
+        setupMachineMatch();
+
+        setupClasses();
+    }
+
+    @Override
+    protected void compileAltNode(ConsAltNode node) {
+    }
+
+    @Override
+    protected void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
+        String template = installTemplate(chars, p, strLength);
+    }
+
+    @Override
+    protected void compileCClassNode(CClassNode node) {
+        if (node.bs != null) {
+            String bitsetName = installBitSet(node.bs.bits);
+        }
+    }
+
+    @Override
+    protected void compileCTypeNode(CTypeNode node) {
+    }
+
+    @Override
+    protected void compileAnyCharNode() {
+    }
+
+    @Override
+    protected void compileBackrefNode(BackRefNode node) {
+    }
+
+    @Override
+    protected void compileCallNode(CallNode node) {
+    }
+
+    @Override
+    protected void compileCECQuantifierNode(QuantifierNode node) {
+    }
+
+    @Override
+    protected void compileNonCECQuantifierNode(QuantifierNode node) {
+    }
+
+    @Override
+    protected void compileOptionNode(EncloseNode node) {
+    }
+
+    @Override
+    protected void compileEncloseNode(EncloseNode node) {
+    }
+
+    @Override
+    protected void compileAnchorNode(AnchorNode node) {
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompilerSupport.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompilerSupport.java
new file mode 100644
index 0000000..06ca21a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompilerSupport.java
@@ -0,0 +1,267 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import jdk.nashorn.internal.runtime.regexp.joni.constants.AsmConstants;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConstants {
+    protected ClassWriter factory;      // matcher allocator, also bit set, code rage and string template container
+    protected MethodVisitor factoryInit;// factory constructor
+    protected String factoryName;
+
+    protected ClassWriter machine;      // matcher
+    protected MethodVisitor machineInit;// matcher constructor
+    protected MethodVisitor match;      // actual matcher implementation (the matchAt method)
+    protected String machineName;
+
+    // we will? try to manage visitMaxs ourselves for efficiency
+    protected int maxStack = 1;
+    protected int maxVars = LAST_INDEX;
+
+    // for field generation
+    protected int bitsets, ranges, templates;
+
+    // simple class name postfix scheme for now
+    static int REG_NUM = 0;
+
+    // dummy class loader for now
+    private static final class DummyClassLoader extends ClassLoader {
+        public Class<?> defineClass(String name, byte[] bytes) {
+            return super.defineClass(name, bytes, 0, bytes.length);
+        }
+    };
+
+    private static final DummyClassLoader loader = new DummyClassLoader();
+
+    AsmCompilerSupport(Analyser analyser) {
+        super(analyser);
+    }
+
+    protected final void prepareFactory() {
+        factory = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        factoryName = "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory" + REG_NUM;
+
+        factory.visit(V1_4, ACC_PUBLIC + ACC_FINAL, factoryName, null, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", null);
+
+        MethodVisitor create = factory.visitMethod(ACC_SYNTHETIC, "create", "(Lorg/joni/Regex;[BII)Lorg/joni/Matcher;", null, null);
+        create.visitTypeInsn(NEW, machineName);
+        create.visitInsn(DUP);          // instance
+        create.visitVarInsn(ALOAD, 1);  // Regex
+        create.visitVarInsn(ALOAD, 2);  // bytes[]
+        create.visitVarInsn(ILOAD, 3);  // p
+        create.visitVarInsn(ILOAD, 4);  // end
+        create.visitMethodInsn(INVOKESPECIAL, machineName, "<init>", "(Lorg/joni/Regex;[BII)V");
+        create.visitInsn(ARETURN);
+        create.visitMaxs(0, 0);
+        //create.visitMaxs(6, 5);
+        create.visitEnd();
+    }
+
+    protected final void prepareFactoryInit() {
+        factoryInit = factory.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+        factoryInit.visitVarInsn(ALOAD, 0);
+        factoryInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", "<init>", "()V");
+    }
+
+    protected final void setupFactoryInit() {
+        factoryInit.visitInsn(RETURN);
+        factoryInit.visitMaxs(0, 0);
+        //init.visitMaxs(1, 1);
+        factoryInit.visitEnd();
+    }
+
+    protected final void prepareMachine() {
+        machine = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        machineName = "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine" + REG_NUM;
+    }
+
+    protected final void prepareMachineInit() {
+        machine.visit(V1_4, ACC_PUBLIC + ACC_FINAL, machineName, null, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", null);
+        machineInit = machine.visitMethod(ACC_PROTECTED, "<init>", "(Lorg/joni/Regex;[BII)V", null, null);
+        machineInit.visitVarInsn(ALOAD, THIS);  // this
+        machineInit.visitVarInsn(ALOAD, 1);     // Regex
+        machineInit.visitVarInsn(ALOAD, 2);     // bytes[]
+        machineInit.visitVarInsn(ILOAD, 3);     // p
+        machineInit.visitVarInsn(ILOAD, 4);     // end
+        machineInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", "<init>", "(Lorg/joni/Regex;[BII)V");
+    }
+
+    protected final void setupMachineInit() {
+        if (bitsets + ranges + templates > 0) { // ok, some of these are in use, we'd like to cache the factory
+            machine.visitField(ACC_PRIVATE + ACC_FINAL, "factory", "L" + factoryName + ";", null, null);
+            machineInit.visitVarInsn(ALOAD, THIS);  // this
+            machineInit.visitVarInsn(ALOAD, 1);     // this, Regex
+            machineInit.visitFieldInsn(GETFIELD, "jdk/nashorn/internal/runtime/regexp/joni/Regex", "factory", "Lorg/joni/MatcherFactory;"); // this, factory
+            machineInit.visitTypeInsn(CHECKCAST, factoryName);
+            machineInit.visitFieldInsn(PUTFIELD, machineName, "factory", "L" + factoryName + ";"); // []
+        }
+
+        machineInit.visitInsn(RETURN);
+        machineInit.visitMaxs(0, 0);
+        //init.visitMaxs(5, 5);
+        machineInit.visitEnd();
+    }
+
+    protected final void prepareMachineMatch() {
+        match = machine.visitMethod(ACC_SYNTHETIC, "matchAt", "(III)I", null, null);
+        move(S, SSTART);        // s = sstart
+        load("bytes", "[B");    //
+        astore(BYTES);          // byte[]bytes = this.bytes
+    }
+
+    protected final void setupMachineMatch() {
+        match.visitInsn(ICONST_M1);
+        match.visitInsn(IRETURN);
+
+        match.visitMaxs(maxStack, maxVars);
+        match.visitEnd();
+    }
+
+    protected final void setupClasses() {
+        byte[]factoryCode = factory.toByteArray();
+        byte[]machineCode = machine.toByteArray();
+
+        if (Config.DEBUG_ASM) {
+            try {
+                FileOutputStream fos;
+                fos = new FileOutputStream(factoryName.substring(factoryName.lastIndexOf('/') + 1) + ".class");
+                fos.write(factoryCode);
+                fos.close();
+                fos = new FileOutputStream(machineName.substring(machineName.lastIndexOf('/') + 1) + ".class");
+                fos.write(machineCode);
+                fos.close();
+            } catch (IOException ioe) {
+                ioe.printStackTrace(Config.err);
+            }
+        }
+
+        loader.defineClass(machineName.replace('/', '.'), machineCode);
+        Class<?> cls = loader.defineClass(factoryName.replace('/', '.'), factoryCode);
+        try {
+            regex.factory = (MatcherFactory)cls.newInstance();
+        } catch(Exception e) {
+            e.printStackTrace(Config.err);
+        }
+    }
+
+    protected final void aload(int var) {
+        match.visitVarInsn(ALOAD, var);
+    }
+
+    protected final void astore(int var) {
+        match.visitVarInsn(ASTORE, var);
+    }
+
+    protected final void loadThis() {
+        match.visitVarInsn(ALOAD, THIS);
+    }
+
+    protected final void load(int var) {
+        match.visitVarInsn(ILOAD, var);
+    }
+
+    protected final void store(int var) {
+        match.visitVarInsn(ISTORE, var);
+    }
+
+    protected final void move(int to, int from) {
+        load(from);
+        store(to);
+    }
+
+    protected final void load(String field, String singature) {
+        loadThis();
+        match.visitFieldInsn(GETFIELD, machineName, field, singature);
+    }
+
+    protected final void load(String field) {
+        load(field, "I");
+    }
+
+    protected final void store(String field, String singature) {
+        loadThis();
+        match.visitFieldInsn(PUTFIELD, machineName, field, singature);
+    }
+
+    protected final void store(String field) {
+        store(field, "I");
+    }
+
+    protected final String installTemplate(char[] arr, int p, int length) {
+        String templateName = TEMPLATE + ++templates;
+        installArray(templateName, arr, p, length);
+        return templateName;
+    }
+
+    protected final String installCodeRange(int[]arr) {
+        String coreRangeName = CODERANGE + ++ranges;
+        installArray(coreRangeName, arr);
+        return coreRangeName;
+    }
+
+    protected final String installBitSet(int[]arr) {
+        String bitsetName = BITSET + ++bitsets;
+        installArray(bitsetName, arr);
+        return bitsetName;
+    }
+
+    private void installArray(String name, int[]arr) {
+        factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[I", null, null);
+        factoryInit.visitVarInsn(ALOAD, THIS);          // this;
+        loadInt(factoryInit, arr.length);               // this, length
+        factoryInit.visitIntInsn(NEWARRAY, T_INT);      // this, arr
+        for (int i=0;i < arr.length; i++) buildArray(i, arr[i], IASTORE);
+        factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[I");
+    }
+
+    private void installArray(String name, char[]arr, int p, int length) {
+        factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[B", null, null);
+        factoryInit.visitVarInsn(ALOAD, THIS);          // this;
+        loadInt(factoryInit, arr.length);               // this, length
+        factoryInit.visitIntInsn(NEWARRAY, T_BYTE);     // this, arr
+        for (int i=p, j=0; i < p + length; i++, j++) buildArray(j, arr[i] & 0xff, BASTORE);
+        factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[B");
+    }
+
+    private void buildArray(int index, int value, int type) {
+        factoryInit.visitInsn(DUP);     // ... arr, arr
+        loadInt(factoryInit, index);    // ... arr, arr, index
+        loadInt(factoryInit, value);    // ... arr, arr, index, value
+        factoryInit.visitInsn(type);    // ... arr
+    }
+
+    private void loadInt(MethodVisitor mv, int value) {
+        if (value >= -1 && value <= 5) {
+            mv.visitInsn(value + ICONST_0); // ICONST_0 == 3
+        } else if (value >= 6 && value <= 127 || value >= -128 && value <= -2) {
+            mv.visitIntInsn(BIPUSH, value);
+        } else if (value >= 128 && value <= 32767 || value >= -32768 && value <= -129) {
+            mv.visitIntInsn(SIPUSH, value);
+        } else {
+            mv.visitLdcInsn(new Integer(value));
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java
new file mode 100644
index 0000000..bf71598
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java
@@ -0,0 +1,115 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public final class BitSet {
+    static final int BITS_PER_BYTE = 8;
+    public static final int SINGLE_BYTE_SIZE = (1 << BITS_PER_BYTE);
+    private static final int BITS_IN_ROOM = 4 * BITS_PER_BYTE;
+    static final int BITSET_SIZE = (SINGLE_BYTE_SIZE / BITS_IN_ROOM);
+    static final int ROOM_SHIFT = log2(BITS_IN_ROOM);
+
+    final int[] bits = new int[BITSET_SIZE];
+
+    private static final int BITS_TO_STRING_WRAP = 4;
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append("BitSet");
+        for (int i=0; i<SINGLE_BYTE_SIZE; i++) {
+            if ((i % (SINGLE_BYTE_SIZE / BITS_TO_STRING_WRAP)) == 0) buffer.append("\n  ");
+            buffer.append(at(i) ? "1" : "0");
+        }
+        return buffer.toString();
+    }
+
+    public boolean at(int pos) {
+        return (bits[pos >>> ROOM_SHIFT] & bit(pos)) != 0;
+    }
+
+    public void set(int pos) {
+        bits[pos >>> ROOM_SHIFT] |= bit(pos);
+    }
+
+    public void clear(int pos) {
+        bits[pos >>> ROOM_SHIFT] &= ~bit(pos);
+    }
+
+    public void invert(int pos) {
+        bits[pos >>> ROOM_SHIFT] ^= bit(pos);
+    }
+
+    public void clear() {
+        for (int i=0; i<BITSET_SIZE; i++) bits[i]=0;
+    }
+
+    public boolean isEmpty() {
+        for (int i=0; i<BITSET_SIZE; i++) {
+            if (bits[i] != 0) return false;
+        }
+        return true;
+    }
+
+    public void setRange(int from, int to) {
+        for (int i=from; i<=to && i < SINGLE_BYTE_SIZE; i++) set(i);
+    }
+
+    public void setAll() {
+        for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~0;
+    }
+
+    public void invert() {
+        for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~bits[i];
+    }
+
+    public void invertTo(BitSet to) {
+        for (int i=0; i<BITSET_SIZE; i++) to.bits[i] = ~bits[i];
+    }
+
+    public void and(BitSet other) {
+        for (int i=0; i<BITSET_SIZE; i++) bits[i] &= other.bits[i];
+    }
+
+    public void or(BitSet other) {
+        for (int i=0; i<BITSET_SIZE; i++) bits[i] |= other.bits[i];
+    }
+
+    public void copy(BitSet other) {
+        for (int i=0; i<BITSET_SIZE; i++) bits[i] = other.bits[i];
+    }
+
+    public int numOn() {
+        int num = 0;
+        for (int i=0; i<SINGLE_BYTE_SIZE; i++) {
+            if (at(i)) num++;
+        }
+        return num;
+    }
+
+    static int bit(int pos){
+        return 1 << (pos % SINGLE_BYTE_SIZE);
+    }
+
+    private static int log2(int n){
+        int log = 0;
+        while ((n >>>= 1) != 0) log++;
+        return log;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitStatus.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitStatus.java
new file mode 100644
index 0000000..758a4e5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitStatus.java
@@ -0,0 +1,55 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+final class BitStatus {
+    public static final int BIT_STATUS_BITS_NUM = 4 * 8;
+
+    public static int bsClear() {
+        return 0;
+    }
+    public static int bsAll() {
+        return -1;
+    }
+    public static boolean bsAt(int stats, int n) {
+        return (n < BIT_STATUS_BITS_NUM ? stats & (1 << n) : (stats & 1)) != 0;
+    }
+    public static int bsOnAt(int stats, int n) {
+        if (n < BIT_STATUS_BITS_NUM) {
+            stats |= (1 << n);
+        } else {
+            stats |= 1;
+        }
+        return stats;
+    }
+    public static int bsOnAtSimple(int stats, int n) {
+        if (n < BIT_STATUS_BITS_NUM) stats |= (1 << n);
+        return stats;
+    }
+
+    public static int bsOnOff(int v, int f, boolean negative) {
+        if (negative) {
+            v &= ~f;
+        } else {
+            v |= f;
+        }
+        return v;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java
new file mode 100644
index 0000000..8aaabe2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java
@@ -0,0 +1,1462 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindCondition;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindLongest;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindNotEmpty;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotBol;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotEol;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isPosixRegion;
+import static jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper.isCrnl;
+import static jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper.isNewLine;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.OPSize;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+
+class ByteCodeMachine extends StackMachine {
+    private int bestLen;          // return value
+    private int s = 0;            // current char
+
+    private int range;            // right range
+    private int sprev;
+    private int sstart;
+    private int sbegin;
+
+    private final int[]code;        // byte code
+    private int ip;                 // instruction pointer
+
+    ByteCodeMachine(Regex regex, char[] chars, int p, int end) {
+        super(regex, chars, p, end);
+        this.code = regex.code;
+    }
+
+    protected int stkp; // a temporary
+    private boolean makeCaptureHistoryTree(CaptureTreeNode node) {
+        //CaptureTreeNode child;
+        int k = stkp;
+        //int k = kp;
+
+        while (k < stk) {
+            StackEntry e = stack[k];
+            if (e.type == MEM_START) {
+                int n = e.getMemNum();
+                if (n <= Config.MAX_CAPTURE_HISTORY_GROUP && bsAt(regex.captureHistory, n)) {
+                    CaptureTreeNode child = new CaptureTreeNode();
+                    child.group = n;
+                    child.beg = e.getMemPStr() - str;
+                    node.addChild(child);
+                    stkp = k + 1;
+                    if (makeCaptureHistoryTree(child)) return true;
+
+                    k = stkp;
+                    child.end = e.getMemPStr() - str;
+                }
+            } else if (e.type == MEM_END) {
+                if (e.getMemNum() == node.group) {
+                    node.end = e.getMemPStr() - str;
+                    stkp = k;
+                    return false;
+                }
+            }
+        }
+        return true; /* 1: root node ending. */
+    }
+
+    private void checkCaptureHistory(Region region) {
+        CaptureTreeNode node;
+        if (region.historyRoot == null) {
+            node = region.historyRoot = new CaptureTreeNode();
+        } else {
+            node = region.historyRoot;
+            node.clear();
+        }
+
+        // was clear ???
+        node.group = 0;
+        node.beg = sstart - str;
+        node.end = s      - str;
+
+        stkp = 0;
+        makeCaptureHistoryTree(region.historyRoot);
+    }
+
+    private boolean stringCmpIC(int caseFlodFlag, int s1, IntHolder ps2, int mbLen, int textEnd) {
+
+        int s2 = ps2.value;
+        int end1 = s1 + mbLen;
+
+        while (s1 < end1) {
+            char c1 = Character.toLowerCase(chars[s1++]);
+            char c2 = Character.toLowerCase(chars[s2++]);
+
+            if (c1 != c2) {
+                return false;
+            }
+        }
+        ps2.value = s2;
+        return true;
+    }
+
+    private void debugMatchBegin() {
+        Config.log.println("match_at: " +
+                "str: " + str +
+                ", end: " + end +
+                ", start: " + this.sstart +
+                ", sprev: " + this.sprev);
+        Config.log.println("size: " + (end - str) + ", start offset: " + (this.sstart - str));
+    }
+
+    private void debugMatchLoop() {
+        if (Config.DEBUG_MATCH) {
+            Config.log.printf("%4d", (s - str)).print("> \"");
+            int q, i;
+            for (i=0, q=s; i<7 && q<end && s>=0; i++) {
+                if (q < end) Config.log.print(new String(new char[]{chars[q++]}));
+            }
+            String str = q < end ? "...\"" : "\"";
+            q += str.length();
+            Config.log.print(str);
+            for (i=0; i<20-(q-s);i++) Config.log.print(" ");
+            StringBuilder sb = new StringBuilder();
+            new ByteCodePrinter(regex).compiledByteCodeToString(sb, ip);
+            Config.log.println(sb.toString());
+        }
+    }
+
+    protected final int matchAt(int range, int sstart, int sprev) {
+        this.range = range;
+        this.sstart = sstart;
+        this.sprev = sprev;
+
+        stk = 0;
+        ip = 0;
+
+        if (Config.DEBUG_MATCH) debugMatchBegin();
+
+        init();
+
+        bestLen = -1;
+        s = sstart;
+
+        final int[]code = this.code;
+        while (true) {
+            if (Config.DEBUG_MATCH) debugMatchLoop();
+
+            sbegin = s;
+            switch (code[ip++]) {
+                case OPCode.END:    if (opEnd()) return finish();                  break;
+                case OPCode.EXACT1:                     opExact1();                break;
+                case OPCode.EXACT2:                     opExact2();                continue;
+                case OPCode.EXACT3:                     opExact3();                continue;
+                case OPCode.EXACT4:                     opExact4();                continue;
+                case OPCode.EXACT5:                     opExact5();                continue;
+                case OPCode.EXACTN:                     opExactN();                continue;
+
+                case OPCode.EXACTMB2N1:                 opExactMB2N1();            break;
+                case OPCode.EXACTMB2N2:                 opExactMB2N2();            continue;
+                case OPCode.EXACTMB2N3:                 opExactMB2N3();            continue;
+                case OPCode.EXACTMB2N:                  opExactMB2N();             continue;
+                case OPCode.EXACTMB3N:                  opExactMB3N();             continue;
+                case OPCode.EXACTMBN:                   opExactMBN();              continue;
+
+                case OPCode.EXACT1_IC:                  opExact1IC();              break;
+                case OPCode.EXACTN_IC:                  opExactNIC();              continue;
+
+                case OPCode.CCLASS:                     opCClass();                break;
+                case OPCode.CCLASS_MB:                  opCClassMB();              break;
+                case OPCode.CCLASS_MIX:                 opCClassMIX();             break;
+                case OPCode.CCLASS_NOT:                 opCClassNot();             break;
+                case OPCode.CCLASS_MB_NOT:              opCClassMBNot();           break;
+                case OPCode.CCLASS_MIX_NOT:             opCClassMIXNot();          break;
+                case OPCode.CCLASS_NODE:                opCClassNode();            break;
+
+                case OPCode.ANYCHAR:                    opAnyChar();               break;
+                case OPCode.ANYCHAR_ML:                 opAnyCharML();             break;
+                case OPCode.ANYCHAR_STAR:               opAnyCharStar();           break;
+                case OPCode.ANYCHAR_ML_STAR:            opAnyCharMLStar();         break;
+                case OPCode.ANYCHAR_STAR_PEEK_NEXT:     opAnyCharStarPeekNext();   break;
+                case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:  opAnyCharMLStarPeekNext(); break;
+                case OPCode.STATE_CHECK_ANYCHAR_STAR:   opStateCheckAnyCharStar(); break;
+                case OPCode.STATE_CHECK_ANYCHAR_ML_STAR:opStateCheckAnyCharMLStar();break;
+
+                case OPCode.WORD:                       opWord();                  break;
+                case OPCode.NOT_WORD:                   opNotWord();               break;
+                case OPCode.WORD_BOUND:                 opWordBound();             continue;
+                case OPCode.NOT_WORD_BOUND:             opNotWordBound();          continue;
+                case OPCode.WORD_BEGIN:                 opWordBegin();             continue;
+                case OPCode.WORD_END:                   opWordEnd();               continue;
+
+                case OPCode.BEGIN_BUF:                  opBeginBuf();              continue;
+                case OPCode.END_BUF:                    opEndBuf();                continue;
+                case OPCode.BEGIN_LINE:                 opBeginLine();             continue;
+                case OPCode.END_LINE:                   opEndLine();               continue;
+                case OPCode.SEMI_END_BUF:               opSemiEndBuf();            continue;
+                case OPCode.BEGIN_POSITION:             opBeginPosition();         continue;
+
+                case OPCode.MEMORY_START_PUSH:          opMemoryStartPush();       continue;
+                case OPCode.MEMORY_START:               opMemoryStart();           continue;
+                case OPCode.MEMORY_END_PUSH:            opMemoryEndPush();         continue;
+                case OPCode.MEMORY_END:                 opMemoryEnd();             continue;
+                case OPCode.MEMORY_END_PUSH_REC:        opMemoryEndPushRec();      continue;
+                case OPCode.MEMORY_END_REC:             opMemoryEndRec();          continue;
+
+                case OPCode.BACKREF1:                   opBackRef1();              continue;
+                case OPCode.BACKREF2:                   opBackRef2();              continue;
+                case OPCode.BACKREFN:                   opBackRefN();              continue;
+                case OPCode.BACKREFN_IC:                opBackRefNIC();            continue;
+                case OPCode.BACKREF_MULTI:              opBackRefMulti();          continue;
+                case OPCode.BACKREF_MULTI_IC:           opBackRefMultiIC();        continue;
+                case OPCode.BACKREF_WITH_LEVEL:         opBackRefAtLevel();        continue;
+
+                case OPCode.NULL_CHECK_START:           opNullCheckStart();        continue;
+                case OPCode.NULL_CHECK_END:             opNullCheckEnd();          continue;
+                case OPCode.NULL_CHECK_END_MEMST:       opNullCheckEndMemST();     continue;
+                case OPCode.NULL_CHECK_END_MEMST_PUSH:  opNullCheckEndMemSTPush(); continue;
+
+                case OPCode.JUMP:                       opJump();                  continue;
+                case OPCode.PUSH:                       opPush();                  continue;
+
+                // CEC
+                case OPCode.STATE_CHECK_PUSH:           opStateCheckPush();        continue;
+                case OPCode.STATE_CHECK_PUSH_OR_JUMP:   opStateCheckPushOrJump();  continue;
+                case OPCode.STATE_CHECK:                opStateCheck();            continue;
+
+                case OPCode.POP:                        opPop();                   continue;
+                case OPCode.PUSH_OR_JUMP_EXACT1:        opPushOrJumpExact1();      continue;
+                case OPCode.PUSH_IF_PEEK_NEXT:          opPushIfPeekNext();        continue;
+
+                case OPCode.REPEAT:                     opRepeat();                continue;
+                case OPCode.REPEAT_NG:                  opRepeatNG();              continue;
+                case OPCode.REPEAT_INC:                 opRepeatInc();             continue;
+                case OPCode.REPEAT_INC_SG:              opRepeatIncSG();           continue;
+                case OPCode.REPEAT_INC_NG:              opRepeatIncNG();           continue;
+                case OPCode.REPEAT_INC_NG_SG:           opRepeatIncNGSG();         continue;
+
+                case OPCode.PUSH_POS:                   opPushPos();               continue;
+                case OPCode.POP_POS:                    opPopPos();                continue;
+                case OPCode.PUSH_POS_NOT:               opPushPosNot();            continue;
+                case OPCode.FAIL_POS:                   opFailPos();               continue;
+                case OPCode.PUSH_STOP_BT:               opPushStopBT();            continue;
+                case OPCode.POP_STOP_BT:                opPopStopBT();             continue;
+
+                case OPCode.LOOK_BEHIND:                opLookBehind();            continue;
+                case OPCode.PUSH_LOOK_BEHIND_NOT:       opPushLookBehindNot();     continue;
+                case OPCode.FAIL_LOOK_BEHIND_NOT:       opFailLookBehindNot();     continue;
+
+                // USE_SUBEXP_CALL
+                case OPCode.CALL:                       opCall();                  continue;
+                case OPCode.RETURN:                     opReturn();                continue;
+
+                case OPCode.FINISH:
+                    return finish();
+
+                case OPCode.FAIL:                       opFail();                  continue;
+
+                default:
+                    throw new InternalException(ErrorMessages.ERR_UNDEFINED_BYTECODE);
+
+            } // main switch
+        } // main while
+    }
+
+    private boolean opEnd() {
+        int n = s - sstart;
+
+        if (n > bestLen) {
+            if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
+                if (isFindLongest(regex.options)) {
+                    if (n > msaBestLen) {
+                        msaBestLen = n;
+                        msaBestS = sstart;
+                    } else {
+                        // goto end_best_len;
+                        return endBestLength();
+                    }
+                }
+            } // USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+
+            bestLen = n;
+            final Region region = msaRegion;
+            if (region != null) {
+                // USE_POSIX_REGION_OPTION ... else ...
+                region.beg[0] = msaBegin = sstart - str;
+                region.end[0] = msaEnd   = s      - str;
+                for (int i = 1; i <= regex.numMem; i++) {
+                    // opt!
+                    if (repeatStk[memEndStk + i] != INVALID_INDEX) {
+                        region.beg[i] = bsAt(regex.btMemStart, i) ?
+                                        stack[repeatStk[memStartStk + i]].getMemPStr() - str :
+                                        repeatStk[memStartStk + i] - str;
+
+
+                        region.end[i] = bsAt(regex.btMemEnd, i) ?
+                                        stack[repeatStk[memEndStk + i]].getMemPStr() :
+                                        repeatStk[memEndStk + i] - str;
+
+                    } else {
+                        region.beg[i] = region.end[i] = Region.REGION_NOTPOS;
+                    }
+
+                }
+
+                if (Config.USE_CAPTURE_HISTORY) {
+                    if (regex.captureHistory != 0) checkCaptureHistory(region);
+                }
+            } else {
+                msaBegin = sstart - str;
+                msaEnd   = s      - str;
+            }
+        } else {
+            Region region = msaRegion;
+            if (Config.USE_POSIX_API_REGION_OPTION) {
+                if (!isPosixRegion(regex.options)) {
+                    if (region != null) {
+                        region.clear();
+                    } else {
+                        msaBegin = msaEnd = 0;
+                    }
+                }
+            } else {
+                if (region != null) {
+                    region.clear();
+                } else {
+                    msaBegin = msaEnd = 0;
+                }
+            } // USE_POSIX_REGION_OPTION
+        }
+        // end_best_len:
+        /* default behavior: return first-matching result. */
+        return endBestLength();
+    }
+
+    private boolean endBestLength() {
+        if (isFindCondition(regex.options)) {
+            if (isFindNotEmpty(regex.options) && s == sstart) {
+                bestLen = -1;
+                {opFail(); return false;} /* for retry */
+            }
+            if (isFindLongest(regex.options) && s < range) {
+                {opFail(); return false;} /* for retry */
+            }
+        }
+        // goto finish;
+        return true;
+    }
+
+    private void opExact1() {
+        if (s >= range || code[ip] != chars[s++]) {opFail(); return;}
+        //if (s > range) {opFail(); return;}
+        ip++;
+        sprev = sbegin; // break;
+    }
+
+    private void opExact2() {
+        if (s + 2 > range) {opFail(); return;}
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        sprev = s;
+        ip++; s++;
+    }
+
+    private void opExact3() {
+        if (s + 3 > range) {opFail(); return;}
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        sprev = s;
+        ip++; s++;
+    }
+
+    private void opExact4() {
+        if (s + 4 > range) {opFail(); return;}
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        sprev = s;
+        ip++; s++;
+    }
+
+    private void opExact5() {
+        if (s + 5 > range) {opFail(); return;}
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        sprev = s;
+        ip++; s++;
+    }
+
+    private void opExactN() {
+        int tlen = code[ip++];
+        if (s + tlen > range) {opFail(); return;}
+
+        if (Config.USE_STRING_TEMPLATES) {
+            char[] bs = regex.templates[code[ip++]];
+            int ps = code[ip++];
+
+            while (tlen-- > 0) if (bs[ps++] != chars[s++]) {opFail(); return;}
+
+        } else {
+            while (tlen-- > 0) if (code[ip++] != chars[s++]) {opFail(); return;}
+        }
+        sprev = s - 1;
+    }
+
+    private void opExactMB2N1() {
+        if (s + 2 > range) {opFail(); return;}
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        sprev = sbegin; // break;
+    }
+
+    private void opExactMB2N2() {
+        if (s + 4 > range) {opFail(); return;}
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        sprev = s;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+   }
+
+    private void opExactMB2N3() {
+        if (s + 6 > range) {opFail(); return;}
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        sprev = s;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+        if (code[ip] != chars[s]) {opFail(); return;}
+        ip++; s++;
+    }
+
+    private void opExactMB2N() {
+        int tlen = code[ip++];
+        if (s + tlen * 2 > range) {opFail(); return;}
+
+        if (Config.USE_STRING_TEMPLATES) {
+            char[] bs = regex.templates[code[ip++]];
+            int ps = code[ip++];
+
+            while(tlen-- > 0) {
+                if (bs[ps] != chars[s]) {opFail(); return;}
+                ps++; s++;
+                if (bs[ps] != chars[s]) {opFail(); return;}
+                ps++; s++;
+            }
+        } else {
+            while(tlen-- > 0) {
+                if (code[ip] != chars[s]) {opFail(); return;}
+                ip++; s++;
+                if (code[ip] != chars[s]) {opFail(); return;}
+                ip++; s++;
+            }
+        }
+        sprev = s - 2;
+    }
+
+    private void opExactMB3N() {
+        int tlen = code[ip++];
+        if (s + tlen * 3 > range) {opFail(); return;}
+
+        if (Config.USE_STRING_TEMPLATES) {
+            char[] bs = regex.templates[code[ip++]];
+            int ps = code[ip++];
+
+            while (tlen-- > 0) {
+                if (bs[ps] != chars[s]) {opFail(); return;}
+                ps++; s++;
+                if (bs[ps] != chars[s]) {opFail(); return;}
+                ps++; s++;
+                if (bs[ps] != chars[s]) {opFail(); return;}
+                ps++; s++;
+            }
+        } else {
+            while (tlen-- > 0) {
+                if (code[ip] != chars[s]) {opFail(); return;}
+                ip++; s++;
+                if (code[ip] != chars[s]) {opFail(); return;}
+                ip++; s++;
+                if (code[ip] != chars[s]) {opFail(); return;}
+                ip++; s++;
+            }
+        }
+
+        sprev = s - 3;
+    }
+
+    private void opExactMBN() {
+        int tlen = code[ip++];   /* mb-len */
+        int tlen2= code[ip++];   /* string len */
+
+        tlen2 *= tlen;
+        if (s + tlen2 > range) {opFail(); return;}
+
+        if (Config.USE_STRING_TEMPLATES) {
+            char[] bs = regex.templates[code[ip++]];
+            int ps = code[ip++];
+
+            while (tlen2-- > 0) {
+                if (bs[ps] != chars[s]) {opFail(); return;}
+                ps++; s++;
+            }
+        } else {
+            while (tlen2-- > 0) {
+                if (code[ip] != chars[s]) {opFail(); return;}
+                ip++; s++;
+            }
+        }
+
+        sprev = s - tlen;
+    }
+
+    private void opExact1IC() {
+        if (s >= range || code[ip] != Character.toLowerCase(chars[s++])) {opFail(); return;}
+        ip++;
+        sprev = sbegin; // break;
+    }
+
+    private void opExactNIC() {
+        int tlen = code[ip++];
+        if (s + tlen > range) {opFail(); return;}
+
+        if (Config.USE_STRING_TEMPLATES) {
+            char[] bs = regex.templates[code[ip++]];
+            int ps = code[ip++];
+
+            while (tlen-- > 0) if (bs[ps++] != Character.toLowerCase(chars[s++])) {opFail(); return;}
+        } else {
+
+            while (tlen-- > 0) if (code[ip++] != Character.toLowerCase(chars[s++])) {opFail(); return;}
+        }
+        sprev = s - 1;
+    }
+
+    private boolean isInBitSet() {
+        int c = chars[s];
+        return (c <= 0xff && (code[ip + (c >>> BitSet.ROOM_SHIFT)] & (1 << c)) != 0);
+    }
+
+    private void opCClass() {
+        if (s >= range || !isInBitSet()) {opFail(); return;}
+        ip += BitSet.BITSET_SIZE;
+        s++;
+        sprev = sbegin; // break;
+    }
+
+    private boolean isInClassMB() {
+        int tlen = code[ip++];
+        if (s >= range) return false;
+        int ss = s;
+        s++;
+        int c = chars[ss];
+        if (!EncodingHelper.isInCodeRange(code, ip, c)) return false;
+        ip += tlen;
+        return true;
+    }
+
+    private void opCClassMB() {
+        // beyond string check
+        if (s >= range || chars[s] <= 0xff) {opFail(); return;}
+        if (!isInClassMB()) {opFail(); return;} // not!!!
+        sprev = sbegin; // break;
+    }
+
+    private void opCClassMIX() {
+        if (s >= range) {opFail(); return;}
+        if (chars[s] > 0xff) {
+            ip += BitSet.BITSET_SIZE;
+            if (!isInClassMB()) {opFail(); return;}
+        } else {
+            if (!isInBitSet()) {opFail(); return;}
+            ip += BitSet.BITSET_SIZE;
+            int tlen = code[ip++]; // by code range length
+            ip += tlen;
+            s++;
+        }
+        sprev = sbegin; // break;
+    }
+
+    private void opCClassNot() {
+        if (s >= range || isInBitSet()) {opFail(); return;}
+        ip += BitSet.BITSET_SIZE;
+        s++;
+        sprev = sbegin; // break;
+    }
+
+    private boolean isNotInClassMB() {
+        int tlen = code[ip++];
+
+        if (!(s + 1 <= range)) {
+            if (s >= range) return false;
+            s = end;
+            ip += tlen;
+            return true;
+        }
+
+        int ss = s;
+        s++;
+        int c = chars[ss];
+
+        if (EncodingHelper.isInCodeRange(code, ip, c)) return false;
+        ip += tlen;
+        return true;
+    }
+
+    private void opCClassMBNot() {
+        if (s >= range) {opFail(); return;}
+        if (chars[s] <= 0xff) {
+            s++;
+            int tlen = code[ip++];
+            ip += tlen;
+            sprev = sbegin; // break;
+            return;
+        }
+        if (!isNotInClassMB()) {opFail(); return;}
+        sprev = sbegin; // break;
+    }
+
+    private void opCClassMIXNot() {
+        if (s >= range) {opFail(); return;}
+        if (chars[s] > 0xff) {
+            ip += BitSet.BITSET_SIZE;
+            if (!isNotInClassMB()) {opFail(); return;}
+        } else {
+            if (isInBitSet()) {opFail(); return;}
+            ip += BitSet.BITSET_SIZE;
+            int tlen = code[ip++];
+            ip += tlen;
+            s++;
+        }
+        sprev = sbegin; // break;
+    }
+
+    private void opCClassNode() {
+        if (s >= range) {opFail(); return;}
+        CClassNode cc = (CClassNode)regex.operands[code[ip++]];
+        int ss = s;
+        s++;
+        int c = chars[ss];
+        if (!cc.isCodeInCCLength(c)) {opFail(); return;}
+        sprev = sbegin; // break;
+    }
+
+    private void opAnyChar() {
+        if (s >= range) {opFail(); return;}
+        if (chars[s] == EncodingHelper.NEW_LINE) {opFail(); return;}
+        s++;
+        sprev = sbegin; // break;
+    }
+
+    private void opAnyCharML() {
+        if (s >= range) {opFail(); return;}
+        s++;
+        sprev = sbegin; // break;
+    }
+
+    private void opAnyCharStar() {
+        final char[] chars = this.chars;
+        while (s < range) {
+            pushAlt(ip, s, sprev);
+            if (isNewLine(chars, s, end)) {opFail(); return;}
+            sprev = s;
+            s++;
+        }
+        sprev = sbegin; // break;
+    }
+
+    private void opAnyCharMLStar() {
+        while (s < range) {
+            pushAlt(ip, s, sprev);
+            sprev = s;
+            s++;
+        }
+        sprev = sbegin; // break;
+    }
+
+    private void opAnyCharStarPeekNext() {
+        final char c = (char)code[ip];
+        final char[] chars = this.chars;
+
+        while (s < range) {
+            char b = chars[s];
+            if (c == b) pushAlt(ip + 1, s, sprev);
+            if (b == EncodingHelper.NEW_LINE) {opFail(); return;}
+            sprev = s;
+            s++;
+        }
+        ip++;
+        sprev = sbegin; // break;
+    }
+
+    private void opAnyCharMLStarPeekNext() {
+        final char c = (char)code[ip];
+        final char[] chars = this.chars;
+
+        while (s < range) {
+            if (c == chars[s]) pushAlt(ip + 1, s, sprev);
+            sprev = s;
+            s++;
+        }
+        ip++;
+        sprev = sbegin; // break;
+    }
+
+    // CEC
+    private void opStateCheckAnyCharStar() {
+        int mem = code[ip++];
+        final char[] chars = this.chars;
+
+        while (s < range) {
+            if (stateCheckVal(s, mem)) {opFail(); return;}
+            pushAltWithStateCheck(ip, s, sprev, mem);
+            if (chars[s] == EncodingHelper.NEW_LINE) {opFail(); return;}
+            sprev = s;
+            s++;
+        }
+        sprev = sbegin; // break;
+    }
+
+    // CEC
+    private void opStateCheckAnyCharMLStar() {
+        int mem = code[ip++];
+
+        while (s < range) {
+            if (stateCheckVal(s, mem)) {opFail(); return;}
+            pushAltWithStateCheck(ip, s, sprev, mem);
+            sprev = s;
+            s++;
+        }
+        sprev = sbegin; // break;
+    }
+
+    private void opWord() {
+        if (s >= range || !EncodingHelper.isWord(chars[s])) {opFail(); return;}
+        s++;
+        sprev = sbegin; // break;
+    }
+
+    private void opNotWord() {
+        if (s >= range || EncodingHelper.isWord(chars[s])) {opFail(); return;}
+        s++;
+        sprev = sbegin; // break;
+    }
+
+    private void opWordBound() {
+        if (s == str) {
+            if (s >= range || !EncodingHelper.isWord(chars[s])) {opFail(); return;}
+        } else if (s == end) {
+            if (sprev >= end || !EncodingHelper.isWord(chars[sprev])) {opFail(); return;}
+        } else {
+            if (EncodingHelper.isWord(chars[s]) == EncodingHelper.isWord(chars[sprev])) {opFail(); return;}
+        }
+    }
+
+    private void opNotWordBound() {
+        if (s == str) {
+            if (s < range && EncodingHelper.isWord(chars[s])) {opFail(); return;}
+        } else if (s == end) {
+            if (sprev < end && EncodingHelper.isWord(chars[sprev])) {opFail(); return;}
+        } else {
+            if (EncodingHelper.isWord(chars[s]) != EncodingHelper.isWord(chars[sprev])) {opFail(); return;}
+        }
+    }
+
+    private void opWordBegin() {
+        if (s < range && EncodingHelper.isWord(chars[s])) {
+            if (s == str || !EncodingHelper.isWord(chars[sprev])) return;
+        }
+        opFail();
+    }
+
+    private void opWordEnd() {
+        if (s != str && EncodingHelper.isWord(chars[sprev])) {
+            if (s == end || !EncodingHelper.isWord(chars[s])) return;
+        }
+        opFail();
+    }
+
+    private void opBeginBuf() {
+        if (s != str) opFail();
+    }
+
+    private void opEndBuf() {
+        if (s != end) opFail();
+    }
+
+    private void opBeginLine() {
+        if (s == str) {
+            if (isNotBol(msaOptions)) opFail();
+            return;
+        } else if (EncodingHelper.isNewLine(chars, sprev, end) && s != end) {
+            return;
+        }
+        opFail();
+    }
+
+    private void opEndLine()  {
+        if (s == end) {
+            if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
+                if (str == end || !EncodingHelper.isNewLine(chars, sprev, end)) {
+                    if (isNotEol(msaOptions)) opFail();
+                }
+                return;
+            } else {
+                if (isNotEol(msaOptions)) opFail();
+                return;
+            }
+        } else if (isNewLine(chars, s, end) || (Config.USE_CRNL_AS_LINE_TERMINATOR && isCrnl(chars, s, end))) {
+            return;
+        }
+        opFail();
+    }
+
+    private void opSemiEndBuf() {
+        if (s == end) {
+            if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
+                if (str == end || !isNewLine(chars, sprev, end)) {
+                    if (isNotEol(msaOptions)) opFail();
+                }
+                return;
+            } else {
+                if (isNotEol(msaOptions)) opFail();
+                return;
+            }
+        } else if (isNewLine(chars, s, end) && s + 1 == end) {
+            return;
+        } else if (Config.USE_CRNL_AS_LINE_TERMINATOR && isCrnl(chars, s, end)) {
+            int ss = s + 2;
+            if (ss == end) return;
+        }
+        opFail();
+    }
+
+    private void opBeginPosition() {
+        if (s != msaStart) opFail();
+    }
+
+    private void opMemoryStartPush() {
+        int mem = code[ip++];
+        pushMemStart(mem, s);
+    }
+
+    private void opMemoryStart() {
+        int mem = code[ip++];
+        repeatStk[memStartStk + mem] = s;
+    }
+
+    private void opMemoryEndPush() {
+        int mem = code[ip++];
+        pushMemEnd(mem, s);
+    }
+
+    private void opMemoryEnd() {
+        int mem = code[ip++];
+        repeatStk[memEndStk + mem] = s;
+    }
+
+    private void opMemoryEndPushRec() {
+        int mem = code[ip++];
+        int stkp = getMemStart(mem); /* should be before push mem-end. */
+        pushMemEnd(mem, s);
+        repeatStk[memStartStk + mem] = stkp;
+    }
+
+    private void opMemoryEndRec() {
+        int mem = code[ip++];
+        repeatStk[memEndStk + mem] = s;
+        int stkp = getMemStart(mem);
+
+        if (BitStatus.bsAt(regex.btMemStart, mem)) {
+            repeatStk[memStartStk + mem] = stkp;
+        } else {
+            repeatStk[memStartStk + mem] = stack[stkp].getMemPStr();
+        }
+
+        pushMemEndMark(mem);
+    }
+
+    private boolean backrefInvalid(int mem) {
+        return repeatStk[memEndStk + mem] == INVALID_INDEX || repeatStk[memStartStk + mem] == INVALID_INDEX;
+    }
+
+    private int backrefStart(int mem) {
+        return bsAt(regex.btMemStart, mem) ? stack[repeatStk[memStartStk + mem]].getMemPStr() : repeatStk[memStartStk + mem];
+    }
+
+    private int backrefEnd(int mem) {
+        return bsAt(regex.btMemEnd, mem) ? stack[repeatStk[memEndStk + mem]].getMemPStr() : repeatStk[memEndStk + mem];
+    }
+
+    private void backref(int mem) {
+        /* if you want to remove following line,
+        you should check in parse and compile time. (numMem) */
+        if (mem > regex.numMem || backrefInvalid(mem)) {opFail(); return;}
+
+        int pstart = backrefStart(mem);
+        int pend = backrefEnd(mem);
+
+        int n = pend - pstart;
+        if (s + n > range) {opFail(); return;}
+        sprev = s;
+
+        // STRING_CMP
+        while(n-- > 0) if (chars[pstart++] != chars[s++]) {opFail(); return;}
+
+        int len;
+
+        // beyond string check
+        if (sprev < range) {
+            while (sprev + 1 < s) sprev++;
+        }
+    }
+
+    private void opBackRef1() {
+        backref(1);
+    }
+
+    private void opBackRef2() {
+        backref(2);
+    }
+
+    private void opBackRefN() {
+        backref(code[ip++]);
+    }
+
+    private void opBackRefNIC() {
+        int mem = code[ip++];
+        /* if you want to remove following line,
+        you should check in parse and compile time. (numMem) */
+        if (mem > regex.numMem || backrefInvalid(mem)) {opFail(); return;}
+
+        int pstart = backrefStart(mem);
+        int pend = backrefEnd(mem);
+
+        int n = pend - pstart;
+        if (s + n > range) {opFail(); return;}
+        sprev = s;
+
+        value = s;
+        if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end)) {opFail(); return;}
+        s = value;
+
+        int len;
+        // if (sprev < chars.length)
+        while (sprev + 1 < s) sprev++;
+    }
+
+    private void opBackRefMulti() {
+        int tlen = code[ip++];
+
+        int i;
+        loop:for (i=0; i<tlen; i++) {
+            int mem = code[ip++];
+            if (backrefInvalid(mem)) continue;
+
+            int pstart = backrefStart(mem);
+            int pend = backrefEnd(mem);
+
+            int n = pend - pstart;
+            if (s + n > range) {opFail(); return;}
+
+            sprev = s;
+            int swork = s;
+
+            while (n-- > 0) {
+                if (chars[pstart++] != chars[swork++]) continue loop;
+            }
+
+            s = swork;
+
+            int len;
+
+            // beyond string check
+            if (sprev < range) {
+                while (sprev + 1 < s) sprev++;
+            }
+
+            ip += tlen - i  - 1; // * SIZE_MEMNUM (1)
+            break; /* success */
+        }
+        if (i == tlen) {opFail(); return;}
+    }
+
+    private void opBackRefMultiIC() {
+        int tlen = code[ip++];
+
+        int i;
+        loop:for (i=0; i<tlen; i++) {
+            int mem = code[ip++];
+            if (backrefInvalid(mem)) continue;
+
+            int pstart = backrefStart(mem);
+            int pend = backrefEnd(mem);
+
+            int n = pend - pstart;
+            if (s + n > range) {opFail(); return;}
+
+            sprev = s;
+
+            value = s;
+            if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end)) continue loop; // STRING_CMP_VALUE_IC
+            s = value;
+
+            int len;
+            // if (sprev < chars.length)
+            while (sprev + 1 < s) sprev++;
+
+            ip += tlen - i  - 1; // * SIZE_MEMNUM (1)
+            break;  /* success */
+        }
+        if (i == tlen) {opFail(); return;}
+    }
+
+    private boolean memIsInMemp(int mem, int num, int memp) {
+        for (int i=0; i<num; i++) {
+            int m = code[memp++];
+            if (mem == m) return true;
+        }
+        return false;
+    }
+
+    // USE_BACKREF_AT_LEVEL // (s) and (end) implicit
+    private boolean backrefMatchAtNestedLevel(boolean ignoreCase, int caseFoldFlag,
+                                              int nest, int memNum, int memp) {
+        int pend = -1;
+        int level = 0;
+        int k = stk - 1;
+
+        while (k >= 0) {
+            StackEntry e = stack[k];
+
+            if (e.type == CALL_FRAME) {
+                level--;
+            } else if (e.type == RETURN) {
+                level++;
+            } else if (level == nest) {
+                if (e.type == MEM_START) {
+                    if (memIsInMemp(e.getMemNum(), memNum, memp)) {
+                        int pstart = e.getMemPStr();
+                        if (pend != -1) {
+                            if (pend - pstart > end - s) return false; /* or goto next_mem; */
+                            int p = pstart;
+
+                            value = s;
+                            if (ignoreCase) {
+                                if (!stringCmpIC(caseFoldFlag, pstart, this, pend - pstart, end)) {
+                                    return false; /* or goto next_mem; */
+                                }
+                            } else {
+                                while (p < pend) {
+                                    if (chars[p++] != chars[value++]) return false; /* or goto next_mem; */
+                                }
+                            }
+                            s = value;
+
+                            return true;
+                        }
+                    }
+                } else if (e.type == MEM_END) {
+                    if (memIsInMemp(e.getMemNum(), memNum, memp)) {
+                        pend = e.getMemPStr();
+                    }
+                }
+            }
+            k--;
+        }
+        return false;
+    }
+
+    private void opBackRefAtLevel() {
+        int ic      = code[ip++];
+        int level   = code[ip++];
+        int tlen    = code[ip++];
+
+        sprev = s;
+        if (backrefMatchAtNestedLevel(ic != 0, regex.caseFoldFlag, level, tlen, ip)) { // (s) and (end) implicit
+            int len;
+            while (sprev + 1 < s) sprev++;
+            ip += tlen; // * SIZE_MEMNUM
+        } else {
+            {opFail(); return;}
+        }
+    }
+
+    /* no need: IS_DYNAMIC_OPTION() == 0 */
+    private void opSetOptionPush() {
+        // option = code[ip++]; // final for now
+        pushAlt(ip, s, sprev);
+        ip += OPSize.SET_OPTION + OPSize.FAIL;
+    }
+
+    private void opSetOption() {
+        // option = code[ip++]; // final for now
+    }
+
+    private void opNullCheckStart() {
+        int mem = code[ip++];
+        pushNullCheckStart(mem, s);
+    }
+
+    private void nullCheckFound() {
+        // null_check_found:
+        /* empty loop founded, skip next instruction */
+        switch(code[ip++]) {
+        case OPCode.JUMP:
+        case OPCode.PUSH:
+            ip++;       // p += SIZE_RELADDR;
+            break;
+        case OPCode.REPEAT_INC:
+        case OPCode.REPEAT_INC_NG:
+        case OPCode.REPEAT_INC_SG:
+        case OPCode.REPEAT_INC_NG_SG:
+            ip++;        // p += SIZE_MEMNUM;
+            break;
+        default:
+            throw new InternalException(ErrorMessages.ERR_UNEXPECTED_BYTECODE);
+        } // switch
+    }
+
+    private void opNullCheckEnd() {
+        int mem = code[ip++];
+        int isNull = nullCheck(mem, s); /* mem: null check id */
+
+        if (isNull != 0) {
+            if (Config.DEBUG_MATCH) {
+                Config.log.println("NULL_CHECK_END: skip  id:" + mem + ", s:" + s);
+            }
+
+            nullCheckFound();
+        }
+    }
+
+    // USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
+    private void opNullCheckEndMemST() {
+        int mem = code[ip++];   /* mem: null check id */
+        int isNull = nullCheckMemSt(mem, s);
+
+        if (isNull != 0) {
+            if (Config.DEBUG_MATCH) {
+                Config.log.println("NULL_CHECK_END_MEMST: skip  id:" + mem + ", s:" + s);
+            }
+
+            if (isNull == -1) {opFail(); return;}
+            nullCheckFound();
+        }
+    }
+
+    // USE_SUBEXP_CALL
+    private void opNullCheckEndMemSTPush() {
+        int mem = code[ip++];   /* mem: null check id */
+
+        int isNull;
+        if (Config.USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT) {
+            isNull = nullCheckMemStRec(mem, s);
+        } else {
+            isNull = nullCheckRec(mem, s);
+        }
+
+        if (isNull != 0) {
+            if (Config.DEBUG_MATCH) {
+                Config.log.println("NULL_CHECK_END_MEMST_PUSH: skip  id:" + mem + ", s:" + s);
+            }
+
+            if (isNull == -1) {opFail(); return;}
+            nullCheckFound();
+        } else {
+            pushNullCheckEnd(mem);
+        }
+    }
+
+    private void opJump() {
+        ip += code[ip] + 1;
+    }
+
+    private void opPush() {
+        int addr = code[ip++];
+        pushAlt(ip + addr, s, sprev);
+    }
+
+    // CEC
+    private void opStateCheckPush() {
+        int mem = code[ip++];
+        if (stateCheckVal(s, mem)) {opFail(); return;}
+        int addr = code[ip++];
+        pushAltWithStateCheck(ip + addr, s, sprev, mem);
+    }
+
+    // CEC
+    private void opStateCheckPushOrJump() {
+        int mem = code[ip++];
+        int addr= code[ip++];
+
+        if (stateCheckVal(s, mem)) {
+            ip += addr;
+        } else {
+            pushAltWithStateCheck(ip + addr, s, sprev, mem);
+        }
+    }
+
+    // CEC
+    private void opStateCheck() {
+        int mem = code[ip++];
+        if (stateCheckVal(s, mem)) {opFail(); return;}
+        pushStateCheck(s, mem);
+    }
+
+    private void opPop() {
+        popOne();
+    }
+
+    private void opPushOrJumpExact1() {
+        int addr = code[ip++];
+        // beyond string check
+        if (s < range && code[ip] == chars[s]) {
+            ip++;
+            pushAlt(ip + addr, s, sprev);
+            return;
+        }
+        ip += addr + 1;
+    }
+
+    private void opPushIfPeekNext() {
+        int addr = code[ip++];
+        // beyond string check
+        if (s < range && code[ip] == chars[s]) {
+            ip++;
+            pushAlt(ip + addr, s, sprev);
+            return;
+        }
+        ip++;
+    }
+
+    private void opRepeat() {
+        int mem = code[ip++];   /* mem: OP_REPEAT ID */
+        int addr= code[ip++];
+
+        // ensure1();
+        repeatStk[mem] = stk;
+        pushRepeat(mem, ip);
+
+        if (regex.repeatRangeLo[mem] == 0) { // lower
+            pushAlt(ip + addr, s, sprev);
+        }
+    }
+
+    private void opRepeatNG() {
+        int mem = code[ip++];   /* mem: OP_REPEAT ID */
+        int addr= code[ip++];
+
+        // ensure1();
+        repeatStk[mem] = stk;
+        pushRepeat(mem, ip);
+
+        if (regex.repeatRangeLo[mem] == 0) {
+            pushAlt(ip, s, sprev);
+            ip += addr;
+        }
+    }
+
+    private void repeatInc(int mem, int si) {
+        StackEntry e = stack[si];
+
+        e.increaseRepeatCount();
+
+        if (e.getRepeatCount() >= regex.repeatRangeHi[mem]) {
+            /* end of repeat. Nothing to do. */
+        } else if (e.getRepeatCount() >= regex.repeatRangeLo[mem]) {
+            pushAlt(ip, s, sprev);
+            ip = e.getRepeatPCode(); /* Don't use stkp after PUSH. */
+        } else {
+            ip = e.getRepeatPCode();
+        }
+        pushRepeatInc(si);
+    }
+
+    private void opRepeatInc() {
+        int mem = code[ip++];   /* mem: OP_REPEAT ID */
+        int si = repeatStk[mem];
+        repeatInc(mem, si);
+    }
+
+    private void opRepeatIncSG() {
+        int mem = code[ip++];   /* mem: OP_REPEAT ID */
+        int si = getRepeat(mem);
+        repeatInc(mem, si);
+    }
+
+    private void repeatIncNG(int mem, int si) {
+        StackEntry e = stack[si];
+
+        e.increaseRepeatCount();
+
+        if (e.getRepeatCount() < regex.repeatRangeHi[mem]) {
+            if (e.getRepeatCount() >= regex.repeatRangeLo[mem]) {
+                int pcode = e.getRepeatPCode();
+                pushRepeatInc(si);
+                pushAlt(pcode, s, sprev);
+            } else {
+                ip = e.getRepeatPCode();
+                pushRepeatInc(si);
+            }
+        } else if (e.getRepeatCount() == regex.repeatRangeHi[mem]) {
+            pushRepeatInc(si);
+        }
+    }
+
+    private void opRepeatIncNG() {
+        int mem = code[ip++];
+        int si = repeatStk[mem];
+        repeatIncNG(mem, si);
+    }
+
+    private void opRepeatIncNGSG() {
+        int mem = code[ip++];
+        int si = getRepeat(mem);
+        repeatIncNG(mem, si);
+    }
+
+    private void opPushPos() {
+        pushPos(s, sprev);
+    }
+
+    private void opPopPos() {
+        StackEntry e = stack[posEnd()];
+        s    = e.getStatePStr();
+        sprev= e.getStatePStrPrev();
+    }
+
+    private void opPushPosNot() {
+        int addr = code[ip++];
+        pushPosNot(ip + addr, s, sprev);
+    }
+
+    private void opFailPos() {
+        popTilPosNot();
+        opFail();
+    }
+
+    private void opPushStopBT() {
+        pushStopBT();
+    }
+
+    private void opPopStopBT() {
+        stopBtEnd();
+    }
+
+    private void opLookBehind() {
+        int tlen = code[ip++];
+        s = EncodingHelper.stepBack(str, s, tlen);
+        if (s == -1) {opFail(); return;}
+        sprev = EncodingHelper.prevCharHead(str, s);
+    }
+
+    private void opLookBehindSb() {
+        int tlen = code[ip++];
+        s -= tlen;
+        if (s < str) {opFail(); return;}
+        sprev = s == str ? -1 : s - 1;
+    }
+
+    private void opPushLookBehindNot() {
+        int addr = code[ip++];
+        int tlen = code[ip++];
+        int q = EncodingHelper.stepBack(str, s, tlen);
+        if (q == -1) {
+            /* too short case -> success. ex. /(?<!XXX)a/.match("a")
+            If you want to change to fail, replace following line. */
+            ip += addr;
+            // return FAIL;
+        } else {
+            pushLookBehindNot(ip + addr, s, sprev);
+            s = q;
+            sprev = EncodingHelper.prevCharHead(str, s);
+        }
+    }
+
+    private void opFailLookBehindNot() {
+        popTilLookBehindNot();
+        opFail();
+    }
+
+    private void opCall() {
+        int addr = code[ip++];
+        pushCallFrame(ip);
+        ip = addr; // absolute address
+    }
+
+    private void opReturn() {
+        ip = sreturn();
+        pushReturn();
+    }
+
+    private void opFail() {
+        if (stack == null) {
+            ip = regex.codeLength - 1;
+            return;
+        }
+
+
+        StackEntry e = pop();
+        ip    = e.getStatePCode();
+        s     = e.getStatePStr();
+        sprev = e.getStatePStrPrev();
+
+        if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+            if (e.getStateCheck() != 0) {
+                e.type = STATE_CHECK_MARK;
+                stk++;
+            }
+        }
+    }
+
+    private int finish() {
+        return bestLen;
+    }
+}
\ No newline at end of file
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java
new file mode 100644
index 0000000..86a558b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java
@@ -0,0 +1,416 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.Arguments;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.OPSize;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+
+class ByteCodePrinter {
+    final int[]code;
+    final int codeLength;
+    final char[][] templates;
+
+    Object[]operands;
+    int operantCount;
+    WarnCallback warnings;
+
+    public ByteCodePrinter(Regex regex) {
+        code = regex.code;
+        codeLength = regex.codeLength;
+        operands = regex.operands;
+        operantCount = regex.operandLength;
+
+        templates = regex.templates;
+        warnings = regex.warnings;
+    }
+
+    public String byteCodeListToString() {
+        return compiledByteCodeListToString();
+    }
+
+    private void pString(StringBuilder sb, int len, int s) {
+        sb.append(":");
+        while (len-- > 0) sb.append(new String(new byte[]{(byte)code[s++]}));
+    }
+
+    private void pStringFromTemplate(StringBuilder sb, int len, byte[]tm, int idx) {
+        sb.append(":T:");
+        while (len-- > 0) sb.append(new String(new byte[]{tm[idx++]}));
+    }
+
+    private void pLenString(StringBuilder sb, int len, int mbLen, int s) {
+        int x = len * mbLen;
+        sb.append(":" + len + ":");
+        while (x-- > 0) sb.append(new String(new byte[]{(byte)code[s++]}));
+    }
+
+    private void pLenStringFromTemplate(StringBuilder sb, int len, int mbLen, char[] tm, int idx) {
+        int x = len * mbLen;
+        sb.append(":T:" + len + ":");
+        while (x-- > 0) sb.append(new String(new byte[]{(byte)tm[idx++]}));
+    }
+
+    public int compiledByteCodeToString(StringBuilder sb, int bp) {
+        int len, n, mem, addr, scn, cod;
+        BitSet bs;
+        CClassNode cc;
+        int tm, idx;
+
+        sb.append("[" + OPCode.OpCodeNames[code[bp]]);
+        int argType = OPCode.OpCodeArgTypes[code[bp]];
+        int ip = bp;
+        if (argType != Arguments.SPECIAL) {
+            bp++;
+            switch (argType) {
+            case Arguments.NON:
+                break;
+
+            case Arguments.RELADDR:
+                sb.append(":(" + code[bp] + ")");
+                bp += OPSize.RELADDR;
+                break;
+
+            case Arguments.ABSADDR:
+                sb.append(":(" + code[bp] + ")");
+                bp += OPSize.ABSADDR;
+                break;
+
+            case Arguments.LENGTH:
+                sb.append(":" + code[bp]);
+                bp += OPSize.LENGTH;
+                break;
+
+            case Arguments.MEMNUM:
+                sb.append(":" + code[bp]);
+                bp += OPSize.MEMNUM;
+                break;
+
+            case Arguments.OPTION:
+                sb.append(":" + code[bp]);
+                bp += OPSize.OPTION;
+                break;
+
+            case Arguments.STATE_CHECK:
+                sb.append(":" + code[bp]);
+                bp += OPSize.STATE_CHECK;
+                break;
+            }
+        } else {
+            switch (code[bp++]) {
+            case OPCode.EXACT1:
+            case OPCode.ANYCHAR_STAR_PEEK_NEXT:
+            case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:
+            case OPCode.ANYCHAR_STAR_PEEK_NEXT_SB:
+            case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT_SB:
+                pString(sb, 1, bp++);
+                break;
+
+            case OPCode.EXACT2:
+                pString(sb, 2, bp);
+                bp += 2;
+                break;
+
+            case OPCode.EXACT3:
+                pString(sb, 3, bp);
+                bp += 3;
+                break;
+
+            case OPCode.EXACT4:
+                pString(sb, 4, bp);
+                bp += 4;
+                break;
+
+            case OPCode.EXACT5:
+                pString(sb, 5, bp);
+                bp += 5;
+                break;
+
+            case OPCode.EXACTN:
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                if (Config.USE_STRING_TEMPLATES) {
+                    tm = code[bp];
+                    bp += OPSize.INDEX;
+                    idx = code[bp];
+                    bp += OPSize.INDEX;
+                    pLenStringFromTemplate(sb, len, 1, templates[tm], idx);
+                } else {
+                    pLenString(sb, len, 1, bp);
+                    bp += len;
+                }
+                break;
+
+            case OPCode.EXACTMB2N1:
+                pString(sb, 2, bp);
+                bp += 2;
+                break;
+
+            case OPCode.EXACTMB2N2:
+                pString(sb, 4, bp);
+                bp += 4;
+                break;
+
+            case OPCode.EXACTMB2N3:
+                pString(sb, 6, bp);
+                bp += 6;
+                break;
+
+            case OPCode.EXACTMB2N:
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                if (Config.USE_STRING_TEMPLATES) {
+                    tm = code[bp];
+                    bp += OPSize.INDEX;
+                    idx = code[bp];
+                    bp += OPSize.INDEX;
+                    pLenStringFromTemplate(sb, len, 2, templates[tm], idx);
+                } else {
+                    pLenString(sb, len, 2, bp);
+                    bp += len * 2;
+                }
+                break;
+
+            case OPCode.EXACTMB3N:
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                if (Config.USE_STRING_TEMPLATES) {
+                    tm = code[bp];
+                    bp += OPSize.INDEX;
+                    idx = code[bp];
+                    bp += OPSize.INDEX;
+                    pLenStringFromTemplate(sb, len, 3, templates[tm], idx);
+                } else {
+                    pLenString(sb, len, 3, bp);
+                    bp += len * 3;
+                }
+                break;
+
+            case OPCode.EXACTMBN:
+                int mbLen = code[bp];
+                bp += OPSize.LENGTH;
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                n = len * mbLen;
+
+                if (Config.USE_STRING_TEMPLATES) {
+                    tm = code[bp];
+                    bp += OPSize.INDEX;
+                    idx = code[bp];
+                    bp += OPSize.INDEX;
+                    sb.append(":T:" + mbLen + ":" + len + ":");
+
+                    while (n-- > 0) sb.append(new String(new char[]{templates[tm][idx++]}));
+                } else {
+                    sb.append(":" + mbLen + ":" + len + ":");
+
+                    while (n-- > 0) sb.append(new String(new byte[]{(byte)code[bp++]}));
+                }
+
+                break;
+
+            case OPCode.EXACT1_IC:
+            case OPCode.EXACT1_IC_SB:
+                final int MAX_CHAR_LENGTH = 6;
+                byte[]bytes = new byte[MAX_CHAR_LENGTH];
+                for (int i = 0; bp + i < code.length && i < MAX_CHAR_LENGTH; i++) bytes[i] = (byte)code[bp + i];
+                pString(sb, 1, bp);
+                bp++;
+                break;
+
+            case OPCode.EXACTN_IC:
+            case OPCode.EXACTN_IC_SB:
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                if (Config.USE_STRING_TEMPLATES) {
+                    tm = code[bp];
+                    bp += OPSize.INDEX;
+                    idx = code[bp];
+                    bp += OPSize.INDEX;
+                    pLenStringFromTemplate(sb, len, 1, templates[tm], idx);
+                } else {
+                    pLenString(sb, len, 1, bp);
+                    bp += len;
+                }
+                break;
+
+            case OPCode.CCLASS:
+            case OPCode.CCLASS_SB:
+                bs = new BitSet();
+                System.arraycopy(code, bp, bs.bits, 0, BitSet.BITSET_SIZE);
+                n = bs.numOn();
+                bp += BitSet.BITSET_SIZE;
+                sb.append(":" + n);
+                break;
+
+            case OPCode.CCLASS_NOT:
+            case OPCode.CCLASS_NOT_SB:
+                bs = new BitSet();
+                System.arraycopy(code, bp, bs.bits, 0, BitSet.BITSET_SIZE);
+                n = bs.numOn();
+                bp += BitSet.BITSET_SIZE;
+                sb.append(":" + n);
+                break;
+
+            case OPCode.CCLASS_MB:
+            case OPCode.CCLASS_MB_NOT:
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                cod = code[bp];
+                //bp += OPSize.CODE_POINT;
+                bp += len;
+                sb.append(":" + cod + ":" + len);
+                break;
+
+            case OPCode.CCLASS_MIX:
+            case OPCode.CCLASS_MIX_NOT:
+                bs = new BitSet();
+                System.arraycopy(code, bp, bs.bits, 0, BitSet.BITSET_SIZE);
+                n = bs.numOn();
+                bp += BitSet.BITSET_SIZE;
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                cod = code[bp];
+                //bp += OPSize.CODE_POINT;
+                bp += len;
+                sb.append(":" + n + ":" + cod + ":" + len);
+                break;
+
+            case OPCode.CCLASS_NODE:
+                cc = (CClassNode)operands[code[bp]];
+                bp += OPSize.POINTER;
+                n = cc.bs.numOn();
+                sb.append(":" + cc + ":" + n);
+                break;
+
+            case OPCode.BACKREFN_IC:
+                mem = code[bp];
+                bp += OPSize.MEMNUM;
+                sb.append(":" + mem);
+                break;
+
+            case OPCode.BACKREF_MULTI_IC:
+            case OPCode.BACKREF_MULTI:
+                sb.append(" ");
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                for (int i=0; i<len; i++) {
+                    mem = code[bp];
+                    bp += OPSize.MEMNUM;
+                    if (i > 0) sb.append(", ");
+                    sb.append(mem);
+                }
+                break;
+
+            case OPCode.BACKREF_WITH_LEVEL: {
+                int option = code[bp];
+                bp += OPSize.OPTION;
+                sb.append(":" + option);
+                int level = code[bp];
+                bp += OPSize.LENGTH;
+                sb.append(":" + level);
+                sb.append(" ");
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                for (int i=0; i<len; i++) {
+                    mem = code[bp];
+                    bp += OPSize.MEMNUM;
+                    if (i > 0) sb.append(", ");
+                    sb.append(mem);
+                }
+                break;
+            }
+
+            case OPCode.REPEAT:
+            case OPCode.REPEAT_NG:
+                mem = code[bp];
+                bp += OPSize.MEMNUM;
+                addr = code[bp];
+                bp += OPSize.RELADDR;
+                sb.append(":" + mem + ":" + addr);
+                break;
+
+            case OPCode.PUSH_OR_JUMP_EXACT1:
+            case OPCode.PUSH_IF_PEEK_NEXT:
+                addr = code[bp];
+                bp += OPSize.RELADDR;
+                sb.append(":(" + addr + ")");
+                pString(sb, 1, bp);
+                bp++;
+                break;
+
+            case OPCode.LOOK_BEHIND:
+            case OPCode.LOOK_BEHIND_SB:
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                sb.append(":" + len);
+                break;
+
+            case OPCode.PUSH_LOOK_BEHIND_NOT:
+                addr = code[bp];
+                bp += OPSize.RELADDR;
+                len = code[bp];
+                bp += OPSize.LENGTH;
+                sb.append(":" + len + ":(" + addr + ")");
+                break;
+
+            case OPCode.STATE_CHECK_PUSH:
+            case OPCode.STATE_CHECK_PUSH_OR_JUMP:
+                scn = code[bp];
+                bp += OPSize.STATE_CHECK_NUM;
+                addr = code[bp];
+                bp += OPSize.RELADDR;
+                sb.append(":" + scn + ":(" + addr + ")");
+                break;
+
+            default:
+                throw new InternalException("undefined code: " + code[--bp]);
+            }
+        }
+
+        sb.append("]");
+
+        // @opcode_address(opcode_size)
+        if (Config.DEBUG_COMPILE_BYTE_CODE_INFO) sb.append("@" + ip + "(" + (bp - ip) + ")");
+
+        return bp;
+    }
+
+    private String compiledByteCodeListToString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("code length: " + codeLength + "\n");
+
+        int ncode = 0;
+        int bp = 0;
+        int end = codeLength;
+
+        while (bp < end) {
+            ncode++;
+
+            if (bp > 0) sb.append(ncode % 5 == 0 ? "\n" : " ");
+
+            bp = compiledByteCodeToString(sb, bp);
+        }
+        sb.append("\n");
+        return sb.toString();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CaptureTreeNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CaptureTreeNode.java
new file mode 100644
index 0000000..268f682
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CaptureTreeNode.java
@@ -0,0 +1,74 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public class CaptureTreeNode {
+
+
+    int group;
+    int beg;
+    int end;
+    // int allocated;
+    int numChildren;
+    CaptureTreeNode[]children;
+
+    CaptureTreeNode() {
+        beg = Region.REGION_NOTPOS;
+        end = Region.REGION_NOTPOS;
+        group = -1;
+    }
+
+    static final int HISTORY_TREE_INIT_ALLOC_SIZE = 8;
+    void addChild(CaptureTreeNode child) {
+        if (children == null) {
+            children = new CaptureTreeNode[HISTORY_TREE_INIT_ALLOC_SIZE];
+        } else if (numChildren >= children.length) {
+            CaptureTreeNode[]tmp = new CaptureTreeNode[children.length << 1];
+            System.arraycopy(children, 0, tmp, 0, children.length);
+            children = tmp;
+        }
+
+        children[numChildren] = child;
+        numChildren++;
+    }
+
+    void clear() {
+        for (int i=0; i<numChildren; i++) {
+            children[i] = null; // ???
+        }
+        numChildren = 0;
+        beg = end = Region.REGION_NOTPOS;
+        group = -1;
+    }
+
+    CaptureTreeNode cloneTree() {
+        CaptureTreeNode clone = new CaptureTreeNode();
+        clone.beg = beg;
+        clone.end = end;
+
+        for (int i=0; i<numChildren; i++) {
+            CaptureTreeNode child = children[i].cloneTree();
+            clone.addChild(child);
+        }
+        return clone;
+    }
+
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java
new file mode 100644
index 0000000..87e0f8e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java
@@ -0,0 +1,378 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
+
+public final class CodeRangeBuffer {
+    private static final int INIT_MULTI_BYTE_RANGE_SIZE = 5;
+    private static final int ALL_MULTI_BYTE_RANGE = 0x7fffffff;
+
+    int[]p;
+    int used;
+
+    public CodeRangeBuffer(int[]ranges) {
+        p = ranges;
+        used = ranges[0] + 1;
+    }
+
+    public CodeRangeBuffer() {
+        p = new int[INIT_MULTI_BYTE_RANGE_SIZE];
+        writeCodePoint(0, 0);
+    }
+
+    public int[]getCodeRange() {
+        return p;
+    }
+
+    private CodeRangeBuffer(CodeRangeBuffer orig) {
+        p = new int[orig.p.length];
+        System.arraycopy(orig.p, 0, p, 0, p.length);
+        used = orig.used;
+    }
+
+    public String toString() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("CodeRange");
+        buf.append("\n  used: " + used);
+        buf.append("\n  code point: " + p[0]);
+        buf.append("\n  ranges: ");
+
+        for (int i=0; i<p[0]; i++) {
+            buf.append("[" + rangeNumToString(p[i * 2 + 1]) + ".." + rangeNumToString(p[i * 2 + 2]) + "]");
+            if (i > 0 && i % 6 == 0) buf.append("\n          ");
+        }
+
+        return buf.toString();
+    }
+
+    private static String rangeNumToString(int num){
+        return "0x" + Integer.toString(num, 16);
+    }
+
+    public void expand(int low) {
+        int length = p.length;
+        do { length <<= 1; } while (length < low);
+        int[]tmp = new int[length];
+        System.arraycopy(p, 0, tmp, 0, used);
+        p = tmp;
+    }
+
+    public void ensureSize(int size) {
+        int length = p.length;
+        while (length < size ) { length <<= 1; }
+        if (p.length != length) {
+            int[]tmp = new int[length];
+            System.arraycopy(p, 0, tmp, 0, used);
+            p = tmp;
+        }
+    }
+
+    private void moveRight(int from, int to, int n) {
+        if (to + n > p.length) expand(to + n);
+        System.arraycopy(p, from, p, to, n);
+        if (to + n > used) used = to + n;
+    }
+
+    protected void moveLeft(int from, int to, int n) {
+        System.arraycopy(p, from, p, to, n);
+    }
+
+    private void moveLeftAndReduce(int from, int to) {
+        System.arraycopy(p, from, p, to, used - from);
+        used -= from - to;
+    }
+
+    public void writeCodePoint(int pos, int b) {
+        int u = pos + 1;
+        if (p.length < u) expand(u);
+        p[pos] = b;
+        if (used < u) used = u;
+    }
+
+    public CodeRangeBuffer clone() {
+        return new CodeRangeBuffer(this);
+    }
+
+    // ugly part: these methods should be made OO
+    // add_code_range_to_buf
+    public static CodeRangeBuffer addCodeRangeToBuff(CodeRangeBuffer pbuf, int from, int to) {
+        if (from > to) {
+            int n = from;
+            from = to;
+            to = n;
+        }
+
+        if (pbuf == null) pbuf = new CodeRangeBuffer(); // move to CClassNode
+
+        int[]p = pbuf.p;
+        int n = p[0];
+
+        int low = 0;
+        int bound = n;
+
+        while (low < bound) {
+            int x = (low + bound) >>> 1;
+            if (from > p[x * 2 + 2]) {
+                low = x + 1;
+            } else {
+                bound = x;
+            }
+        }
+
+        int high = low;
+        bound = n;
+
+        while (high < bound) {
+            int x = (high + bound) >>> 1;
+            if (to >= p[x * 2 + 1] - 1) {
+                high = x + 1;
+            } else {
+                bound = x;
+            }
+        }
+
+        int incN = low + 1 - high;
+
+        if (n + incN > Config.MAX_MULTI_BYTE_RANGES_NUM) throw new ValueException(ErrorMessages.ERR_TOO_MANY_MULTI_BYTE_RANGES);
+
+        if (incN != 1) {
+            if (from > p[low * 2 + 1]) from = p[low * 2 + 1];
+            if (to < p[(high - 1) * 2 + 2]) to = p[(high - 1) * 2 + 2];
+        }
+
+        if (incN != 0 && high < n) {
+            int fromPos = 1 + high * 2;
+            int toPos = 1 + (low + 1) * 2;
+            int size = (n - high) * 2;
+
+            if (incN > 0) {
+                pbuf.moveRight(fromPos, toPos, size);
+            } else {
+                pbuf.moveLeftAndReduce(fromPos, toPos);
+            }
+        }
+
+        int pos = 1 + low * 2;
+        // pbuf.ensureSize(pos + 2);
+        pbuf.writeCodePoint(pos, from);
+        pbuf.writeCodePoint(pos + 1, to);
+        n += incN;
+        pbuf.writeCodePoint(0, n);
+
+        return pbuf;
+    }
+
+    // add_code_range, be aware of it returning null!
+    public static CodeRangeBuffer addCodeRange(CodeRangeBuffer pbuf, ScanEnvironment env, int from, int to) {
+        if (from >to) {
+            if (env.syntax.allowEmptyRangeInCC()) {
+                return pbuf;
+            } else {
+                throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
+            }
+        }
+        return addCodeRangeToBuff(pbuf, from, to);
+    }
+
+    // SET_ALL_MULTI_BYTE_RANGE
+    protected static CodeRangeBuffer setAllMultiByteRange(CodeRangeBuffer pbuf) {
+        return addCodeRangeToBuff(pbuf, EncodingHelper.mbcodeStartPosition(), ALL_MULTI_BYTE_RANGE);
+    }
+
+    // ADD_ALL_MULTI_BYTE_RANGE
+    public static CodeRangeBuffer addAllMultiByteRange(CodeRangeBuffer pbuf) {
+        return setAllMultiByteRange(pbuf);
+    }
+
+    // not_code_range_buf
+    public static CodeRangeBuffer notCodeRangeBuff(CodeRangeBuffer bbuf) {
+        CodeRangeBuffer pbuf = null;
+
+        if (bbuf == null) return setAllMultiByteRange(pbuf);
+
+        int[]p = bbuf.p;
+        int n = p[0];
+
+        if (n <= 0) return setAllMultiByteRange(pbuf);
+
+        int pre = EncodingHelper.mbcodeStartPosition();
+
+        int from;
+        int to = 0;
+        for (int i=0; i<n; i++) {
+            from = p[i * 2 + 1];
+            to = p[i * 2 + 2];
+            if (pre <= from - 1) {
+                pbuf = addCodeRangeToBuff(pbuf, pre, from - 1);
+            }
+            if (to == ALL_MULTI_BYTE_RANGE) break;
+            pre = to + 1;
+        }
+
+        if (to < ALL_MULTI_BYTE_RANGE) pbuf = addCodeRangeToBuff(pbuf, to + 1, ALL_MULTI_BYTE_RANGE);
+        return pbuf;
+    }
+
+    // or_code_range_buf
+    public static CodeRangeBuffer orCodeRangeBuff(CodeRangeBuffer bbuf1, boolean not1,
+                                                  CodeRangeBuffer bbuf2, boolean not2) {
+        CodeRangeBuffer pbuf = null;
+
+        if (bbuf1 == null && bbuf2 == null) {
+            if (not1 || not2) {
+                return setAllMultiByteRange(pbuf);
+            }
+            return null;
+        }
+
+        if (bbuf2 == null) {
+            CodeRangeBuffer tbuf;
+            boolean tnot;
+            // swap
+            tnot = not1; not1 = not2; not2 = tnot;
+            tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
+        }
+
+        if (bbuf1 == null) {
+            if (not1) {
+                return setAllMultiByteRange(pbuf);
+            } else {
+                if (!not2) {
+                    return bbuf2.clone();
+                } else {
+                    return notCodeRangeBuff(bbuf2);
+                }
+            }
+        }
+
+        if (not1) {
+            CodeRangeBuffer tbuf;
+            boolean tnot;
+            // swap
+            tnot = not1; not1 = not2; not2 = tnot;
+            tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
+        }
+
+        if (!not2 && !not1) { /* 1 OR 2 */
+            pbuf = bbuf2.clone();
+        } else if (!not1) { /* 1 OR (not 2) */
+            pbuf = notCodeRangeBuff(bbuf2);
+        }
+
+        int[]p1 = bbuf1.p;
+        int n1 = p1[0];
+
+        for (int i=0; i<n1; i++) {
+            int from = p1[i * 2 + 1];
+            int to = p1[i * 2 + 2];
+            pbuf = addCodeRangeToBuff(pbuf, from, to);
+        }
+
+        return pbuf;
+    }
+
+    // and_code_range1
+    public static CodeRangeBuffer andCodeRange1(CodeRangeBuffer pbuf, int from1, int to1, int[]data, int n) {
+        for (int i=0; i<n; i++) {
+            int from2 = data[i * 2 + 1];
+            int to2 = data[i * 2 + 2];
+            if (from2 < from1) {
+                if (to2 < from1) {
+                    continue;
+                } else {
+                    from1 = to2 + 1;
+                }
+            } else if (from2 <= to1) {
+                if (to2 < to1) {
+                    if (from1 <= from2 - 1) {
+                        pbuf = addCodeRangeToBuff(pbuf, from1, from2 - 1);
+                    }
+                    from1 = to2 + 1;
+                } else {
+                    to1 = from2 - 1;
+                }
+            } else {
+                from1 = from2;
+            }
+            if (from1 > to1) break;
+        }
+
+        if (from1 <= to1) {
+            pbuf = addCodeRangeToBuff(pbuf, from1, to1);
+        }
+
+        return pbuf;
+    }
+
+    // and_code_range_buf
+    public static CodeRangeBuffer andCodeRangeBuff(CodeRangeBuffer bbuf1, boolean not1,
+                                                   CodeRangeBuffer bbuf2, boolean not2) {
+        CodeRangeBuffer pbuf = null;
+
+        if (bbuf1 == null) {
+            if (not1 && bbuf2 != null) return bbuf2.clone(); /* not1 != 0 -> not2 == 0 */
+            return null;
+        } else if (bbuf2 == null) {
+            if (not2) return bbuf1.clone();
+            return null;
+        }
+
+        if (not1) {
+            CodeRangeBuffer tbuf;
+            boolean tnot;
+            // swap
+            tnot = not1; not1 = not2; not2 = tnot;
+            tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
+        }
+
+        int[]p1 = bbuf1.p;
+        int n1 = p1[0];
+        int[]p2 = bbuf2.p;
+        int n2 = p2[0];
+
+        if (!not2 && !not1) { /* 1 AND 2 */
+            for (int i=0; i<n1; i++) {
+                int from1 = p1[i * 2 + 1];
+                int to1 = p1[i * 2 + 2];
+
+                for (int j=0; j<n2; j++) {
+                    int from2 = p2[j * 2 + 1];
+                    int to2 = p2[j * 2 + 2];
+
+                    if (from2 > to1) break;
+                    if (to2 < from1) continue;
+                    int from = from1 > from2 ? from1 : from2;
+                    int to = to1 < to2 ? to1 : to2;
+                    pbuf = addCodeRangeToBuff(pbuf, from, to);
+                }
+            }
+        } else if (!not1) { /* 1 AND (not 2) */
+            for (int i=0; i<n1; i++) {
+                int from1 = p1[i * 2 + 1];
+                int to1 = p1[i * 2 + 2];
+                pbuf = andCodeRange1(pbuf, from1, to1, p2, n2);
+            }
+        }
+
+        return pbuf;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Compiler.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Compiler.java
new file mode 100644
index 0000000..8fdc240
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Compiler.java
@@ -0,0 +1,178 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
+
+abstract class Compiler implements ErrorMessages {
+    protected final Analyser analyser;
+    protected final Regex regex;
+
+    protected Compiler(Analyser analyser) {
+        this.analyser = analyser;
+        this.regex = analyser.regex;
+    }
+
+    final void compile() {
+        prepare();
+        compileTree(analyser.root);
+        finish();
+    }
+
+    protected abstract void prepare();
+    protected abstract void finish();
+
+    protected abstract void compileAltNode(ConsAltNode node);
+
+    private void compileStringRawNode(StringNode sn) {
+        if (sn.length() <= 0) return;
+        addCompileString(sn.chars, sn.p, 1 /*sb*/, sn.length(), false);
+    }
+
+    private void compileStringNode(StringNode node) {
+        StringNode sn = node;
+        if (sn.length() <= 0) return;
+
+        boolean ambig = sn.isAmbig();
+
+        int p, prev;
+        p = prev = sn.p;
+        int end = sn.end;
+        char[] chars = sn.chars;
+        p++;
+        int slen = 1;
+
+        while (p < end) {
+            slen++;
+            p++;
+        }
+        addCompileString(chars, prev, 1, slen, ambig);
+    }
+
+    protected abstract void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase);
+
+    protected abstract void compileCClassNode(CClassNode node);
+    protected abstract void compileCTypeNode(CTypeNode node);
+    protected abstract void compileAnyCharNode();
+    protected abstract void compileCallNode(CallNode node);
+    protected abstract void compileBackrefNode(BackRefNode node);
+    protected abstract void compileCECQuantifierNode(QuantifierNode node);
+    protected abstract void compileNonCECQuantifierNode(QuantifierNode node);
+    protected abstract void compileOptionNode(EncloseNode node);
+    protected abstract void compileEncloseNode(EncloseNode node);
+    protected abstract void compileAnchorNode(AnchorNode node);
+
+    protected final void compileTree(Node node) {
+        switch (node.getType()) {
+        case NodeType.LIST:
+            ConsAltNode lin = (ConsAltNode)node;
+            do {
+                compileTree(lin.car);
+            } while ((lin = lin.cdr) != null);
+            break;
+
+        case NodeType.ALT:
+            compileAltNode((ConsAltNode)node);
+            break;
+
+        case NodeType.STR:
+            StringNode sn = (StringNode)node;
+            if (sn.isRaw()) {
+                compileStringRawNode(sn);
+            } else {
+                compileStringNode(sn);
+            }
+            break;
+
+        case NodeType.CCLASS:
+            compileCClassNode((CClassNode)node);
+            break;
+
+        case NodeType.CTYPE:
+            compileCTypeNode((CTypeNode)node);
+            break;
+
+        case NodeType.CANY:
+            compileAnyCharNode();
+            break;
+
+        case NodeType.BREF:
+            compileBackrefNode((BackRefNode)node);
+            break;
+
+        case NodeType.CALL:
+            if (Config.USE_SUBEXP_CALL) {
+                compileCallNode((CallNode)node);
+                break;
+            } // USE_SUBEXP_CALL
+            break;
+
+        case NodeType.QTFR:
+            if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+                compileCECQuantifierNode((QuantifierNode)node);
+            } else {
+                compileNonCECQuantifierNode((QuantifierNode)node);
+            }
+            break;
+
+        case NodeType.ENCLOSE:
+            EncloseNode enode = (EncloseNode)node;
+            if (enode.isOption()) {
+                compileOptionNode(enode);
+            } else {
+                compileEncloseNode(enode);
+            }
+            break;
+
+        case NodeType.ANCHOR:
+            compileAnchorNode((AnchorNode)node);
+            break;
+
+        default:
+            // undefined node type
+            newInternalException(ERR_PARSER_BUG);
+        } // switch
+    }
+
+    protected final void compileTreeNTimes(Node node, int n) {
+        for (int i=0; i<n; i++) compileTree(node);
+    }
+
+    protected void newSyntaxException(String message) {
+        throw new SyntaxException(message);
+    }
+
+    protected void newInternalException(String message) {
+        throw new InternalException(message);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java
new file mode 100644
index 0000000..04f5b47
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java
@@ -0,0 +1,100 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import java.io.PrintStream;
+
+public interface Config {
+    final int CHAR_TABLE_SIZE = 256;
+
+    /* from jcodings */
+    final boolean VANILLA = false;
+    final int INTERNAL_ENC_CASE_FOLD_MULTI_CHAR = (1<<30);
+    final int ENC_CASE_FOLD_MIN = INTERNAL_ENC_CASE_FOLD_MULTI_CHAR;
+    final int ENC_CASE_FOLD_DEFAULT = ENC_CASE_FOLD_MIN;
+    final boolean USE_CRNL_AS_LINE_TERMINATOR = false;
+
+    final boolean USE_NAMED_GROUP = true;
+    final boolean USE_SUBEXP_CALL = true;
+    final boolean USE_BACKREF_WITH_LEVEL = true;                            /* \k<name+n>, \k<name-n> */
+
+    final boolean USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT = true; /* /(?:()|())*\2/ */
+    final boolean USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE = true;     /* /\n$/ =~ "\n" */
+    final boolean USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR = false;
+
+    final boolean CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS = true;
+
+    final boolean USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE = false;
+    final boolean USE_CAPTURE_HISTORY = false;
+    final boolean USE_VARIABLE_META_CHARS = true;
+    final boolean USE_WORD_BEGIN_END = true;                                /* "\<": word-begin, "\>": word-end */
+    final boolean USE_POSIX_API_REGION_OPTION = true;                           /* needed for POSIX API support */
+    final boolean USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE = true;
+    final boolean USE_COMBINATION_EXPLOSION_CHECK = false;
+
+    final int NREGION                   = 10;
+    final int MAX_BACKREF_NUM           = 1000;
+    final int MAX_REPEAT_NUM            = 100000;
+    final int MAX_MULTI_BYTE_RANGES_NUM = 10000;
+
+
+    final boolean USE_WARN = true;
+
+    // internal config
+    final boolean USE_PARSE_TREE_NODE_RECYCLE       = true;
+    final boolean USE_OP_PUSH_OR_JUMP_EXACT         = true;
+    final boolean USE_SHARED_CCLASS_TABLE           = false;
+    final boolean USE_QTFR_PEEK_NEXT                = true;
+
+    final int INIT_MATCH_STACK_SIZE                 = 64;
+    final int DEFAULT_MATCH_STACK_LIMIT_SIZE        = 0;        /* unlimited */
+    final int NUMBER_OF_POOLED_STACKS               = 4;
+
+
+
+    final boolean DONT_OPTIMIZE                     = false;
+
+    final boolean USE_STRING_TEMPLATES              = true; // use embeded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
+
+
+    final int MAX_CAPTURE_HISTORY_GROUP             = 31;
+
+
+    final int CHECK_STRING_THRESHOLD_LEN            = 7;
+    final int CHECK_BUFF_MAX_SIZE                   = 0x4000;
+
+    final boolean NON_UNICODE_SDW                   = true;
+
+
+    final PrintStream log = System.out;
+    final PrintStream err = System.err;
+
+    final boolean DEBUG_ALL                         = false;
+
+    final boolean DEBUG                             = DEBUG_ALL;
+    final boolean DEBUG_PARSE_TREE                  = DEBUG_ALL;
+    final boolean DEBUG_PARSE_TREE_RAW              = true;
+    final boolean DEBUG_COMPILE                     = DEBUG_ALL;
+    final boolean DEBUG_COMPILE_BYTE_CODE_INFO      = DEBUG_ALL;
+    final boolean DEBUG_SEARCH                      = DEBUG_ALL;
+    final boolean DEBUG_MATCH                       = DEBUG_ALL;
+    final boolean DEBUG_ASM                         = true;
+    final boolean DEBUG_ASM_EXEC                    = true;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java
new file mode 100644
index 0000000..d3e5494
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java
@@ -0,0 +1,285 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
+
+import java.util.Arrays;
+
+public class EncodingHelper {
+
+    public final static char NEW_LINE = 0xa;
+    public final static char RETURN   = 0xd;
+
+    final static char[] EMPTYCHARS = new char[0];
+    final static int[][] codeRanges = new int[15][];
+
+    public static int digitVal(int code) {
+        return code - '0';
+    }
+
+    public static int odigitVal(int code) {
+        return digitVal(code);
+    }
+
+    public static boolean isXDigit(int code) {
+        return Character.isDigit(code) || (code >= 'a' && code <= 'f') || (code >= 'A' && code <= 'F');
+    }
+
+    public static int xdigitVal(int code) {
+        if (Character.isDigit(code)) {
+            return code - '0';
+        } else if (code >= 'a' && code <= 'f') {
+            return code - 'a' + 10;
+        } else {
+            return code - 'A' + 10;
+        }
+    }
+
+    public static boolean isDigit(int code) {
+        return code >= '0' && code <= '9';
+    }
+
+    public static boolean isWord(int code) {
+        // letter, digit, or '_'
+        return (1 << Character.getType(code) & CharacterType.WORD_MASK) != 0;
+    }
+
+    public static boolean isNewLine(int code) {
+        return code == NEW_LINE;
+    }
+
+    public static boolean isNewLine(char[] chars, int p, int end) {
+        return p < end && chars[p] == NEW_LINE;
+    }
+
+    public static boolean isCrnl(char[] chars, int p, int end) {
+        return p + 1 < end && chars[p] == RETURN && chars[p + 1] == NEW_LINE;
+    }
+
+    // Encoding.prevCharHead
+    public static int prevCharHead(int p, int s) {
+        return s <= p ? -1 : s - 1;
+    }
+
+    /* onigenc_get_right_adjust_char_head_with_prev */
+    public static int rightAdjustCharHeadWithPrev(int s, IntHolder prev) {
+        if (prev != null) prev.value = -1; /* Sorry */
+        return s;
+    }
+
+    // Encoding.stepBack
+    public static int stepBack(int p, int s, int n) {
+       while (s != -1 && n-- > 0) {
+           if (s <= p) return -1;
+           s--;
+       }
+       return s;
+    }
+
+    /* onigenc_with_ascii_strncmp */
+    public static int strNCmp(char[] chars1, int p1, int end, char[] chars2, int p2, int n) {
+        while (n-- > 0) {
+            if (p1 >= end) return chars2[p2];
+            int c = chars1[p1];
+            int x = chars2[p2] - c;
+            if (x != 0) return x;
+
+            p2++;
+            p1++;
+        }
+        return 0;
+    }
+
+    public static int mbcToCode(byte[] bytes, int p, int end) {
+        int code = 0;
+        for (int i = p; i < end; i++) {
+            code = (code << 8) | (bytes[i] & 0xff);
+        }
+        return code;
+    }
+
+    public static int mbcodeStartPosition() {
+        return 0x80;
+    }
+
+    public static char[] caseFoldCodesByString(int flag, char c) {
+        if (Character.isUpperCase(c)) {
+            return new char[] {Character.toLowerCase(c)};
+        } else if (Character.isLowerCase(c)) {
+            return new char[] {Character.toUpperCase(c)};
+        } else {
+            return EMPTYCHARS;
+        }
+    }
+
+    public static void applyAllCaseFold(int flag, ApplyCaseFold fun, Object arg) {
+        int[] code = new int[1];
+
+        for (int c = 0; c < 0xffff; c++) {
+            if (Character.getType(c) == Character.LOWERCASE_LETTER) {
+
+                int upper = code[0] = Character.toUpperCase(c);
+                fun.apply(c, code, 1, arg);
+
+                code[0] = c;
+                fun.apply(upper, code, 1, arg);
+            }
+        }
+    }
+
+    // CodeRange.isInCodeRange
+    public static boolean isInCodeRange(int[]p, int code) {
+        int low = 0;
+        int n = p[0];
+        int high = n;
+
+        while (low < high) {
+            int x = (low + high) >> 1;
+            if (code > p[(x << 1) + 2]) {
+                low = x + 1;
+            } else {
+                high = x;
+            }
+        }
+        return low < n && code >= p[(low << 1) + 1];
+    }
+
+    public static int[] ctypeCodeRange(int ctype, IntHolder sbOut) {
+        sbOut.value = 0x100; // use bitset for codes smaller than 256
+        int[] range = null;
+
+        if (ctype < codeRanges.length) {
+            range = codeRanges[ctype];
+
+            if (range == null) {
+                // format: [numberOfRanges, rangeStart, rangeEnd, ...]
+                range = new int[16];
+                int rangeCount = 0;
+                int lastCode = -2;
+
+                for (int code = 0; code <= 0xffff; code++) {
+                    if (isCodeCType(code, ctype)) {
+                        if (lastCode < code -1) {
+                            if (rangeCount * 2 + 2 >= range.length) {
+                                range = Arrays.copyOf(range, range.length * 2);
+                            }
+                            range[rangeCount * 2 + 1] = code;
+                            rangeCount++;
+                        }
+                        range[rangeCount * 2] = lastCode = code;
+                    }
+                }
+
+                if (rangeCount * 2 + 1 < range.length) {
+                    range = Arrays.copyOf(range, rangeCount * 2 + 1);
+                }
+
+                range[0] = rangeCount;
+                codeRanges[ctype] = range;
+            }
+        }
+
+        return range;
+    }
+
+    // CodeRange.isInCodeRange
+    public static boolean isInCodeRange(int[]p, int offset, int code) {
+        int low = 0;
+        int n = p[offset];
+        int high = n ;
+
+        while (low < high) {
+            int x = (low + high) >> 1;
+            if (code > p[(x << 1) + 2 + offset]) {
+                low = x + 1;
+            } else {
+                high = x;
+            }
+        }
+        return low < n && code >= p[(low << 1) + 1 + offset];
+    }
+
+    /**
+     * @see <a href="http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt">http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt</a>
+     */
+    public static boolean isCodeCType(int code, int ctype) {
+        int type;
+        switch (ctype) {
+            case CharacterType.NEWLINE:
+                return code == EncodingHelper.NEW_LINE;
+            case CharacterType.ALPHA:
+                return (1 << Character.getType(code) & CharacterType.ALPHA_MASK) != 0;
+            case CharacterType.BLANK:
+                return code == 0x09 || Character.getType(code) == Character.SPACE_SEPARATOR;
+            case CharacterType.CNTRL:
+                type = Character.getType(code);
+                return (1 << type & CharacterType.CNTRL_MASK) != 0 || type == Character.UNASSIGNED;
+            case CharacterType.DIGIT:
+                return EncodingHelper.isDigit(code);
+            case CharacterType.GRAPH:
+                switch (code) {
+                    case 0x09:
+                    case 0x0a:
+                    case 0x0b:
+                    case 0x0c:
+                    case 0x0d:
+                        return false;
+                    default:
+                        type = Character.getType(code);
+                        return (1 << type & CharacterType.GRAPH_MASK) == 0 && type != Character.UNASSIGNED;
+                }
+            case CharacterType.LOWER:
+                return Character.isLowerCase(code);
+            case CharacterType.PRINT:
+                type = Character.getType(code);
+                return (1 << type & CharacterType.PRINT_MASK) == 0 && type != Character.UNASSIGNED;
+            case CharacterType.PUNCT:
+                return (1 << Character.getType(code) & CharacterType.PUNCT_MASK) != 0;
+            case CharacterType.SPACE:
+                // ECMA 7.2 and 7.3
+                switch (code) {
+                    case 0x09:
+                    case 0x0a:
+                    case 0x0b:
+                    case 0x0c:
+                    case 0x0d:
+                        return true;
+                    default:
+                        // true if Unicode separator or BOM
+                        return (1 << Character.getType(code) & CharacterType.SPACE_MASK) != 0 || code == 0xfeff;
+                }
+            case CharacterType.UPPER:
+                return Character.isUpperCase(code);
+            case CharacterType.XDIGIT:
+                return EncodingHelper.isXDigit(code);
+            case CharacterType.WORD:
+                return (1 << Character.getType(code) & CharacterType.WORD_MASK) != 0;
+            case CharacterType.ALNUM:
+                return (1 << Character.getType(code) & CharacterType.ALNUM_MASK) != 0;
+            case CharacterType.ASCII:
+                return code < 0x80;
+            default:
+                throw new RuntimeException("illegal character type: " + ctype);
+        }
+    }
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java
new file mode 100644
index 0000000..c289f33
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java
@@ -0,0 +1,1274 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isSingleline;
+import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.isRepeatInfinite;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.MetaChar;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.TokenType;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.PosixBracket;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
+
+class Lexer extends ScannerSupport {
+    protected final ScanEnvironment env;
+    protected final Syntax syntax;              // fast access to syntax
+    protected final Token token = new Token();  // current token
+
+    protected Lexer(ScanEnvironment env, char[] chars, int p, int end) {
+        super(chars, p, end);
+        this.env = env;
+        this.syntax = env.syntax;
+    }
+
+    /**
+     * @return 0: normal {n,m}, 2: fixed {n}
+     * !introduce returnCode here
+     */
+    private int fetchRangeQuantifier() {
+        mark();
+        boolean synAllow = syntax.allowInvalidInterval();
+
+        if (!left()) {
+            if (synAllow) {
+                return 1; /* "....{" : OK! */
+            } else {
+                newSyntaxException(ERR_END_PATTERN_AT_LEFT_BRACE);
+            }
+        }
+
+        if (!synAllow) {
+            c = peek();
+            if (c == ')' || c == '(' || c == '|') {
+                newSyntaxException(ERR_END_PATTERN_AT_LEFT_BRACE);
+            }
+        }
+
+        int low = scanUnsignedNumber();
+        if (low < 0) newSyntaxException(ErrorMessages.ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE);
+        if (low > Config.MAX_REPEAT_NUM) newSyntaxException(ErrorMessages.ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE);
+
+        boolean nonLow = false;
+        if (p == _p) { /* can't read low */
+            if (syntax.allowIntervalLowAbbrev()) {
+                low = 0;
+                nonLow = true;
+            } else {
+                return invalidRangeQuantifier(synAllow);
+            }
+        }
+
+        if (!left()) return invalidRangeQuantifier(synAllow);
+
+        fetch();
+        int up;
+        int ret = 0;
+        if (c == ',') {
+            int prev = p; // ??? last
+            up = scanUnsignedNumber();
+            if (up < 0) newValueException(ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE);
+            if (up > Config.MAX_REPEAT_NUM) newValueException(ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE);
+
+            if (p == prev) {
+                if (nonLow) return invalidRangeQuantifier(synAllow);
+                up = QuantifierNode.REPEAT_INFINITE; /* {n,} : {n,infinite} */
+            }
+        } else {
+            if (nonLow) return invalidRangeQuantifier(synAllow);
+            unfetch();
+            up = low; /* {n} : exact n times */
+            ret = 2; /* fixed */
+        }
+
+        if (!left()) return invalidRangeQuantifier(synAllow);
+        fetch();
+
+        if (syntax.opEscBraceInterval()) {
+            if (c != syntax.metaCharTable.esc) return invalidRangeQuantifier(synAllow);
+            fetch();
+        }
+
+        if (c != '}') return invalidRangeQuantifier(synAllow);
+
+        if (!isRepeatInfinite(up) && low > up) {
+            newValueException(ERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE);
+        }
+
+        token.type = TokenType.INTERVAL;
+        token.setRepeatLower(low);
+        token.setRepeatUpper(up);
+
+        return ret; /* 0: normal {n,m}, 2: fixed {n} */
+    }
+
+    private int invalidRangeQuantifier(boolean synAllow) {
+        if (synAllow) {
+            restore();
+            return 1;
+        } else {
+            newSyntaxException(ERR_INVALID_REPEAT_RANGE_PATTERN);
+            return 0; // not reached
+        }
+    }
+
+    /* \M-, \C-, \c, or \... */
+    private int fetchEscapedValue() {
+        if (!left()) newSyntaxException(ERR_END_PATTERN_AT_ESCAPE);
+        fetch();
+
+        switch(c) {
+
+        case 'M':
+            if (syntax.op2EscCapitalMBarMeta()) {
+                if (!left()) newSyntaxException(ERR_END_PATTERN_AT_META);
+                fetch();
+                if (c != '-') newSyntaxException(ERR_META_CODE_SYNTAX);
+                if (!left()) newSyntaxException(ERR_END_PATTERN_AT_META);
+                fetch();
+                if (c == syntax.metaCharTable.esc) {
+                    c = fetchEscapedValue();
+                }
+                c = ((c & 0xff) | 0x80);
+            } else {
+                fetchEscapedValueBackSlash();
+            }
+            break;
+
+        case 'C':
+            if (syntax.op2EscCapitalCBarControl()) {
+                if (!left()) newSyntaxException(ERR_END_PATTERN_AT_CONTROL);
+                fetch();
+                if (c != '-') newSyntaxException(ERR_CONTROL_CODE_SYNTAX);
+                fetchEscapedValueControl();
+            } else {
+                fetchEscapedValueBackSlash();
+            }
+            break;
+
+        case 'c':
+            if (syntax.opEscCControl()) {
+                fetchEscapedValueControl();
+            }
+            /* fall through */
+
+        default:
+            fetchEscapedValueBackSlash();
+        } // switch
+
+        return c; // ???
+    }
+
+    private void fetchEscapedValueBackSlash() {
+        c = env.convertBackslashValue(c);
+    }
+
+    private void fetchEscapedValueControl() {
+        if (!left()) newSyntaxException(ERR_END_PATTERN_AT_CONTROL);
+        fetch();
+        if (c == '?') {
+            c = 0177;
+        } else {
+            if (c == syntax.metaCharTable.esc) {
+                c = fetchEscapedValue();
+            }
+            c &= 0x9f;
+        }
+    }
+
+    private int nameEndCodePoint(int start) {
+        switch(start) {
+        case '<':
+            return '>';
+        case '\'':
+            return '\'';
+        default:
+            return 0;
+        }
+    }
+
+    // USE_NAMED_GROUP && USE_BACKREF_AT_LEVEL
+    /*
+        \k<name+n>, \k<name-n>
+        \k<num+n>,  \k<num-n>
+        \k<-num+n>, \k<-num-n>
+     */
+
+    // value implicit (rnameEnd)
+    private boolean fetchNameWithLevel(int startCode, Ptr rbackNum, Ptr rlevel) {
+        int src = p;
+        boolean existLevel = false;
+        int isNum = 0;
+        int sign = 1;
+
+        int endCode = nameEndCodePoint(startCode);
+        int pnumHead = p;
+        int nameEnd = stop;
+
+        String err = null;
+        if (!left()) {
+            newValueException(ERR_EMPTY_GROUP_NAME);
+        } else {
+            fetch();
+            if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
+            if (Character.isDigit(c)) {
+                isNum = 1;
+            } else if (c == '-') {
+                isNum = 2;
+                sign = -1;
+                pnumHead = p;
+            } else if (!EncodingHelper.isWord(c)) {
+                err = ERR_INVALID_GROUP_NAME;
+            }
+        }
+
+        while (left()) {
+            nameEnd = p;
+            fetch();
+            if (c == endCode || c == ')' || c == '+' || c == '-') {
+                if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
+                break;
+            }
+
+            if (isNum != 0) {
+                if (EncodingHelper.isDigit(c)) {
+                    isNum = 1;
+                } else {
+                    err = ERR_INVALID_GROUP_NAME;
+                    // isNum = 0;
+                }
+            } else if (!EncodingHelper.isWord(c)) {
+                err = ERR_INVALID_CHAR_IN_GROUP_NAME;
+            }
+        }
+
+        boolean isEndCode = false;
+        if (err == null && c != endCode) {
+            if (c == '+' || c == '-') {
+                int flag = c == '-' ? -1 : 1;
+
+                fetch();
+                if (!EncodingHelper.isDigit(c)) newValueException(ERR_INVALID_GROUP_NAME, src, stop);
+                unfetch();
+                int level = scanUnsignedNumber();
+                if (level < 0) newValueException(ERR_TOO_BIG_NUMBER);
+                rlevel.p = level * flag;
+                existLevel = true;
+
+                fetch();
+                isEndCode = c == endCode;
+            }
+
+            if (!isEndCode) {
+                err = ERR_INVALID_GROUP_NAME;
+                nameEnd = stop;
+            }
+        }
+
+        if (err == null) {
+            if (isNum != 0) {
+                mark();
+                p = pnumHead;
+                int backNum = scanUnsignedNumber();
+                restore();
+                if (backNum < 0) {
+                    newValueException(ERR_TOO_BIG_NUMBER);
+                } else if (backNum == 0) {
+                    newValueException(ERR_INVALID_GROUP_NAME, src, stop);
+                }
+                rbackNum.p = backNum * sign;
+            }
+            value = nameEnd;
+            return existLevel;
+        } else {
+            newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
+            return false; // not reached
+        }
+    }
+
+    // USE_NAMED_GROUP
+    // ref: 0 -> define name    (don't allow number name)
+    //      1 -> reference name (allow number name)
+    private int fetchNameForNamedGroup(int startCode, boolean ref) {
+        int src = p;
+        value = 0;
+
+        int isNum = 0;
+        int sign = 1;
+
+        int endCode = nameEndCodePoint(startCode);
+        int pnumHead = p;
+        int nameEnd = stop;
+
+        String err = null;
+        if (!left()) {
+            newValueException(ERR_EMPTY_GROUP_NAME);
+        } else {
+            fetch();
+            if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
+            if (EncodingHelper.isDigit(c)) {
+                if (ref) {
+                    isNum = 1;
+                } else {
+                    err = ERR_INVALID_GROUP_NAME;
+                    // isNum = 0;
+                }
+            } else if (c == '-') {
+                if (ref) {
+                    isNum = 2;
+                    sign = -1;
+                    pnumHead = p;
+                } else {
+                    err = ERR_INVALID_GROUP_NAME;
+                    // isNum = 0;
+                }
+            } else if (!EncodingHelper.isWord(c)) {
+                err = ERR_INVALID_CHAR_IN_GROUP_NAME;
+            }
+        }
+
+        if (err == null) {
+            while (left()) {
+                nameEnd = p;
+                fetch();
+                if (c == endCode || c == ')') {
+                    if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
+                    break;
+                }
+
+                if (isNum != 0) {
+                    if (EncodingHelper.isDigit(c)) {
+                        isNum = 1;
+                    } else {
+                        if (!EncodingHelper.isWord(c)) {
+                            err = ERR_INVALID_CHAR_IN_GROUP_NAME;
+                        } else {
+                            err = ERR_INVALID_GROUP_NAME;
+                        }
+                        // isNum = 0;
+                    }
+                } else {
+                    if (!EncodingHelper.isWord(c)) {
+                        err = ERR_INVALID_CHAR_IN_GROUP_NAME;
+                    }
+                }
+            }
+
+            if (c != endCode) {
+                err = ERR_INVALID_GROUP_NAME;
+                nameEnd = stop;
+            }
+
+            int backNum = 0;
+            if (isNum != 0) {
+                mark();
+                p = pnumHead;
+                backNum = scanUnsignedNumber();
+                restore();
+                if (backNum < 0) {
+                    newValueException(ERR_TOO_BIG_NUMBER);
+                } else if (backNum == 0) {
+                    newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
+                }
+                backNum *= sign;
+            }
+            value = nameEnd;
+            return backNum;
+        } else {
+            while (left()) {
+                nameEnd = p;
+                fetch();
+                if (c == endCode || c == ')') break;
+            }
+            if (!left()) nameEnd = stop;
+            newValueException(err, src, nameEnd);
+            return 0; // not reached
+        }
+    }
+
+    // #else USE_NAMED_GROUP
+    // make it return nameEnd!
+    private final int fetchNameForNoNamedGroup(int startCode, boolean ref) {
+        int src = p;
+        value = 0;
+
+        int isNum = 0;
+        int sign = 1;
+
+        int endCode = nameEndCodePoint(startCode);
+        int pnumHead = p;
+        int nameEnd = stop;
+
+        String err = null;
+        if (!left()) {
+            newValueException(ERR_EMPTY_GROUP_NAME);
+        } else {
+            fetch();
+            if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
+
+            if (EncodingHelper.isDigit(c)) {
+                isNum = 1;
+            } else if (c == '-') {
+                isNum = 2;
+                sign = -1;
+                pnumHead = p;
+            } else {
+                err = ERR_INVALID_CHAR_IN_GROUP_NAME;
+            }
+        }
+
+        while(left()) {
+            nameEnd = p;
+
+            fetch();
+            if (c == endCode || c == ')') break;
+            if (!EncodingHelper.isDigit(c)) err = ERR_INVALID_CHAR_IN_GROUP_NAME;
+        }
+
+        if (err == null && c != endCode) {
+            err = ERR_INVALID_GROUP_NAME;
+            nameEnd = stop;
+        }
+
+        if (err == null) {
+            mark();
+            p = pnumHead;
+            int backNum = scanUnsignedNumber();
+            restore();
+            if (backNum < 0) {
+                newValueException(ERR_TOO_BIG_NUMBER);
+            } else if (backNum == 0){
+                newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
+            }
+            backNum *= sign;
+
+            value = nameEnd;
+            return backNum;
+        } else {
+            newValueException(err, src, nameEnd);
+            return 0; // not reached
+        }
+    }
+
+    protected final int fetchName(int startCode, boolean ref) {
+        if (Config.USE_NAMED_GROUP) {
+            return fetchNameForNamedGroup(startCode, ref);
+        } else {
+            return fetchNameForNoNamedGroup(startCode, ref);
+        }
+    }
+
+    private boolean strExistCheckWithEsc(int[]s, int n, int bad) {
+        int p = this.p;
+        int to = this.stop;
+
+        boolean inEsc = false;
+        int i=0;
+        while(p < to) {
+            if (inEsc) {
+                inEsc = false;
+                p ++;
+            } else {
+                int x = chars[p];
+                int q = p + 1;
+                if (x == s[0]) {
+                    for (i=1; i<n && q < to; i++) {
+                        x = chars[q];
+                        if (x != s[i]) break;
+                        q++;
+                    }
+                    if (i >= n) return true;
+                    p++;
+                } else {
+                    x = chars[p];
+                    if (x == bad) return false;
+                    else if (x == syntax.metaCharTable.esc) inEsc = true;
+                    p = q;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static final int send[] = new int[]{':', ']'};
+
+    private void fetchTokenInCCFor_charType(boolean flag, int type) {
+        token.type = TokenType.CHAR_TYPE;
+        token.setPropCType(type);
+        token.setPropNot(flag);
+    }
+
+    private void fetchTokenInCCFor_p() {
+        int c2 = peek(); // !!! migrate to peekIs
+        if (c2 == '{' && syntax.op2EscPBraceCharProperty()) {
+            inc();
+            token.type = TokenType.CHAR_PROPERTY;
+            token.setPropNot(c == 'P');
+
+            if (syntax.op2EscPBraceCircumflexNot()) {
+                c2 = fetchTo();
+                if (c2 == '^') {
+                    token.setPropNot(!token.getPropNot());
+                } else {
+                    unfetch();
+                }
+            }
+        } else {
+            syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
+        }
+    }
+
+    private void fetchTokenInCCFor_x() {
+        if (!left()) return;
+        int last = p;
+
+        if (peekIs('{') && syntax.opEscXBraceHex8()) {
+            inc();
+            int num = scanUnsignedHexadecimalNumber(8);
+            if (num < 0) newValueException(ERR_TOO_BIG_WIDE_CHAR_VALUE);
+            if (left()) {
+                int c2 = peek();
+                if (EncodingHelper.isXDigit(c2)) newValueException(ERR_TOO_LONG_WIDE_CHAR_VALUE);
+            }
+
+            if (p > last + 1 && left() && peekIs('}')) {
+                inc();
+                token.type = TokenType.CODE_POINT;
+                token.base = 16;
+                token.setCode(num);
+            } else {
+                /* can't read nothing or invalid format */
+                p = last;
+            }
+        } else if (syntax.opEscXHex2()) {
+            int num = scanUnsignedHexadecimalNumber(2);
+            if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+            if (p == last) { /* can't read nothing. */
+                num = 0; /* but, it's not error */
+            }
+            token.type = TokenType.RAW_BYTE;
+            token.base = 16;
+            token.setC(num);
+        }
+    }
+
+    private void fetchTokenInCCFor_u() {
+        if (!left()) return;
+        int last = p;
+
+        if (syntax.op2EscUHex4()) {
+            int num = scanUnsignedHexadecimalNumber(4);
+            if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+            if (p == last) {  /* can't read nothing. */
+                num = 0; /* but, it's not error */
+            }
+            token.type = TokenType.CODE_POINT;
+            token.base = 16;
+            token.setCode(num);
+        }
+    }
+
+    private void fetchTokenInCCFor_digit() {
+        if (syntax.opEscOctal3()) {
+            unfetch();
+            int last = p;
+            int num = scanUnsignedOctalNumber(3);
+            if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+            if (p == last) {  /* can't read nothing. */
+                num = 0; /* but, it's not error */
+            }
+            token.type = TokenType.RAW_BYTE;
+            token.base = 8;
+            token.setC(num);
+        }
+    }
+
+    private void fetchTokenInCCFor_posixBracket() {
+        if (syntax.opPosixBracket() && peekIs(':')) {
+            token.backP = p; /* point at '[' is readed */
+            inc();
+            if (strExistCheckWithEsc(send, send.length, ']')) {
+                token.type = TokenType.POSIX_BRACKET_OPEN;
+            } else {
+                unfetch();
+                // remove duplication, goto cc_in_cc;
+                if (syntax.op2CClassSetOp()) {
+                    token.type = TokenType.CC_CC_OPEN;
+                } else {
+                    env.ccEscWarn("[");
+                }
+            }
+        } else { // cc_in_cc:
+            if (syntax.op2CClassSetOp()) {
+                token.type = TokenType.CC_CC_OPEN;
+            } else {
+                env.ccEscWarn("[");
+            }
+        }
+    }
+
+    private void fetchTokenInCCFor_and() {
+        if (syntax.op2CClassSetOp() && left() && peekIs('&')) {
+            inc();
+            token.type = TokenType.CC_AND;
+        }
+    }
+
+    protected final TokenType fetchTokenInCC() {
+        if (!left()) {
+            token.type = TokenType.EOT;
+            return token.type;
+        }
+
+        fetch();
+        token.type = TokenType.CHAR;
+        token.base = 0;
+        token.setC(c);
+        token.escaped = false;
+
+        if (c == ']') {
+            token.type = TokenType.CC_CLOSE;
+        } else if (c == '-') {
+            token.type = TokenType.CC_RANGE;
+        } else if (c == syntax.metaCharTable.esc) {
+            if (!syntax.backSlashEscapeInCC()) return token.type;
+            if (!left()) newSyntaxException(ERR_END_PATTERN_AT_ESCAPE);
+            fetch();
+            token.escaped = true;
+            token.setC(c);
+
+            switch (c) {
+            case 'w':
+                fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
+                break;
+            case 'W':
+                fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
+                break;
+            case 'd':
+                fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
+                break;
+            case 'D':
+                fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
+                break;
+            case 's':
+                fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
+                break;
+            case 'S':
+                fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
+                break;
+            case 'h':
+                if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(false, CharacterType.XDIGIT);
+                break;
+            case 'H':
+                if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
+                break;
+            case 'p':
+            case 'P':
+                fetchTokenInCCFor_p();
+                break;
+            case 'x':
+                fetchTokenInCCFor_x();
+                break;
+            case 'u':
+                fetchTokenInCCFor_u();
+                break;
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+                fetchTokenInCCFor_digit();
+                break;
+
+            default:
+                unfetch();
+                int num = fetchEscapedValue();
+                if (token.getC() != num) {
+                    token.setCode(num);
+                    token.type = TokenType.CODE_POINT;
+                }
+                break;
+            } // switch
+
+        } else if (c == '[') {
+            fetchTokenInCCFor_posixBracket();
+        } else if (c == '&') {
+            fetchTokenInCCFor_and();
+        }
+        return token.type;
+    }
+
+    protected final int backrefRelToAbs(int relNo) {
+        return env.numMem + 1 + relNo;
+    }
+
+    private void fetchTokenFor_repeat(int lower, int upper) {
+        token.type = TokenType.OP_REPEAT;
+        token.setRepeatLower(lower);
+        token.setRepeatUpper(upper);
+        greedyCheck();
+    }
+
+    private void fetchTokenFor_openBrace() {
+        switch (fetchRangeQuantifier()) {
+        case 0:
+            greedyCheck();
+            break;
+        case 2:
+            if (syntax.fixedIntervalIsGreedyOnly()) {
+                possessiveCheck();
+            } else {
+                greedyCheck();
+            }
+            break;
+        default: /* 1 : normal char */
+        } // inner switch
+    }
+
+    private void fetchTokenFor_anchor(int subType) {
+        token.type = TokenType.ANCHOR;
+        token.setAnchor(subType);
+    }
+
+    private void fetchTokenFor_xBrace() {
+        if (!left()) return;
+
+        int last = p;
+        if (peekIs('{') && syntax.opEscXBraceHex8()) {
+            inc();
+            int num = scanUnsignedHexadecimalNumber(8);
+            if (num < 0) newValueException(ERR_TOO_BIG_WIDE_CHAR_VALUE);
+            if (left()) {
+                if (EncodingHelper.isXDigit(peek())) newValueException(ERR_TOO_LONG_WIDE_CHAR_VALUE);
+            }
+
+            if (p > last + 1 && left() && peekIs('}')) {
+                inc();
+                token.type = TokenType.CODE_POINT;
+                token.setCode(num);
+            } else {
+                /* can't read nothing or invalid format */
+                p = last;
+            }
+        } else if (syntax.opEscXHex2()) {
+            int num = scanUnsignedHexadecimalNumber(2);
+            if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+            if (p == last) { /* can't read nothing. */
+                num = 0; /* but, it's not error */
+            }
+            token.type = TokenType.RAW_BYTE;
+            token.base = 16;
+            token.setC(num);
+        }
+    }
+
+    private void fetchTokenFor_uHex() {
+        if (!left()) return;
+        int last = p;
+
+        if (syntax.op2EscUHex4()) {
+            int num = scanUnsignedHexadecimalNumber(4);
+            if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+            if (p == last) { /* can't read nothing. */
+                num = 0; /* but, it's not error */
+            }
+            token.type = TokenType.CODE_POINT;
+            token.base = 16;
+            token.setCode(num);
+        }
+    }
+
+    private void fetchTokenFor_digit() {
+        unfetch();
+        int last = p;
+        int num = scanUnsignedNumber();
+        if (num < 0 || num > Config.MAX_BACKREF_NUM) { // goto skip_backref
+        } else if (syntax.opDecimalBackref() && (num <= env.numMem || num <= 9)) { /* This spec. from GNU regex */
+            if (syntax.strictCheckBackref()) {
+                if (num > env.numMem || env.memNodes == null || env.memNodes[num] == null) newValueException(ERR_INVALID_BACKREF);
+            }
+            token.type = TokenType.BACKREF;
+            token.setBackrefNum(1);
+            token.setBackrefRef1(num);
+            token.setBackrefByName(false);
+            if (Config.USE_BACKREF_WITH_LEVEL) token.setBackrefExistLevel(false);
+            return;
+        }
+
+        if (c == '8' || c == '9') { /* normal char */ // skip_backref:
+            p = last;
+            inc();
+            return;
+        }
+        p = last;
+
+        fetchTokenFor_zero(); /* fall through */
+    }
+
+    private void fetchTokenFor_zero() {
+        if (syntax.opEscOctal3()) {
+            int last = p;
+            int num = scanUnsignedOctalNumber(c == '0' ? 2 : 3);
+            if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+            if (p == last) { /* can't read nothing. */
+                num = 0; /* but, it's not error */
+            }
+            token.type = TokenType.RAW_BYTE;
+            token.base = 8;
+            token.setC(num);
+        } else if (c != '0') {
+            inc();
+        }
+    }
+
+    private void fetchTokenFor_namedBackref() {
+        if (syntax.op2EscKNamedBackref()) {
+            if (left()) {
+                fetch();
+                if (c =='<' || c == '\'') {
+                    int last = p;
+                    int backNum;
+                    if (Config.USE_BACKREF_WITH_LEVEL) {
+                        Ptr rbackNum = new Ptr();
+                        Ptr rlevel = new Ptr();
+                        token.setBackrefExistLevel(fetchNameWithLevel(c, rbackNum, rlevel));
+                        token.setBackrefLevel(rlevel.p);
+                        backNum = rbackNum.p;
+                    } else {
+                        backNum = fetchName(c, true);
+                    } // USE_BACKREF_AT_LEVEL
+                    int nameEnd = value; // set by fetchNameWithLevel/fetchName
+
+                    if (backNum != 0) {
+                        if (backNum < 0) {
+                            backNum = backrefRelToAbs(backNum);
+                            if (backNum <= 0) newValueException(ERR_INVALID_BACKREF);
+                        }
+
+                        if (syntax.strictCheckBackref() && (backNum > env.numMem || env.memNodes == null)) {
+                            newValueException(ERR_INVALID_BACKREF);
+                        }
+                        token.type = TokenType.BACKREF;
+                        token.setBackrefByName(false);
+                        token.setBackrefNum(1);
+                        token.setBackrefRef1(backNum);
+                    } else {
+                        NameEntry e = env.reg.nameToGroupNumbers(chars, last, nameEnd);
+                        if (e == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, last, nameEnd);
+
+                        if (syntax.strictCheckBackref()) {
+                            if (e.backNum == 1) {
+                                if (e.backRef1 > env.numMem ||
+                                    env.memNodes == null ||
+                                    env.memNodes[e.backRef1] == null) newValueException(ERR_INVALID_BACKREF);
+                            } else {
+                                for (int i=0; i<e.backNum; i++) {
+                                    if (e.backRefs[i] > env.numMem ||
+                                        env.memNodes == null ||
+                                        env.memNodes[e.backRefs[i]] == null) newValueException(ERR_INVALID_BACKREF);
+                                }
+                            }
+                        }
+
+                        token.type = TokenType.BACKREF;
+                        token.setBackrefByName(true);
+
+                        if (e.backNum == 1) {
+                            token.setBackrefNum(1);
+                            token.setBackrefRef1(e.backRef1);
+                        } else {
+                            token.setBackrefNum(e.backNum);
+                            token.setBackrefRefs(e.backRefs);
+                        }
+                    }
+                } else {
+                    unfetch();
+                    syntaxWarn(Warnings.INVALID_BACKREFERENCE);
+                }
+            } else {
+                syntaxWarn(Warnings.INVALID_BACKREFERENCE);
+            }
+        }
+    }
+
+    private void fetchTokenFor_subexpCall() {
+        if (syntax.op2EscGSubexpCall()) {
+            if (left()) {
+                fetch();
+                if (c == '<' || c == '\'') {
+                    int last = p;
+                    int gNum = fetchName(c, true);
+                    int nameEnd = value;
+                    token.type = TokenType.CALL;
+                    token.setCallNameP(last);
+                    token.setCallNameEnd(nameEnd);
+                    token.setCallGNum(gNum);
+                } else {
+                    unfetch();
+                    syntaxWarn(Warnings.INVALID_SUBEXP_CALL);
+                }
+            } else {
+                syntaxWarn(Warnings.INVALID_SUBEXP_CALL);
+            }
+        }
+    }
+
+    private void fetchTokenFor_charProperty() {
+        if (peekIs('{') && syntax.op2EscPBraceCharProperty()) {
+            inc();
+            token.type = TokenType.CHAR_PROPERTY;
+            token.setPropNot(c == 'P');
+
+            if (syntax.op2EscPBraceCircumflexNot()) {
+                fetch();
+                if (c == '^') {
+                    token.setPropNot(!token.getPropNot());
+                } else {
+                    unfetch();
+                }
+            }
+        } else {
+            syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
+        }
+    }
+
+    private void fetchTokenFor_metaChars() {
+        if (c == syntax.metaCharTable.anyChar) {
+            token.type = TokenType.ANYCHAR;
+        } else if (c == syntax.metaCharTable.anyTime) {
+            fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
+        }  else if (c == syntax.metaCharTable.zeroOrOneTime) {
+            fetchTokenFor_repeat(0, 1);
+        } else if (c == syntax.metaCharTable.oneOrMoreTime) {
+            fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
+        } else if (c == syntax.metaCharTable.anyCharAnyTime) {
+            token.type = TokenType.ANYCHAR_ANYTIME;
+            // goto out
+        }
+    }
+
+    protected final TokenType fetchToken() {
+        // mark(); // out
+        start:
+        while(true) {
+            if (!left()) {
+                token.type = TokenType.EOT;
+                return token.type;
+            }
+
+            token.type = TokenType.STRING;
+            token.base = 0;
+            token.backP = p;
+
+            fetch();
+
+            if (c == syntax.metaCharTable.esc && !syntax.op2IneffectiveEscape()) { // IS_MC_ESC_CODE(code, syn)
+                if (!left()) newSyntaxException(ERR_END_PATTERN_AT_ESCAPE);
+
+                token.backP = p;
+                fetch();
+
+                token.setC(c);
+                token.escaped = true;
+                switch(c) {
+
+                case '*':
+                    if (syntax.opEscAsteriskZeroInf()) fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
+                    break;
+                case '+':
+                    if (syntax.opEscPlusOneInf()) fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
+                    break;
+                case '?':
+                    if (syntax.opEscQMarkZeroOne()) fetchTokenFor_repeat(0, 1);
+                    break;
+                case '{':
+                    if (syntax.opEscBraceInterval()) fetchTokenFor_openBrace();
+                    break;
+                case '|':
+                    if (syntax.opEscVBarAlt()) token.type = TokenType.ALT;
+                    break;
+                case '(':
+                    if (syntax.opEscLParenSubexp()) token.type = TokenType.SUBEXP_OPEN;
+                    break;
+                case ')':
+                    if (syntax.opEscLParenSubexp()) token.type = TokenType.SUBEXP_CLOSE;
+                    break;
+                case 'w':
+                    if (syntax.opEscWWord()) fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
+                    break;
+                case 'W':
+                    if (syntax.opEscWWord()) fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
+                    break;
+                case 'b':
+                    if (syntax.opEscBWordBound()) fetchTokenFor_anchor(AnchorType.WORD_BOUND);
+                    break;
+                case 'B':
+                    if (syntax.opEscBWordBound()) fetchTokenFor_anchor(AnchorType.NOT_WORD_BOUND);
+                    break;
+                case '<':
+                    if (Config.USE_WORD_BEGIN_END && syntax.opEscLtGtWordBeginEnd()) fetchTokenFor_anchor(AnchorType.WORD_BEGIN);
+                    break;
+                case '>':
+                    if (Config.USE_WORD_BEGIN_END && syntax.opEscLtGtWordBeginEnd()) fetchTokenFor_anchor(AnchorType.WORD_END);
+                    break;
+                case 's':
+                    if (syntax.opEscSWhiteSpace()) fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
+                    break;
+                case 'S':
+                    if (syntax.opEscSWhiteSpace()) fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
+                    break;
+                case 'd':
+                    if (syntax.opEscDDigit()) fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
+                    break;
+                case 'D':
+                    if (syntax.opEscDDigit()) fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
+                    break;
+                case 'h':
+                    if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(false, CharacterType.XDIGIT);
+                    break;
+                case 'H':
+                    if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
+                    break;
+                case 'A':
+                    if (syntax.opEscAZBufAnchor()) fetchTokenFor_anchor(AnchorType.BEGIN_BUF);
+                    break;
+                case 'Z':
+                    if (syntax.opEscAZBufAnchor()) fetchTokenFor_anchor(AnchorType.SEMI_END_BUF);
+                    break;
+                case 'z':
+                    if (syntax.opEscAZBufAnchor()) fetchTokenFor_anchor(AnchorType.END_BUF);
+                    break;
+                case 'G':
+                    if (syntax.opEscCapitalGBeginAnchor()) fetchTokenFor_anchor(AnchorType.BEGIN_POSITION);
+                    break;
+                case '`':
+                    if (syntax.op2EscGnuBufAnchor()) fetchTokenFor_anchor(AnchorType.BEGIN_BUF);
+                    break;
+                case '\'':
+                    if (syntax.op2EscGnuBufAnchor()) fetchTokenFor_anchor(AnchorType.END_BUF);
+                    break;
+                case 'x':
+                    fetchTokenFor_xBrace();
+                    break;
+                case 'u':
+                    fetchTokenFor_uHex();
+                    break;
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                    fetchTokenFor_digit();
+                    break;
+                case '0':
+                    fetchTokenFor_zero();
+                    break;
+                case 'k':
+                    if (Config.USE_NAMED_GROUP) fetchTokenFor_namedBackref();
+                    break;
+                case 'g':
+                    if (Config.USE_SUBEXP_CALL) fetchTokenFor_subexpCall();
+                    break;
+                case 'Q':
+                    if (syntax.op2EscCapitalQQuote()) token.type = TokenType.QUOTE_OPEN;
+                    break;
+                case 'p':
+                case 'P':
+                    fetchTokenFor_charProperty();
+                    break;
+
+                default:
+                    unfetch();
+                    int num = fetchEscapedValue();
+
+                    /* set_raw: */
+                    if (token.getC() != num) {
+                        token.type = TokenType.CODE_POINT;
+                        token.setCode(num);
+                    } else { /* string */
+                        p = token.backP + 1;
+                    }
+                    break;
+
+                } // switch (c)
+
+            } else {
+                token.setC(c);
+                token.escaped = false;
+
+                if (Config.USE_VARIABLE_META_CHARS && (c != MetaChar.INEFFECTIVE_META_CHAR && syntax.opVariableMetaCharacters())) {
+                    fetchTokenFor_metaChars();
+                    break;
+                }
+
+                {
+                    switch(c) {
+                    case '.':
+                        if (syntax.opDotAnyChar()) token.type = TokenType.ANYCHAR;
+                        break;
+                    case '*':
+                        if (syntax.opAsteriskZeroInf()) fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
+                        break;
+                    case '+':
+                        if (syntax.opPlusOneInf()) fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
+                        break;
+                    case '?':
+                        if (syntax.opQMarkZeroOne()) fetchTokenFor_repeat(0, 1);
+                        break;
+                    case '{':
+                        if (syntax.opBraceInterval()) fetchTokenFor_openBrace();
+                        break;
+                    case '|':
+                        if (syntax.opVBarAlt()) token.type = TokenType.ALT;
+                        break;
+
+                    case '(':
+                        if (peekIs('?') && syntax.op2QMarkGroupEffect()) {
+                            inc();
+                            if (peekIs('#')) {
+                                fetch();
+                                while (true) {
+                                    if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
+                                    fetch();
+                                    if (c == syntax.metaCharTable.esc) {
+                                        if (left()) fetch();
+                                    } else {
+                                        if (c == ')') break;
+                                    }
+                                }
+                                continue start; // goto start
+                            }
+                            unfetch();
+                        }
+
+                        if (syntax.opLParenSubexp()) token.type = TokenType.SUBEXP_OPEN;
+                        break;
+                    case ')':
+                        if (syntax.opLParenSubexp()) token.type = TokenType.SUBEXP_CLOSE;
+                        break;
+                    case '^':
+                        if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.BEGIN_BUF : AnchorType.BEGIN_LINE);
+                        break;
+                    case '$':
+                        if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.SEMI_END_BUF : AnchorType.END_LINE);
+                        break;
+                    case '[':
+                        if (syntax.opBracketCC()) token.type = TokenType.CC_CC_OPEN;
+                        break;
+                    case ']':
+                        //if (*src > env->pattern)   /* /].../ is allowed. */
+                        //CLOSE_BRACKET_WITHOUT_ESC_WARN(env, (UChar* )"]");
+                        break;
+                    case '#':
+                        if (Option.isExtend(env.option)) {
+                            while (left()) {
+                                fetch();
+                                if (EncodingHelper.isNewLine(c)) break;
+                            }
+                            continue start; // goto start
+                        }
+                        break;
+
+                    case ' ':
+                    case '\t':
+                    case '\n':
+                    case '\r':
+                    case '\f':
+                        if (Option.isExtend(env.option)) continue start; // goto start
+                        break;
+
+                    default: // string
+                        break;
+
+                    } // switch
+                }
+            }
+
+            break;
+        } // while
+        return token.type;
+    }
+
+    private void greedyCheck() {
+        if (left() && peekIs('?') && syntax.opQMarkNonGreedy()) {
+
+            fetch();
+
+            token.setRepeatGreedy(false);
+            token.setRepeatPossessive(false);
+        } else {
+            possessiveCheck();
+        }
+    }
+
+    private void possessiveCheck() {
+        if (left() && peekIs('+') &&
+            (syntax.op2PlusPossessiveRepeat() && token.type != TokenType.INTERVAL ||
+             syntax.op2PlusPossessiveInterval() && token.type == TokenType.INTERVAL)) {
+
+            fetch();
+
+            token.setRepeatGreedy(true);
+            token.setRepeatPossessive(true);
+        } else {
+            token.setRepeatGreedy(true);
+            token.setRepeatPossessive(false);
+        }
+    }
+
+    protected final int fetchCharPropertyToCType() {
+        mark();
+
+        while (left()) {
+            int last = p;
+            fetch();
+            if (c == '}') {
+                String name = new String(chars, _p, last - _p);
+                return PosixBracket.propertyNameToCType(name);
+            } else if (c == '(' || c == ')' || c == '{' || c == '|') {
+                String name = new String(chars, _p, last - _p);
+                throw new JOniException(ERR_INVALID_CHAR_PROPERTY_NAME.replaceAll("%n", name));
+            }
+        }
+        newInternalException(ERR_PARSER_BUG);
+        return 0; // not reached
+    }
+
+    protected final void syntaxWarn(String message, char c) {
+        syntaxWarn(message.replace("<%n>", Character.toString(c)));
+    }
+
+    protected final void syntaxWarn(String message) {
+        if (Config.USE_WARN) {
+            env.reg.warnings.warn(message + ": /" + new String(chars, getBegin(), getEnd()) + "/");
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java
new file mode 100644
index 0000000..4aea4ac
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java
@@ -0,0 +1,556 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindLongest;
+
+import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
+
+public abstract class Matcher extends IntHolder {
+    protected final Regex regex;
+
+    protected final char[] chars;
+    protected final int str;
+    protected final int end;
+
+    protected int msaStart;
+    protected int msaOptions;
+    protected final Region msaRegion;
+    protected int msaBestLen;
+    protected int msaBestS;
+
+    protected int msaBegin;
+    protected int msaEnd;
+
+    public Matcher(Regex regex, char[] chars) {
+        this(regex, chars, 0, chars.length);
+    }
+
+    public Matcher(Regex regex, char[] chars, int p, int end) {
+        this.regex = regex;
+
+        this.chars = chars;
+        this.str = p;
+        this.end = end;
+
+        this.msaRegion = regex.numMem == 0 ? null : new Region(regex.numMem + 1);
+    }
+
+    // main matching method
+    protected abstract int matchAt(int range, int sstart, int sprev);
+
+    protected abstract void stateCheckBuffInit(int strLength, int offset, int stateNum);
+    protected abstract void stateCheckBuffClear();
+
+    public final Region getRegion() {
+        return msaRegion;
+    }
+
+    public final Region getEagerRegion() {
+        return msaRegion != null ? msaRegion : new Region(msaBegin, msaEnd);
+    }
+
+    public final int getBegin() {
+        return msaBegin;
+    }
+
+    public final int getEnd() {
+        return msaEnd;
+    }
+
+    protected final void msaInit(int option, int start) {
+        msaOptions = option;
+        msaStart = start;
+        if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) msaBestLen = -1;
+    }
+
+    public final int match(int at, int range, int option) {
+        msaInit(option, at);
+
+        if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+            int offset = at = str;
+            stateCheckBuffInit(end - str, offset, regex.numCombExpCheck); // move it to construction?
+        } // USE_COMBINATION_EXPLOSION_CHECK
+
+        int prev = EncodingHelper.prevCharHead(str, at);
+
+        if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
+            return matchAt(end /*range*/, at, prev);
+        } else {
+            return matchAt(range /*range*/, at, prev);
+        }
+    }
+
+    int low, high; // these are the return values
+    private boolean forwardSearchRange(char[] chars, int str, int end, int s, int range, IntHolder lowPrev) {
+        int pprev = -1;
+        int p = s;
+
+        if (Config.DEBUG_SEARCH) {
+            Config.log.println("forward_search_range: "+
+                                "str: " + str +
+                                ", end: " + end +
+                                ", s: " + s +
+                                ", range: " + range);
+        }
+
+        if (regex.dMin > 0) {
+            p += regex.dMin;
+        }
+
+        retry:while (true) {
+            p = regex.searchAlgorithm.search(regex, chars, p, end, range);
+
+            if (p != -1 && p < range) {
+                if (p - regex.dMin < s) {
+                    // retry_gate:
+                    pprev = p;
+                    p++;
+                    continue retry;
+                }
+
+                if (regex.subAnchor != 0) {
+                    switch (regex.subAnchor) {
+                    case AnchorType.BEGIN_LINE:
+                        if (p != str) {
+                            int prev = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, p);
+                            if (!EncodingHelper.isNewLine(chars, prev, end)) {
+                                // goto retry_gate;
+                                pprev = p;
+                                p++;
+                                continue retry;
+                            }
+                        }
+                        break;
+
+                    case AnchorType.END_LINE:
+                        if (p == end) {
+                            if (!Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
+                                int prev = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, p);
+                                if (prev != -1 && EncodingHelper.isNewLine(chars, prev, end)) {
+                                    // goto retry_gate;
+                                    pprev = p;
+                                    p++;
+                                    continue retry;
+                                }
+                            }
+                        } else if (!EncodingHelper.isNewLine(chars, p, end) && (!Config.USE_CRNL_AS_LINE_TERMINATOR || !EncodingHelper.isCrnl(chars, p, end))) {
+                            //if () break;
+                            // goto retry_gate;
+                            pprev = p;
+                            p++;
+                            continue retry;
+                        }
+                        break;
+                    } // switch
+                }
+
+                if (regex.dMax == 0) {
+                    low = p;
+                    if (lowPrev != null) { // ??? // remove null checks
+                        if (low > s) {
+                            lowPrev.value = EncodingHelper.prevCharHead(s, p);
+                        } else {
+                            lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, p);
+                        }
+                    }
+                } else {
+                    if (regex.dMax != MinMaxLen.INFINITE_DISTANCE) {
+                        low = p - regex.dMax;
+
+                        if (low > s) {
+                            low = EncodingHelper.rightAdjustCharHeadWithPrev(low, lowPrev);
+                            if (lowPrev != null && lowPrev.value == -1) {
+                                lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : s, low);
+                            }
+                        } else {
+                            if (lowPrev != null) {
+                                lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, low);
+                            }
+                        }
+                    }
+                }
+                /* no needs to adjust *high, *high is used as range check only */
+                high = p - regex.dMin;
+
+                if (Config.DEBUG_SEARCH) {
+                    Config.log.println("forward_search_range success: "+
+                                        "low: " + (low - str) +
+                                        ", high: " + (high - str) +
+                                        ", dmin: " + regex.dMin +
+                                        ", dmax: " + regex.dMax);
+                }
+
+                return true;    /* success */
+            }
+
+            return false;   /* fail */
+        } //while
+    }
+
+    // low, high
+    private boolean backwardSearchRange(char[] chars, int str, int end, int s, int range, int adjrange) {
+        range += regex.dMin;
+        int p = s;
+
+        retry:while (true) {
+            p = regex.searchAlgorithm.searchBackward(regex, chars, range, adjrange, end, p, s, range);
+
+            if (p != -1) {
+                if (regex.subAnchor != 0) {
+                    switch (regex.subAnchor) {
+                    case AnchorType.BEGIN_LINE:
+                        if (p != str) {
+                            int prev = EncodingHelper.prevCharHead(str, p);
+                            if (!EncodingHelper.isNewLine(chars, prev, end)) {
+                                p = prev;
+                                continue retry;
+                            }
+                        }
+                        break;
+
+                    case AnchorType.END_LINE:
+                        if (p == end) {
+                            if (!Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
+                                int prev = EncodingHelper.prevCharHead(adjrange, p);
+                                if (prev == -1) return false;
+                                if (EncodingHelper.isNewLine(chars, prev, end)) {
+                                    p = prev;
+                                    continue retry;
+                                }
+                            }
+                        } else if (!EncodingHelper.isNewLine(chars, p, end) && (!Config.USE_CRNL_AS_LINE_TERMINATOR || !EncodingHelper.isCrnl(chars, p, end))) {
+                            p = EncodingHelper.prevCharHead(adjrange, p);
+                            if (p == -1) return false;
+                            continue retry;
+                        }
+                        break;
+                    } // switch
+                }
+
+                /* no needs to adjust *high, *high is used as range check only */
+                if (regex.dMax != MinMaxLen.INFINITE_DISTANCE) {
+                    low = p - regex.dMax;
+                    high = p - regex.dMin;
+                }
+
+                if (Config.DEBUG_SEARCH) {
+                    Config.log.println("backward_search_range: "+
+                                        "low: " + (low - str) +
+                                        ", high: " + (high - str));
+                }
+
+                return true;
+            }
+
+            if (Config.DEBUG_SEARCH) Config.log.println("backward_search_range: fail.");
+            return false;
+        } // while
+    }
+
+    // MATCH_AND_RETURN_CHECK
+    private boolean matchCheck(int upperRange, int s, int prev) {
+        if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
+            if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
+                //range = upperRange;
+                if (matchAt(upperRange, s, prev) != -1) {
+                    if (!isFindLongest(regex.options)) return true;
+                }
+            } else {
+                //range = upperRange;
+                if (matchAt(upperRange, s, prev) != -1) return true;
+            }
+        } else {
+            if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
+                if (matchAt(end, s, prev) != -1) {
+                    //range = upperRange;
+                    if (!isFindLongest(regex.options)) return true;
+                }
+            } else {
+                //range = upperRange;
+                if (matchAt(end, s, prev) != -1) return true;
+            }
+        }
+        return false;
+    }
+
+    public final int search(int start, int range, int option) {
+        int s, prev;
+        int origStart = start;
+        int origRange = range;
+
+        if (Config.DEBUG_SEARCH) {
+            Config.log.println("onig_search (entry point): "+
+                    "str: " + str +
+                    ", end: " + (end - str) +
+                    ", start: " + (start - str) +
+                    ", range " + (range - str));
+        }
+
+        if (start > end || start < str) return -1;
+
+        /* anchor optimize: resume search range */
+        if (regex.anchor != 0 && str < end) {
+            int minSemiEnd, maxSemiEnd;
+
+            if ((regex.anchor & AnchorType.BEGIN_POSITION) != 0) {
+                /* search start-position only */
+                // !begin_position:!
+                if (range > start) {
+                    range = start + 1;
+                } else {
+                    range = start;
+                }
+            } else if ((regex.anchor & AnchorType.BEGIN_BUF) != 0) {
+                /* search str-position only */
+                if (range > start) {
+                    if (start != str) return -1; // mismatch_no_msa;
+                    range = str + 1;
+                } else {
+                    if (range <= str) {
+                        start = str;
+                        range = str;
+                    } else {
+                        return -1; // mismatch_no_msa;
+                    }
+                }
+            } else if ((regex.anchor & AnchorType.END_BUF) != 0) {
+                minSemiEnd = maxSemiEnd = end;
+                // !end_buf:!
+                if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
+            } else if ((regex.anchor & AnchorType.SEMI_END_BUF) != 0) {
+                int preEnd = EncodingHelper.stepBack(str, end, 1);
+                maxSemiEnd = end;
+                if (EncodingHelper.isNewLine(chars, preEnd, end)) {
+                    minSemiEnd = preEnd;
+                    if (Config.USE_CRNL_AS_LINE_TERMINATOR) {
+                        preEnd = EncodingHelper.stepBack(str, preEnd, 1);
+                        if (preEnd != -1 && EncodingHelper.isCrnl(chars, preEnd, end)) {
+                            minSemiEnd = preEnd;
+                        }
+                    }
+                    if (minSemiEnd > str && start <= minSemiEnd) {
+                        // !goto end_buf;!
+                        if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
+                    }
+                } else {
+                    minSemiEnd = end;
+                    // !goto end_buf;!
+                    if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
+                }
+            } else if ((regex.anchor & AnchorType.ANYCHAR_STAR_ML) != 0) {
+                // goto !begin_position;!
+                if (range > start) {
+                    range = start + 1;
+                } else {
+                    range = start;
+                }
+            }
+
+        } else if (str == end) { /* empty string */
+            // empty address ?
+            if (Config.DEBUG_SEARCH) {
+                Config.log.println("onig_search: empty string.");
+            }
+
+            if (regex.thresholdLength == 0) {
+                s = start = str;
+                prev = -1;
+                msaInit(option, start);
+
+                if (Config.USE_COMBINATION_EXPLOSION_CHECK) stateCheckBuffClear();
+
+                if (matchCheck(end, s, prev)) return match(s);
+                return mismatch();
+            }
+            return -1; // goto mismatch_no_msa;
+        }
+
+        if (Config.DEBUG_SEARCH) {
+            Config.log.println("onig_search(apply anchor): " +
+                                "end: " + (end - str) +
+                                ", start " + (start - str) +
+                                ", range " + (range - str));
+        }
+
+        msaInit(option, origStart);
+        if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+            int offset = Math.min(start, range) - str;
+            stateCheckBuffInit(end - str, offset, regex.numCombExpCheck);
+        }
+
+        s = start;
+        if (range > start) {    /* forward search */
+            if (s > str) {
+                prev = EncodingHelper.prevCharHead(str, s);
+            } else {
+                prev = 0; // -1
+            }
+
+            if (regex.searchAlgorithm != SearchAlgorithm.NONE) {
+                int schRange = range;
+                if (regex.dMax != 0) {
+                    if (regex.dMax == MinMaxLen.INFINITE_DISTANCE) {
+                        schRange = end;
+                    } else {
+                        schRange += regex.dMax;
+                        if (schRange > end) schRange = end;
+                    }
+                }
+                if ((end - start) < regex.thresholdLength) return mismatch();
+
+                if (regex.dMax != MinMaxLen.INFINITE_DISTANCE) {
+                    do {
+                        if (!forwardSearchRange(chars, str, end, s, schRange, this)) return mismatch(); // low, high, lowPrev
+                        if (s < low) {
+                            s = low;
+                            prev = value;
+                        }
+                        while (s <= high) {
+                            if (matchCheck(origRange, s, prev)) return match(s); // ???
+                            prev = s;
+                            s++;
+                        }
+                    } while (s < range);
+                    return mismatch();
+
+                } else { /* check only. */
+                    if (!forwardSearchRange(chars, str, end, s, schRange, null)) return mismatch();
+
+                    if ((regex.anchor & AnchorType.ANYCHAR_STAR) != 0) {
+                        do {
+                            if (matchCheck(origRange, s, prev)) return match(s);
+                            prev = s;
+                            s++;
+                        } while (s < range);
+                        return mismatch();
+                    }
+
+                }
+            }
+
+            do {
+                if (matchCheck(origRange, s, prev)) return match(s);
+                prev = s;
+                s++;
+            } while (s < range);
+
+            if (s == range) { /* because empty match with /$/. */
+                if (matchCheck(origRange, s, prev)) return match(s);
+            }
+        } else { /* backward search */
+            if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
+                if (origStart < end) {
+                    origStart++; // /* is upper range */
+                }
+            }
+
+            if (regex.searchAlgorithm != SearchAlgorithm.NONE) {
+                int adjrange;
+                if (range < end) {
+                    adjrange = range;
+                } else {
+                    adjrange = end;
+                }
+                if (regex.dMax != MinMaxLen.INFINITE_DISTANCE && (end - range) >= regex.thresholdLength) {
+                    do {
+                        int schStart = s + regex.dMax;
+                        if (schStart > end) schStart = end;
+                        if (!backwardSearchRange(chars, str, end, schStart, range, adjrange)) return mismatch(); // low, high
+                        if (s > high) s = high;
+                        while (s != -1 && s >= low) {
+                            prev = EncodingHelper.prevCharHead(str, s);
+                            if (matchCheck(origStart, s, prev)) return match(s);
+                            s = prev;
+                        }
+                    } while (s >= range);
+                    return mismatch();
+                } else { /* check only. */
+                    if ((end - range) < regex.thresholdLength) return mismatch();
+
+                    int schStart = s;
+                    if (regex.dMax != 0) {
+                        if (regex.dMax == MinMaxLen.INFINITE_DISTANCE) {
+                            schStart = end;
+                        } else {
+                            schStart += regex.dMax;
+                            if (schStart > end) {
+                                schStart = end;
+                            }
+                        }
+                    }
+                    if (!backwardSearchRange(chars, str, end, schStart, range, adjrange)) return mismatch();
+                }
+            }
+
+            do {
+                prev = EncodingHelper.prevCharHead(str, s);
+                if (matchCheck(origStart, s, prev)) return match(s);
+                s = prev;
+            } while (s >= range);
+
+        }
+        return mismatch();
+    }
+
+    private boolean endBuf(int start, int range, int minSemiEnd, int maxSemiEnd) {
+        if ((maxSemiEnd - str) < regex.anchorDmin) return true; // mismatch_no_msa;
+
+        if (range > start) {
+            if ((minSemiEnd - start) > regex.anchorDmax) {
+                start = minSemiEnd - regex.anchorDmax;
+                if (start >= end) {
+                    /* match with empty at end */
+                    start = EncodingHelper.prevCharHead(str, end);
+                }
+            }
+            if ((maxSemiEnd - (range - 1)) < regex.anchorDmin) {
+                range = maxSemiEnd - regex.anchorDmin + 1;
+            }
+            if (start >= range) return true; // mismatch_no_msa;
+        } else {
+            if ((minSemiEnd - range) > regex.anchorDmax) {
+                range = minSemiEnd - regex.anchorDmax;
+            }
+            if ((maxSemiEnd - start) < regex.anchorDmin) {
+                start = maxSemiEnd - regex.anchorDmin;
+            }
+            if (range > start) return true; // mismatch_no_msa;
+        }
+        return false;
+    }
+
+    private int match(int s) {
+        return s - str; // sstart ???
+    }
+
+    private int mismatch() {
+        if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
+            if (msaBestLen >= 0) {
+                int s = msaBestS;
+                return match(s);
+            }
+        }
+        // falls through finish:
+        return -1;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory.java
new file mode 100644
index 0000000..f507018
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public abstract class MatcherFactory {
+    public abstract Matcher create(Regex regex, char[] chars, int p, int end);
+
+    static final MatcherFactory DEFAULT = new MatcherFactory() {
+        @Override
+        public Matcher create(Regex regex, char[] chars, int p, int end) {
+            return new ByteCodeMachine(regex, chars, p, end);
+        }
+    };
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MinMaxLen.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MinMaxLen.java
new file mode 100644
index 0000000..388c0c5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MinMaxLen.java
@@ -0,0 +1,139 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+final class MinMaxLen {
+    int min; /* min byte length */
+    int max; /* max byte length */
+
+    MinMaxLen() {
+    }
+
+    MinMaxLen(int min, int max) {
+        this.min = min;
+        this.max = max;
+    }
+
+    /* 1000 / (min-max-dist + 1) */
+    private static final short distValues[] = {
+        1000,  500,  333,  250,  200,  167,  143,  125,  111,  100,
+          91,   83,   77,   71,   67,   63,   59,   56,   53,   50,
+          48,   45,   43,   42,   40,   38,   37,   36,   34,   33,
+          32,   31,   30,   29,   29,   28,   27,   26,   26,   25,
+          24,   24,   23,   23,   22,   22,   21,   21,   20,   20,
+          20,   19,   19,   19,   18,   18,   18,   17,   17,   17,
+          16,   16,   16,   16,   15,   15,   15,   15,   14,   14,
+          14,   14,   14,   14,   13,   13,   13,   13,   13,   13,
+          12,   12,   12,   12,   12,   12,   11,   11,   11,   11,
+          11,   11,   11,   11,   11,   10,   10,   10,   10,   10
+    };
+
+    int distanceValue() {
+        if (max == INFINITE_DISTANCE) return 0;
+        int d = max - min;
+        /* return dist_vals[d] * 16 / (mm->min + 12); */
+        return d < distValues.length ? distValues[d] : 1;
+    }
+
+    int compareDistanceValue(MinMaxLen other, int v1, int v2) {
+        if (v2 <= 0) return -1;
+        if (v1 <= 0) return 1;
+
+        v1 *= distanceValue();
+        v2 *= other.distanceValue();
+
+        if (v2 > v1) return 1;
+        if (v2 < v1) return -1;
+
+        if (other.min < min) return 1;
+        if (other.min > min) return -1;
+        return 0;
+    }
+
+    boolean equal(MinMaxLen other) {
+        return min == other.min && max == other.max;
+    }
+
+    void set(int min, int max) {
+        this.min = min;
+        this.max = max;
+    }
+
+    void clear() {
+        min = max = 0;
+    }
+
+    void copy(MinMaxLen other) {
+        min = other.min;
+        max = other.max;
+    }
+
+    void add(MinMaxLen other) {
+        min = distanceAdd(min, other.min);
+        max = distanceAdd(max, other.max);
+    }
+
+    void addLength(int len) {
+        min = distanceAdd(min, len);
+        max = distanceAdd(max, len);
+    }
+
+    void altMerge(MinMaxLen other) {
+        if (min > other.min) min = other.min;
+        if (max < other.max) max = other.max;
+    }
+
+    static final int INFINITE_DISTANCE = 0x7FFFFFFF;
+    static int distanceAdd(int d1, int d2) {
+        if (d1 == INFINITE_DISTANCE || d2 == INFINITE_DISTANCE) {
+            return INFINITE_DISTANCE;
+        } else {
+            if (d1 <= INFINITE_DISTANCE - d2) return d1 + d2;
+            else return INFINITE_DISTANCE;
+        }
+    }
+
+    static int distanceMultiply(int d, int m) {
+        if (m == 0) return 0;
+        if (d < INFINITE_DISTANCE / m) {
+            return d * m;
+        } else {
+            return INFINITE_DISTANCE;
+        }
+    }
+
+    static String distanceRangeToString(int a, int b) {
+        String s = "";
+        if (a == INFINITE_DISTANCE) {
+            s += "inf";
+        } else {
+            s += "(" + a + ")";
+        }
+
+        s += "-";
+
+        if (b == INFINITE_DISTANCE) {
+            s += "inf";
+        } else {
+            s += "(" + b + ")";
+        }
+        return s;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NameEntry.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NameEntry.java
new file mode 100644
index 0000000..d35f725
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NameEntry.java
@@ -0,0 +1,97 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public final class NameEntry {
+    static final int INIT_NAME_BACKREFS_ALLOC_NUM = 8;
+
+    public final char[] name;
+    public final int nameP;
+    public final int nameEnd;
+
+    int backNum;
+    int backRef1;
+    int backRefs[];
+
+    public NameEntry(char[] chars, int p, int end) {
+        name = chars;
+        nameP = p;
+        nameEnd = end;
+    }
+
+    public int[] getBackRefs() {
+        switch (backNum) {
+        case 0:
+            return new int[]{};
+        case 1:
+            return new int[]{backRef1};
+        default:
+            int[]result = new int[backNum];
+            System.arraycopy(backRefs, 0, result, 0, backNum);
+            return result;
+        }
+    }
+
+    private void alloc() {
+        backRefs = new int[INIT_NAME_BACKREFS_ALLOC_NUM];
+    }
+
+    private void ensureSize() {
+        if (backNum > backRefs.length) {
+            int[]tmp = new int[backRefs.length << 1];
+            System.arraycopy(backRefs, 0, tmp, 0, backRefs.length);
+            backRefs = tmp;
+        }
+    }
+
+    public void addBackref(int backRef) {
+        backNum++;
+
+        switch (backNum) {
+            case 1:
+                backRef1 = backRef;
+                break;
+            case 2:
+                alloc();
+                backRefs[0] = backRef1;
+                backRefs[1] = backRef;
+                break;
+            default:
+                ensureSize();
+                backRefs[backNum - 1] = backRef;
+        }
+    }
+
+    public String toString() {
+        StringBuilder buff = new StringBuilder(new String(name, nameP, nameEnd - nameP) + " ");
+        if (backNum == 0) {
+            buff.append("-");
+        } else if (backNum == 1){
+            buff.append(backRef1);
+        } else {
+            for (int i=0; i<backNum; i++){
+                if (i > 0) buff.append(", ");
+                buff.append(backRefs[i]);
+            }
+        }
+        return buff.toString();
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NativeMachine.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NativeMachine.java
new file mode 100644
index 0000000..2a3f2a1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NativeMachine.java
@@ -0,0 +1,27 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public abstract class NativeMachine extends Matcher {
+
+    protected NativeMachine(Regex regex, char[] chars, int p, int end) {
+        super(regex, chars, p, end);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NodeOptInfo.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NodeOptInfo.java
new file mode 100644
index 0000000..76b1d5f
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NodeOptInfo.java
@@ -0,0 +1,125 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public final class NodeOptInfo {
+    final MinMaxLen length = new  MinMaxLen();
+    final OptAnchorInfo anchor = new OptAnchorInfo();
+    final OptExactInfo exb = new OptExactInfo();            /* boundary */
+    final OptExactInfo exm = new OptExactInfo();            /* middle */
+    final OptExactInfo expr = new OptExactInfo();           /* prec read (?=...) */
+    final OptMapInfo map = new OptMapInfo();                /* boundary */
+
+    public void setBoundNode(MinMaxLen mmd) {
+        exb.mmd.copy(mmd);
+        expr.mmd.copy(mmd);
+        map.mmd.copy(mmd);
+    }
+
+    public void clear() {
+        length.clear();
+        anchor.clear();
+        exb.clear();
+        exm.clear();
+        expr.clear();
+        map.clear();
+    }
+
+    public void copy(NodeOptInfo other) {
+        length.copy(other.length);
+        anchor.copy(other.anchor);
+        exb.copy(other.exb);
+        exm.copy(other.exm);
+        expr.copy(other.expr);
+        map.copy(other.map);
+    }
+
+    public void concatLeftNode(NodeOptInfo other) {
+        OptAnchorInfo tanchor = new OptAnchorInfo(); // remove it somehow ?
+        tanchor.concat(anchor, other.anchor, length.max, other.length.max);
+        anchor.copy(tanchor);
+
+        if (other.exb.length > 0 && length.max == 0) {
+            tanchor.concat(anchor, other.exb.anchor, length.max, other.length.max);
+            other.exb.anchor.copy(tanchor);
+        }
+
+        if (other.map.value > 0 && length.max == 0) {
+            if (other.map.mmd.max == 0) {
+                other.map.anchor.leftAnchor |= anchor.leftAnchor;
+            }
+        }
+
+        boolean exbReach = exb.reachEnd;
+        boolean exmReach = exm.reachEnd;
+
+        if (other.length.max != 0) {
+            exb.reachEnd = exm.reachEnd = false;
+        }
+
+        if (other.exb.length > 0) {
+            if (exbReach) {
+                exb.concat(other.exb);
+                other.exb.clear();
+            } else if (exmReach) {
+                exm.concat(other.exb);
+                other.exb.clear();
+            }
+        }
+
+        exm.select(other.exb);
+        exm.select(other.exm);
+
+        if (expr.length > 0) {
+            if (other.length.max > 0) {
+                // TODO: make sure it is not an Oniguruma bug (casting unsigned int to int for arithmetic comparison)
+                int otherLengthMax = other.length.max;
+                if (otherLengthMax == MinMaxLen.INFINITE_DISTANCE) otherLengthMax = -1;
+                if (expr.length > otherLengthMax) expr.length = otherLengthMax;
+                if (expr.mmd.max == 0) {
+                    exb.select(expr);
+                } else {
+                    exm.select(expr);
+                }
+            }
+        } else if (other.expr.length > 0) {
+            expr.copy(other.expr);
+        }
+
+        map.select(other.map);
+        length.add(other.length);
+    }
+
+    public void altMerge(NodeOptInfo other, OptEnvironment env) {
+        anchor.altMerge(other.anchor);
+        exb.altMerge(other.exb, env);
+        exm.altMerge(other.exm, env);
+        expr.altMerge(other.expr, env);
+        map.altMerge(other.map);
+        length.altMerge(other.length);
+    }
+
+    public void setBound(MinMaxLen mmd) {
+        exb.mmd.copy(mmd);
+        expr.mmd.copy(mmd);
+        map.mmd.copy(mmd);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptAnchorInfo.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptAnchorInfo.java
new file mode 100644
index 0000000..4ed24e0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptAnchorInfo.java
@@ -0,0 +1,92 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+
+final class OptAnchorInfo implements AnchorType {
+    int leftAnchor;
+    int rightAnchor;
+
+    void clear() {
+        leftAnchor = rightAnchor = 0;
+    }
+
+    void copy(OptAnchorInfo other) {
+        leftAnchor = other.leftAnchor;
+        rightAnchor = other.rightAnchor;
+    }
+
+    void concat(OptAnchorInfo left, OptAnchorInfo right, int leftLength, int rightLength) {
+        leftAnchor = left.leftAnchor;
+        if (leftLength == 0) leftAnchor |= right.leftAnchor;
+
+        rightAnchor = right.rightAnchor;
+        if (rightLength == 0) rightAnchor |= left.rightAnchor;
+    }
+
+    boolean isSet(int anchor) {
+        if ((leftAnchor & anchor) != 0) return true;
+        return (rightAnchor & anchor) != 0;
+    }
+
+    void add(int anchor) {
+        if (isLeftAnchor(anchor)) {
+            leftAnchor |= anchor;
+        } else {
+            rightAnchor |= anchor;
+        }
+    }
+
+    void remove(int anchor) {
+        if (isLeftAnchor(anchor)) {
+            leftAnchor &= ~anchor;
+        } else {
+            rightAnchor &= ~anchor;
+        }
+    }
+
+    void altMerge(OptAnchorInfo other) {
+        leftAnchor &= other.leftAnchor;
+        rightAnchor &= other.rightAnchor;
+    }
+
+    static boolean isLeftAnchor(int anchor) { // make a mask for it ?
+        return !(anchor == END_BUF || anchor == SEMI_END_BUF ||
+                 anchor == END_LINE || anchor == PREC_READ ||
+                 anchor == PREC_READ_NOT);
+    }
+
+    static String anchorToString(int anchor) {
+        StringBuffer s = new StringBuffer("[");
+
+        if ((anchor & AnchorType.BEGIN_BUF) !=0 ) s.append("begin-buf ");
+        if ((anchor & AnchorType.BEGIN_LINE) !=0 ) s.append("begin-line ");
+        if ((anchor & AnchorType.BEGIN_POSITION) !=0 ) s.append("begin-pos ");
+        if ((anchor & AnchorType.END_BUF) !=0 ) s.append("end-buf ");
+        if ((anchor & AnchorType.SEMI_END_BUF) !=0 ) s.append("semi-end-buf ");
+        if ((anchor & AnchorType.END_LINE) !=0 ) s.append("end-line ");
+        if ((anchor & AnchorType.ANYCHAR_STAR) !=0 ) s.append("anychar-star ");
+        if ((anchor & AnchorType.ANYCHAR_STAR_ML) !=0 ) s.append("anychar-star-pl ");
+        s.append("]");
+
+        return s.toString();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptEnvironment.java
new file mode 100644
index 0000000..8c75e03
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptEnvironment.java
@@ -0,0 +1,35 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+// remove this one in future and pass mmd directly
+final class OptEnvironment {
+    final MinMaxLen mmd = new MinMaxLen();
+    int options;
+    int caseFoldFlag;
+    ScanEnvironment scanEnv;
+
+    void copy(OptEnvironment other) {
+        mmd.copy(other.mmd);
+        options = other.options;
+        caseFoldFlag = other.caseFoldFlag;
+        scanEnv = other.scanEnv;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptExactInfo.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptExactInfo.java
new file mode 100644
index 0000000..f7992a3
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptExactInfo.java
@@ -0,0 +1,153 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+final class OptExactInfo {
+    static final int OPT_EXACT_MAXLEN = 24;
+
+    final MinMaxLen mmd = new MinMaxLen();
+    final OptAnchorInfo anchor = new OptAnchorInfo();
+
+    boolean reachEnd;
+    boolean ignoreCase;
+
+    final char chars[] = new char[OPT_EXACT_MAXLEN];
+    int length;
+
+    boolean isFull() {
+        return length >= OPT_EXACT_MAXLEN;
+    }
+
+    void clear() {
+        mmd.clear();
+        anchor.clear();
+
+        reachEnd = false;
+        ignoreCase = false;
+        length = 0;
+    }
+
+    void copy(OptExactInfo other) {
+        mmd.copy(other.mmd);
+        anchor.copy(other.anchor);
+        reachEnd = other.reachEnd;
+        ignoreCase = other.ignoreCase;
+        length = other.length;
+
+        System.arraycopy(other.chars, 0, chars, 0, OPT_EXACT_MAXLEN);
+    }
+
+    void concat(OptExactInfo other) {
+        if (!ignoreCase && other.ignoreCase) {
+            if (length >= other.length) return; /* avoid */
+            ignoreCase = true;
+        }
+
+        int p = 0; // add->s;
+        int end = p + other.length;
+
+        int i;
+        for (i = length; p < end;) {
+            if (i + 1 > OPT_EXACT_MAXLEN) break;
+            chars[i++] = other.chars[p++];
+        }
+
+        length = i;
+        reachEnd = (p == end ? other.reachEnd : false);
+
+        OptAnchorInfo tmp = new OptAnchorInfo();
+        tmp.concat(anchor, other.anchor, 1, 1);
+        if (!other.reachEnd) tmp.rightAnchor = 0;
+        anchor.copy(tmp);
+    }
+
+    // ?? raw is not used here
+    void concatStr(char[] lchars, int p, int end, boolean raw) {
+        int i;
+        for (i = length; p < end && i < OPT_EXACT_MAXLEN;) {
+            if (i + 1 > OPT_EXACT_MAXLEN) break;
+            chars[i++] = lchars[p++];
+        }
+
+        length = i;
+    }
+
+    void altMerge(OptExactInfo other, OptEnvironment env) {
+        if (other.length == 0 || length == 0) {
+            clear();
+            return;
+        }
+
+        if (!mmd.equal(other.mmd)) {
+            clear();
+            return;
+        }
+
+        int i;
+        for (i = 0; i < length && i < other.length; i++) {
+            if (chars[i] != other.chars[i]) break;
+        }
+
+        if (!other.reachEnd || i<other.length || i<length) reachEnd = false;
+
+        length = i;
+        ignoreCase |= other.ignoreCase;
+
+        anchor.altMerge(other.anchor);
+
+        if (!reachEnd) anchor.rightAnchor = 0;
+    }
+
+
+    void select(OptExactInfo alt) {
+        int v1 = length;
+        int v2 = alt.length;
+
+        if (v2 == 0) {
+            return;
+        } else if (v1 == 0) {
+            copy(alt);
+            return;
+        } else if (v1 <= 2 && v2 <= 2) {
+            /* ByteValTable[x] is big value --> low price */
+            v2 = OptMapInfo.positionValue(chars[0] & 0xff);
+            v1 = OptMapInfo.positionValue(alt.chars[0] & 0xff);
+
+            if (length > 1) v1 += 5;
+            if (alt.length > 1) v2 += 5;
+        }
+
+        if (!ignoreCase) v1 *= 2;
+        if (!alt.ignoreCase) v2 *= 2;
+
+        if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) copy(alt);
+    }
+
+    // comp_opt_exact_or_map_info
+    private static final int COMP_EM_BASE   = 20;
+    int compare(OptMapInfo m) {
+        if (m.value <= 0) return -1;
+
+        int ve = COMP_EM_BASE * length * (ignoreCase ? 1 : 2);
+        int vm = COMP_EM_BASE * 5 * 2 / m.value;
+
+        return mmd.compareDistanceValue(m.mmd, ve, vm);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptMapInfo.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptMapInfo.java
new file mode 100644
index 0000000..9cf6a50
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptMapInfo.java
@@ -0,0 +1,120 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+final class OptMapInfo {
+
+    final MinMaxLen mmd = new MinMaxLen();          /* info position */
+    final OptAnchorInfo anchor = new OptAnchorInfo();
+
+    int value;                                      /* weighted value */
+    final byte map[] = new byte[Config.CHAR_TABLE_SIZE];
+
+    void clear() {
+        mmd.clear();
+        anchor.clear();
+        value = 0;
+        for (int i=0; i<map.length; i++) map[i] = 0;
+    }
+
+    void copy(OptMapInfo other) {
+        mmd.copy(other.mmd);
+        anchor.copy(other.anchor);
+        value = other.value;
+        //for(int i=0; i<map.length; i++) map[i] = other.map[i];
+        System.arraycopy(other.map, 0, map, 0, other.map.length);
+    }
+
+    void addChar(int c) {
+        int c_ = c & 0xff;
+        if (map[c_] == 0) {
+            map[c_] = 1;
+            value += positionValue(c_);
+        }
+    }
+
+    void addCharAmb(char[] chars, int p, int end, int caseFoldFlag) {
+        addChar(chars[p]);
+
+        caseFoldFlag &= ~Config.INTERNAL_ENC_CASE_FOLD_MULTI_CHAR;
+        char[]items = EncodingHelper.caseFoldCodesByString(caseFoldFlag, chars[p]);
+
+        for (int i=0; i<items.length; i++) {
+            addChar(items[i]);
+        }
+    }
+
+    // select_opt_map_info
+    private static final int z = 1<<15; /* 32768: something big value */
+    void select(OptMapInfo alt) {
+        if (alt.value == 0) return;
+        if (value == 0) {
+            copy(alt);
+            return;
+        }
+
+        int v1 = z / value;
+        int v2 = z /alt.value;
+
+        if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) copy(alt);
+    }
+
+    // alt_merge_opt_map_info
+    void altMerge(OptMapInfo other) {
+        /* if (! is_equal_mml(&to->mmd, &add->mmd)) return ; */
+        if (value == 0) return;
+        if (other.value == 0 || mmd.max < other.mmd.max) {
+            clear();
+            return;
+        }
+
+        mmd.altMerge(other.mmd);
+
+        int val = 0;
+        for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
+            if (other.map[i] != 0) map[i] = 1;
+            if (map[i] != 0) val += positionValue(i);
+        }
+
+        value = val;
+        anchor.altMerge(other.anchor);
+    }
+
+    static final short ByteValTable[] = {
+        5,  1,  1,  1,  1,  1,  1,  1,  1, 10, 10,  1,  1, 10,  1,  1,
+        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+       12,  4,  7,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5,  5,  5,
+        6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  5,  5,
+        5,  6,  6,  6,  6,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+        6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  6,  5,  5,  5,
+        5,  6,  6,  6,  6,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+        6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  1
+     };
+
+    // map_position_value
+    static int positionValue(int i) {
+        if (i < ByteValTable.length) {
+            return ByteValTable[i];
+        } else {
+            return 4; /* Take it easy. */
+        }
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Option.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Option.java
new file mode 100644
index 0000000..26f3e56
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Option.java
@@ -0,0 +1,122 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public class Option {
+
+    /* options */
+    public static final int NONE                 = 0;
+    public static final int IGNORECASE           = (1<<0);
+    public static final int EXTEND               = (1<<1);
+    public static final int MULTILINE            = (1<<2);
+    public static final int SINGLELINE           = (1<<3);
+    public static final int FIND_LONGEST         = (1<<4);
+    public static final int FIND_NOT_EMPTY       = (1<<5);
+    public static final int NEGATE_SINGLELINE    = (1<<6);
+    public static final int DONT_CAPTURE_GROUP   = (1<<7);
+    public static final int CAPTURE_GROUP        = (1<<8);
+
+    /* options (search time) */
+    public static final int NOTBOL               = (1<<9);
+    public static final int NOTEOL               = (1<<10);
+    public static final int POSIX_REGION         = (1<<11);
+    public static final int MAXBIT               = (1<<12); /* limit */
+
+    public static final int DEFAULT              = NONE;
+
+    public static String toString(int option) {
+        String options = "";
+        if (isIgnoreCase(option)) options += "IGNORECASE ";
+        if (isExtend(option)) options += "EXTEND ";
+        if (isMultiline(option)) options += "MULTILINE ";
+        if (isSingleline(option)) options += "SINGLELINE ";
+        if (isFindLongest(option)) options += "FIND_LONGEST ";
+        if (isFindNotEmpty(option)) options += "FIND_NOT_EMPTY  ";
+        if (isNegateSingleline(option)) options += "NEGATE_SINGLELINE ";
+        if (isDontCaptureGroup(option)) options += "DONT_CAPTURE_GROUP ";
+        if (isCaptureGroup(option)) options += "CAPTURE_GROUP ";
+
+        if (isNotBol(option)) options += "NOTBOL ";
+        if (isNotEol(option)) options += "NOTEOL ";
+        if (isPosixRegion(option)) options += "POSIX_REGION ";
+
+        return options;
+    }
+
+    public static boolean isIgnoreCase(int option) {
+        return (option & IGNORECASE) != 0;
+    }
+
+    public static boolean isExtend(int option) {
+        return (option & EXTEND) != 0;
+    }
+
+    public static boolean isSingleline(int option) {
+        return (option & SINGLELINE) != 0;
+    }
+
+    public static boolean isMultiline(int option) {
+        return (option & MULTILINE) != 0;
+    }
+
+    public static boolean isFindLongest(int option) {
+        return (option & FIND_LONGEST) != 0;
+    }
+
+    public static boolean isFindNotEmpty(int option) {
+        return (option & FIND_NOT_EMPTY) != 0;
+    }
+
+    public static boolean isFindCondition(int option) {
+        return (option & (FIND_LONGEST | FIND_NOT_EMPTY)) != 0;
+    }
+
+    public static boolean isNegateSingleline(int option) {
+        return (option & NEGATE_SINGLELINE) != 0;
+    }
+
+    public static boolean isDontCaptureGroup(int option) {
+        return (option & DONT_CAPTURE_GROUP) != 0;
+    }
+
+    public static boolean isCaptureGroup(int option) {
+        return (option & CAPTURE_GROUP) != 0;
+    }
+
+    public static boolean isNotBol(int option) {
+        return (option & NOTBOL) != 0;
+    }
+
+    public static boolean isNotEol(int option) {
+        return (option & NOTEOL) != 0;
+    }
+
+    public static boolean isPosixRegion(int option) {
+        return (option & POSIX_REGION) != 0;
+    }
+
+    /* OP_SET_OPTION is required for these options.  ??? */
+    //    public static boolean isDynamic(int option) {
+    //        return (option & (MULTILINE | IGNORECASE)) != 0;
+    //    }
+    public static boolean isDynamic(int option) {
+        return false;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java
new file mode 100644
index 0000000..1b5a586
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java
@@ -0,0 +1,953 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAtSimple;
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnOff;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
+
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.PosixBracket;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.AnyCharNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode.CCStateArg;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.CCSTATE;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.CCVALTYPE;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.TokenType;
+
+class Parser extends Lexer {
+
+    protected final Regex regex;
+    protected Node root;
+
+    protected int returnCode; // return code used by parser methods (they itself return parsed nodes)
+                              // this approach will not affect recursive calls
+
+    protected Parser(ScanEnvironment env, char[] chars, int p, int end) {
+        super(env, chars, p, end);
+        regex = env.reg;
+    }
+
+    // onig_parse_make_tree
+    protected final Node parse() {
+        root = parseRegexp();
+        regex.numMem = env.numMem;
+        return root;
+    }
+
+    private static final int POSIX_BRACKET_NAME_MIN_LEN            = 4;
+    private static final int POSIX_BRACKET_CHECK_LIMIT_LENGTH      = 20;
+    private static final char BRACKET_END[]                        = ":]".toCharArray();
+    private boolean parsePosixBracket(CClassNode cc) {
+        mark();
+
+        boolean not;
+        if (peekIs('^')) {
+            inc();
+            not = true;
+        } else {
+            not = false;
+        }
+        if (stop - p >= POSIX_BRACKET_NAME_MIN_LEN + 3) { // else goto not_posix_bracket
+            char[][] pbs = PosixBracket.PBSNamesLower;
+            for (int i=0; i<pbs.length; i++) {
+                char[] name = pbs[i];
+                // hash lookup here ?
+                if (EncodingHelper.strNCmp(chars, p, stop, name, 0, name.length) == 0) {
+                    p += name.length;
+                    if (EncodingHelper.strNCmp(chars, p, stop, BRACKET_END, 0, BRACKET_END.length) != 0) {
+                        newSyntaxException(ERR_INVALID_POSIX_BRACKET_TYPE);
+                    }
+                    cc.addCType(PosixBracket.PBSValues[i], not, env, this);
+                    inc();
+                    inc();
+                    return false;
+                }
+            }
+
+        }
+
+        // not_posix_bracket:
+        c = 0;
+        int i= 0;
+        while (left() && ((c=peek()) != ':') && c != ']') {
+            inc();
+            if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
+        }
+
+        if (c == ':' && left()) {
+            inc();
+            if (left()) {
+                fetch();
+                if (c == ']') newSyntaxException(ERR_INVALID_POSIX_BRACKET_TYPE);
+            }
+        }
+        restore();
+        return true; /* 1: is not POSIX bracket, but no error. */
+    }
+
+    private CClassNode parseCharProperty() {
+        int ctype = fetchCharPropertyToCType();
+        CClassNode n = new CClassNode();
+        n.addCType(ctype, false, env, this);
+        if (token.getPropNot()) n.setNot();
+        return n;
+    }
+
+    private boolean codeExistCheck(int code, boolean ignoreEscaped) {
+        mark();
+
+        boolean inEsc = false;
+        while (left()) {
+            if (ignoreEscaped && inEsc) {
+                inEsc = false;
+            } else {
+                fetch();
+                if (c == code) {
+                    restore();
+                    return true;
+                }
+                if (c == syntax.metaCharTable.esc) inEsc = true;
+            }
+        }
+
+        restore();
+        return false;
+    }
+
+    private CClassNode parseCharClass() {
+        fetchTokenInCC();
+
+        final boolean neg;
+        if (token.type == TokenType.CHAR && token.getC() == '^' && !token.escaped) {
+            neg = true;
+            fetchTokenInCC();
+        } else {
+            neg = false;
+        }
+
+        if (token.type == TokenType.CC_CLOSE) {
+            if (!codeExistCheck(']', true)) newSyntaxException(ERR_EMPTY_CHAR_CLASS);
+            env.ccEscWarn("]");
+            token.type = TokenType.CHAR; /* allow []...] */
+        }
+
+        CClassNode cc = new CClassNode();
+        CClassNode prevCC = null;
+        CClassNode workCC = null;
+
+        CCStateArg arg = new CCStateArg();
+
+        boolean andStart = false;
+        arg.state = CCSTATE.START;
+
+        while (token.type != TokenType.CC_CLOSE) {
+            boolean fetched = false;
+
+            switch (token.type) {
+
+            case CHAR:
+                if (token.getC() > 0xff) {
+                    arg.inType = CCVALTYPE.CODE_POINT;
+                } else {
+                    arg.inType = CCVALTYPE.SB; // sb_char:
+                }
+                arg.v = token.getC();
+                arg.vIsRaw = false;
+                parseCharClassValEntry2(cc, arg); // goto val_entry2
+                break;
+
+            case RAW_BYTE:
+                if (token.base != 0) { /* tok->base != 0 : octal or hexadec. */
+                    byte[] buf = new byte[4];
+                    int psave = p;
+                    int base = token.base;
+                    buf[0] = (byte)token.getC();
+                    int i;
+                    for (i=1; i<4; i++) {
+                        fetchTokenInCC();
+                        if (token.type != TokenType.RAW_BYTE || token.base != base) {
+                            fetched = true;
+                            break;
+                        }
+                        buf[i] = (byte)token.getC();
+                    }
+
+                    if (i == 1) {
+                        arg.v = buf[0] & 0xff;
+                        arg.inType = CCVALTYPE.SB; // goto raw_single
+                    } else {
+                        arg.v = EncodingHelper.mbcToCode(buf, 0, buf.length);
+                        arg.inType = CCVALTYPE.CODE_POINT;
+                    }
+                } else {
+                    arg.v = token.getC();
+                    arg.inType = CCVALTYPE.SB; // raw_single:
+                }
+                arg.vIsRaw = true;
+                parseCharClassValEntry2(cc, arg); // goto val_entry2
+                break;
+
+            case CODE_POINT:
+                arg.v = token.getCode();
+                arg.vIsRaw = true;
+                parseCharClassValEntry(cc, arg); // val_entry:, val_entry2
+                break;
+
+            case POSIX_BRACKET_OPEN:
+                if (parsePosixBracket(cc)) { /* true: is not POSIX bracket */
+                    env.ccEscWarn("[");
+                    p = token.backP;
+                    arg.v = token.getC();
+                    arg.vIsRaw = false;
+                    parseCharClassValEntry(cc, arg); // goto val_entry
+                    break;
+                }
+                cc.nextStateClass(arg, env); // goto next_class
+                break;
+
+            case CHAR_TYPE:
+                cc.addCType(token.getPropCType(), token.getPropNot(), env, this);
+                cc.nextStateClass(arg, env); // next_class:
+                break;
+
+            case CHAR_PROPERTY:
+                int ctype = fetchCharPropertyToCType();
+                cc.addCType(ctype, token.getPropNot(), env, this);
+                cc.nextStateClass(arg, env); // goto next_class
+                break;
+
+            case CC_RANGE:
+                if (arg.state == CCSTATE.VALUE) {
+                    fetchTokenInCC();
+                    fetched = true;
+                    if (token.type == TokenType.CC_CLOSE) { /* allow [x-] */
+                        parseCharClassRangeEndVal(cc, arg); // range_end_val:, goto val_entry;
+                        break;
+                    } else if (token.type == TokenType.CC_AND) {
+                        env.ccEscWarn("-");
+                        parseCharClassRangeEndVal(cc, arg); // goto range_end_val
+                        break;
+                    }
+                    arg.state = CCSTATE.RANGE;
+                } else if (arg.state == CCSTATE.START) {
+                    arg.v = token.getC(); /* [-xa] is allowed */
+                    arg.vIsRaw = false;
+                    fetchTokenInCC();
+                    fetched = true;
+                    if (token.type == TokenType.CC_RANGE || andStart) env.ccEscWarn("-"); /* [--x] or [a&&-x] is warned. */
+                    parseCharClassValEntry(cc, arg); // goto val_entry
+                    break;
+                } else if (arg.state == CCSTATE.RANGE) {
+                    env.ccEscWarn("-");
+                    parseCharClassSbChar(cc, arg); // goto sb_char /* [!--x] is allowed */
+                    break;
+                } else { /* CCS_COMPLETE */
+                    fetchTokenInCC();
+                    fetched = true;
+                    if (token.type == TokenType.CC_CLOSE) { /* allow [a-b-] */
+                        parseCharClassRangeEndVal(cc, arg); // goto range_end_val
+                        break;
+                    } else if (token.type == TokenType.CC_AND) {
+                        env.ccEscWarn("-");
+                        parseCharClassRangeEndVal(cc, arg); // goto range_end_val
+                        break;
+                    }
+
+                    if (syntax.allowDoubleRangeOpInCC()) {
+                        env.ccEscWarn("-");
+                        parseCharClassSbChar(cc, arg); // goto sb_char /* [0-9-a] is allowed as [0-9\-a] */
+                        break;
+                    }
+                    newSyntaxException(ERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS);
+                }
+                break;
+
+            case CC_CC_OPEN: /* [ */
+                CClassNode acc = parseCharClass();
+                cc.or(acc);
+                break;
+
+            case CC_AND:     /* && */
+                if (arg.state == CCSTATE.VALUE) {
+                    arg.v = 0; // ??? safe v ?
+                    arg.vIsRaw = false;
+                    cc.nextStateValue(arg, env);
+                }
+                /* initialize local variables */
+                andStart = true;
+                arg.state = CCSTATE.START;
+                if (prevCC != null) {
+                    prevCC.and(cc);
+                } else {
+                    prevCC = cc;
+                    if (workCC == null) workCC = new CClassNode();
+                    cc = workCC;
+                }
+                cc.clear();
+                break;
+
+            case EOT:
+                newSyntaxException(ERR_PREMATURE_END_OF_CHAR_CLASS);
+
+            default:
+                newInternalException(ERR_PARSER_BUG);
+            } // switch
+
+            if (!fetched) fetchTokenInCC();
+
+        } // while
+
+        if (arg.state == CCSTATE.VALUE) {
+            arg.v = 0; // ??? safe v ?
+            arg.vIsRaw = false;
+            cc.nextStateValue(arg, env);
+        }
+
+        if (prevCC != null) {
+            prevCC.and(cc);
+            cc = prevCC;
+        }
+
+        if (neg) {
+            cc.setNot();
+        } else {
+            cc.clearNot();
+        }
+
+        if (cc.isNot() && syntax.notNewlineInNegativeCC()) {
+            if (!cc.isEmpty()) {
+                final int NEW_LINE = 0x0a;
+                if (EncodingHelper.isNewLine(NEW_LINE)) {
+                    cc.bs.set(NEW_LINE);
+                }
+            }
+        }
+
+        return cc;
+    }
+
+    private void parseCharClassSbChar(CClassNode cc, CCStateArg arg) {
+        arg.inType = CCVALTYPE.SB;
+        arg.v = token.getC();
+        arg.vIsRaw = false;
+        parseCharClassValEntry2(cc, arg); // goto val_entry2
+    }
+
+    private void parseCharClassRangeEndVal(CClassNode cc, CCStateArg arg) {
+        arg.v = '-';
+        arg.vIsRaw = false;
+        parseCharClassValEntry(cc, arg); // goto val_entry
+    }
+
+    private void parseCharClassValEntry(CClassNode cc, CCStateArg arg) {
+        arg.inType = arg.v <= 0xff ? CCVALTYPE.SB : CCVALTYPE.CODE_POINT;
+        parseCharClassValEntry2(cc, arg); // val_entry2:
+    }
+
+    private void parseCharClassValEntry2(CClassNode cc, CCStateArg arg) {
+        cc.nextStateValue(arg, env);
+    }
+
+    private Node parseEnclose(TokenType term) {
+        Node node = null;
+
+        if (!left()) newSyntaxException(ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS);
+
+        int option = env.option;
+
+        if (peekIs('?') && syntax.op2QMarkGroupEffect()) {
+            inc();
+            if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
+
+            boolean listCapture = false;
+
+            fetch();
+            switch(c) {
+            case ':':  /* (?:...) grouping only */
+                fetchToken(); // group:
+                node = parseSubExp(term);
+                returnCode = 1; /* group */
+                return node;
+            case '=':
+                node = new AnchorNode(AnchorType.PREC_READ);
+                break;
+            case '!':  /*         preceding read */
+                node = new AnchorNode(AnchorType.PREC_READ_NOT);
+                break;
+            case '>':  /* (?>...) stop backtrack */
+                node = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
+                break;
+            case '\'':
+                if (Config.USE_NAMED_GROUP) {
+                    if (syntax.op2QMarkLtNamedGroup()) {
+                        listCapture = false; // goto named_group1
+                        node = parseEncloseNamedGroup2(listCapture);
+                        break;
+                    } else {
+                        newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
+                    }
+                } // USE_NAMED_GROUP
+                break;
+            case '<':  /* look behind (?<=...), (?<!...) */
+                fetch();
+                if (c == '=') {
+                    node = new AnchorNode(AnchorType.LOOK_BEHIND);
+                } else if (c == '!') {
+                    node = new AnchorNode(AnchorType.LOOK_BEHIND_NOT);
+                } else {
+                    if (Config.USE_NAMED_GROUP) {
+                        if (syntax.op2QMarkLtNamedGroup()) {
+                            unfetch();
+                            c = '<';
+
+                            listCapture = false; // named_group1:
+                            node = parseEncloseNamedGroup2(listCapture); // named_group2:
+                            break;
+                        } else {
+                            newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
+                        }
+
+                    } else { // USE_NAMED_GROUP
+                        newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
+                    } // USE_NAMED_GROUP
+                }
+                break;
+            case '@':
+                if (syntax.op2AtMarkCaptureHistory()) {
+                    if (Config.USE_NAMED_GROUP) {
+                        if (syntax.op2QMarkLtNamedGroup()) {
+                            fetch();
+                            if (c == '<' || c == '\'') {
+                                listCapture = true;
+                                node = parseEncloseNamedGroup2(listCapture); // goto named_group2 /* (?@<name>...) */
+                            }
+                            unfetch();
+                        }
+                    } // USE_NAMED_GROUP
+                    EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
+                    int num = env.addMemEntry();
+                    if (num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
+                    en.regNum = num;
+                    node = en;
+                } else {
+                    newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
+                }
+                break;
+
+            // case 'p': #ifdef USE_POSIXLINE_OPTION
+            case '-':
+            case 'i':
+            case 'm':
+            case 's':
+            case 'x':
+                boolean neg = false;
+                while (true) {
+                    switch(c) {
+                    case ':':
+                    case ')':
+                        break;
+                    case '-':
+                        neg = true;
+                        break;
+                    case 'x':
+                        option = bsOnOff(option, Option.EXTEND, neg);
+                        break;
+                    case 'i':
+                        option = bsOnOff(option, Option.IGNORECASE, neg);
+                        break;
+                    case 's':
+                        if (syntax.op2OptionPerl()) {
+                            option = bsOnOff(option, Option.MULTILINE, neg);
+                        } else {
+                            newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
+                        }
+                        break;
+                    case 'm':
+                        if (syntax.op2OptionPerl()) {
+                            option = bsOnOff(option, Option.SINGLELINE, !neg);
+                        } else if (syntax.op2OptionRuby()) {
+                            option = bsOnOff(option, Option.MULTILINE, neg);
+                        } else {
+                            newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
+                        }
+                        break;
+                    // case 'p': #ifdef USE_POSIXLINE_OPTION // not defined
+                    // option = bsOnOff(option, Option.MULTILINE|Option.SINGLELINE, neg);
+                    // break;
+
+                    default:
+                        newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
+                    } // switch
+
+                    if (c == ')') {
+                        EncloseNode en = new EncloseNode(option, 0); // node_new_option
+                        node = en;
+                        returnCode = 2; /* option only */
+                        return node;
+                    } else if (c == ':') {
+                        int prev = env.option;
+                        env.option = option;
+                        fetchToken();
+                        Node target = parseSubExp(term);
+                        env.option = prev;
+                        EncloseNode en = new EncloseNode(option, 0); // node_new_option
+                        en.setTarget(target);
+                        node = en;
+                        returnCode = 0;
+                        return node;
+                    }
+                    if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
+                    fetch();
+                } // while
+
+            default:
+                newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
+            } // switch
+
+        } else {
+            if (isDontCaptureGroup(env.option)) {
+                fetchToken(); // goto group
+                node = parseSubExp(term);
+                returnCode = 1; /* group */
+                return node;
+            }
+            EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
+            int num = env.addMemEntry();
+            en.regNum = num;
+            node = en;
+        }
+
+        fetchToken();
+        Node target = parseSubExp(term);
+
+        if (node.getType() == NodeType.ANCHOR) {
+            AnchorNode an = (AnchorNode) node;
+            an.setTarget(target);
+        } else {
+            EncloseNode en = (EncloseNode)node;
+            en.setTarget(target);
+            if (en.type == EncloseType.MEMORY) {
+                /* Don't move this to previous of parse_subexp() */
+                env.setMemNode(en.regNum, node);
+            }
+        }
+        returnCode = 0;
+        return node; // ??
+    }
+
+    private Node parseEncloseNamedGroup2(boolean listCapture) {
+        int nm = p;
+        int num = fetchName(c, false);
+        int nameEnd = value;
+        num = env.addMemEntry();
+        if (listCapture && num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
+
+        regex.nameAdd(chars, nm, nameEnd, num, syntax);
+        EncloseNode en = new EncloseNode(env.option, true); // node_new_enclose_memory
+        en.regNum = num;
+
+        Node node = en;
+
+        if (listCapture) env.captureHistory = bsOnAtSimple(env.captureHistory, num);
+        env.numNamed++;
+        return node;
+    }
+
+    private int findStrPosition(int[]s, int n, int from, int to, Ptr nextChar) {
+        int x;
+        int q;
+        int p = from;
+        int i = 0;
+        while (p < to) {
+            x = chars[p];
+            q = p + 1;
+            if (x == s[0]) {
+                for (i=1; i<n && q<to; i++) {
+                    x = chars[q];
+                    if (x != s[i]) break;
+                    q++;
+                }
+                if (i >= n) {
+                    if (chars[nextChar.p] != 0) nextChar.p = q; // we may need zero term semantics...
+                    return p;
+                }
+            }
+            p = q;
+        }
+        return -1;
+    }
+
+    private Node parseExp(TokenType term) {
+        if (token.type == term) return StringNode.EMPTY; // goto end_of_token
+
+        Node node = null;
+        boolean group = false;
+
+        switch(token.type) {
+        case ALT:
+        case EOT:
+            return StringNode.EMPTY; // end_of_token:, node_new_empty
+
+        case SUBEXP_OPEN:
+            node = parseEnclose(TokenType.SUBEXP_CLOSE);
+            if (returnCode == 1) {
+                group = true;
+            } else if (returnCode == 2) { /* option only */
+                int prev = env.option;
+                EncloseNode en = (EncloseNode)node;
+                env.option = en.option;
+                fetchToken();
+                Node target = parseSubExp(term);
+                env.option = prev;
+                en.setTarget(target);
+                return node;
+            }
+            break;
+        case SUBEXP_CLOSE:
+            if (!syntax.allowUnmatchedCloseSubexp()) newSyntaxException(ERR_UNMATCHED_CLOSE_PARENTHESIS);
+            if (token.escaped) {
+                return parseExpTkRawByte(group); // goto tk_raw_byte
+            } else {
+                return parseExpTkByte(group); // goto tk_byte
+            }
+        case STRING:
+            return parseExpTkByte(group); // tk_byte:
+
+        case RAW_BYTE:
+            return parseExpTkRawByte(group); // tk_raw_byte:
+        case CODE_POINT:
+            char[] buf = new char[] {(char)token.getCode()};
+            // #ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG ... // setRaw() #else
+            node = new StringNode(buf, 0, 1);
+            break;
+
+        case QUOTE_OPEN:
+            int[] endOp = new int[] {syntax.metaCharTable.esc, 'E'};
+            int qstart = p;
+            Ptr nextChar = new Ptr();
+            int qend = findStrPosition(endOp, endOp.length, qstart, stop, nextChar);
+            if (qend == -1) nextChar.p = qend = stop;
+            node = new StringNode(chars, qstart, qend);
+            p = nextChar.p;
+            break;
+
+        case CHAR_TYPE:
+            switch(token.getPropCType()) {
+            case CharacterType.D:
+            case CharacterType.S:
+            case CharacterType.W:
+                if (Config.NON_UNICODE_SDW) {
+                    CClassNode cc = new CClassNode();
+                    cc.addCType(token.getPropCType(), false, env, this);
+                    if (token.getPropNot()) cc.setNot();
+                    node = cc;
+                }
+                break;
+
+            case CharacterType.WORD:
+                node = new CTypeNode(token.getPropCType(), token.getPropNot());
+                break;
+
+            case CharacterType.SPACE:
+            case CharacterType.DIGIT:
+            case CharacterType.XDIGIT:
+                // #ifdef USE_SHARED_CCLASS_TABLE ... #endif
+                CClassNode ccn = new CClassNode();
+                ccn.addCType(token.getPropCType(), false, env, this);
+                if (token.getPropNot()) ccn.setNot();
+                node = ccn;
+                break;
+
+            default:
+                newInternalException(ERR_PARSER_BUG);
+
+            } // inner switch
+            break;
+
+        case CHAR_PROPERTY:
+            node = parseCharProperty();
+            break;
+
+        case CC_CC_OPEN:
+            CClassNode cc = parseCharClass();
+            node = cc;
+            if (isIgnoreCase(env.option)) {
+                ApplyCaseFoldArg arg = new ApplyCaseFoldArg(env, cc);
+                EncodingHelper.applyAllCaseFold(env.caseFoldFlag, ApplyCaseFold.INSTANCE, arg);
+
+                if (arg.altRoot != null) {
+                    node = ConsAltNode.newAltNode(node, arg.altRoot);
+                }
+            }
+            break;
+
+        case ANYCHAR:
+            node = new AnyCharNode();
+            break;
+
+        case ANYCHAR_ANYTIME:
+            node = new AnyCharNode();
+            QuantifierNode qn = new QuantifierNode(0, QuantifierNode.REPEAT_INFINITE, false);
+            qn.setTarget(node);
+            node = qn;
+            break;
+
+        case BACKREF:
+            int[]backRefs = token.getBackrefNum() > 1 ? token.getBackrefRefs() : new int[]{token.getBackrefRef1()};
+            node = new BackRefNode(token.getBackrefNum(),
+                            backRefs,
+                            token.getBackrefByName(),
+                            token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL
+                            token.getBackrefLevel(),      // ...
+                            env);
+
+            break;
+
+        case CALL:
+            if (Config.USE_SUBEXP_CALL) {
+                int gNum = token.getCallGNum();
+
+                if (gNum < 0) {
+                    gNum = backrefRelToAbs(gNum);
+                    if (gNum <= 0) newValueException(ERR_INVALID_BACKREF);
+                }
+                node = new CallNode(chars, token.getCallNameP(), token.getCallNameEnd(), gNum);
+                env.numCall++;
+            } // USE_SUBEXP_CALL
+            break;
+
+        case ANCHOR:
+            node = new AnchorNode(token.getAnchor()); // possible bug in oniguruma
+            break;
+
+        case OP_REPEAT:
+        case INTERVAL:
+            if (syntax.contextIndepRepeatOps()) {
+                if (syntax.contextInvalidRepeatOps()) {
+                    newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED);
+                } else {
+                    node = StringNode.EMPTY; // node_new_empty
+                }
+            } else {
+                return parseExpTkByte(group); // goto tk_byte
+            }
+            break;
+
+        default:
+            newInternalException(ERR_PARSER_BUG);
+        } //switch
+
+        //targetp = node;
+
+        fetchToken(); // re_entry:
+
+        return parseExpRepeat(node, group); // repeat:
+    }
+
+    private Node parseExpTkByte(boolean group) {
+        StringNode node = new StringNode(chars, token.backP, p); // tk_byte:
+        while (true) {
+            fetchToken();
+            if (token.type != TokenType.STRING) break;
+
+            if (token.backP == node.end) {
+                node.end = p; // non escaped character, remain shared, just increase shared range
+            } else {
+                node.cat(chars, token.backP, p); // non continuous string stream, need to COW
+            }
+        }
+        // targetp = node;
+        return parseExpRepeat(node, group); // string_end:, goto repeat
+    }
+
+    private Node parseExpTkRawByte(boolean group) {
+        // tk_raw_byte:
+
+        // important: we don't use 0xff mask here neither in the compiler
+        // (in the template string) so we won't have to mask target
+        // strings when comparing against them in the matcher
+        StringNode node = new StringNode((char)token.getC());
+        node.setRaw();
+
+        int len = 1;
+        while (true) {
+            if (len >= 1) {
+                if (len == 1) {
+                    fetchToken();
+                    node.clearRaw();
+                    // !goto string_end;!
+                    return parseExpRepeat(node, group);
+                }
+            }
+
+            fetchToken();
+            if (token.type != TokenType.RAW_BYTE) {
+                /* Don't use this, it is wrong for little endian encodings. */
+                // USE_PAD_TO_SHORT_BYTE_CHAR ...
+
+                newValueException(ERR_TOO_SHORT_MULTI_BYTE_STRING);
+            }
+
+            // important: we don't use 0xff mask here neither in the compiler
+            // (in the template string) so we won't have to mask target
+            // strings when comparing against them in the matcher
+            node.cat((char)token.getC());
+            len++;
+        } // while
+    }
+
+    private Node parseExpRepeat(Node target, boolean group) {
+        while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat:
+            if (target.isInvalidQuantifier()) newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID);
+
+            QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
+                                                     token.getRepeatUpper(),
+                                                     token.type == TokenType.INTERVAL);
+
+            qtfr.greedy = token.getRepeatGreedy();
+            int ret = qtfr.setQuantifier(target, group, env, chars, getBegin(), getEnd());
+            Node qn = qtfr;
+
+            if (token.getRepeatPossessive()) {
+                EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
+                en.setTarget(qn);
+                qn = en;
+            }
+
+            if (ret == 0) {
+                target = qn;
+            } else if (ret == 2) { /* split case: /abc+/ */
+                target = ConsAltNode.newListNode(target, null);
+                ConsAltNode tmp = ((ConsAltNode)target).setCdr(ConsAltNode.newListNode(qn, null));
+
+                fetchToken();
+                return parseExpRepeatForCar(target, tmp, group);
+            }
+            fetchToken(); // goto re_entry
+        }
+        return target;
+    }
+
+    private Node parseExpRepeatForCar(Node top, ConsAltNode target, boolean group) {
+        while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat:
+            if (target.car.isInvalidQuantifier()) newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID);
+
+            QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
+                                                     token.getRepeatUpper(),
+                                                     token.type == TokenType.INTERVAL);
+
+            qtfr.greedy = token.getRepeatGreedy();
+            int ret = qtfr.setQuantifier(target.car, group, env, chars, getBegin(), getEnd());
+            Node qn = qtfr;
+
+            if (token.getRepeatPossessive()) {
+                EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
+                en.setTarget(qn);
+                qn = en;
+            }
+
+            if (ret == 0) {
+                target.setCar(qn);
+            } else if (ret == 2) { /* split case: /abc+/ */
+                assert false;
+            }
+            fetchToken(); // goto re_entry
+        }
+        return top;
+    }
+
+    private Node parseBranch(TokenType term) {
+        Node node = parseExp(term);
+
+        if (token.type == TokenType.EOT || token.type == term || token.type == TokenType.ALT) {
+            return node;
+        } else {
+            ConsAltNode top = ConsAltNode.newListNode(node, null);
+            ConsAltNode t = top;
+
+            while (token.type != TokenType.EOT && token.type != term && token.type != TokenType.ALT) {
+                node = parseExp(term);
+                if (node.getType() == NodeType.LIST) {
+                    t.setCdr((ConsAltNode)node);
+                    while (((ConsAltNode)node).cdr != null ) node = ((ConsAltNode)node).cdr;
+
+                    t = ((ConsAltNode)node);
+                } else {
+                    t.setCdr(ConsAltNode.newListNode(node, null));
+                    t = t.cdr;
+                }
+            }
+            return top;
+        }
+    }
+
+    /* term_tok: TK_EOT or TK_SUBEXP_CLOSE */
+    private Node parseSubExp(TokenType term) {
+        Node node = parseBranch(term);
+
+        if (token.type == term) {
+            return node;
+        } else if (token.type == TokenType.ALT) {
+            ConsAltNode top = ConsAltNode.newAltNode(node, null);
+            ConsAltNode t = top;
+            while (token.type == TokenType.ALT) {
+                fetchToken();
+                node = parseBranch(term);
+
+                t.setCdr(ConsAltNode.newAltNode(node, null));
+                t = t.cdr;
+            }
+
+            if (token.type != term) parseSubExpError(term);
+            return top;
+        } else {
+            parseSubExpError(term);
+            return null; //not reached
+        }
+    }
+
+    private void parseSubExpError(TokenType term) {
+        if (term == TokenType.SUBEXP_CLOSE) {
+            newSyntaxException(ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS);
+        } else {
+            newInternalException(ERR_PARSER_BUG);
+        }
+    }
+
+    private Node parseRegexp() {
+        fetchToken();
+        return parseSubExp(TokenType.EOT);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java
new file mode 100644
index 0000000..ae98cb5
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java
@@ -0,0 +1,413 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isCaptureGroup;
+import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
+
+public final class Regex implements RegexState {
+
+    int[] code;             /* compiled pattern */
+    int codeLength;
+    boolean stackNeeded;
+    Object[]operands;       /* e.g. shared CClassNode */
+    int operandLength;
+
+    int state;              /* normal, searching, compiling */ // remove
+    int numMem;             /* used memory(...) num counted from 1 */
+    int numRepeat;          /* OP_REPEAT/OP_REPEAT_NG id-counter */
+    int numNullCheck;       /* OP_NULL_CHECK_START/END id counter */
+    int numCombExpCheck;    /* combination explosion check */
+    int numCall;            /* number of subexp call */
+    int captureHistory;     /* (?@...) flag (1-31) */
+    int btMemStart;         /* need backtrack flag */
+    int btMemEnd;           /* need backtrack flag */
+
+    int stackPopLevel;
+
+    int[]repeatRangeLo;
+    int[]repeatRangeHi;
+
+    public WarnCallback warnings;
+    public MatcherFactory factory;
+
+    int options;
+    int userOptions;
+    Object userObject;
+    //final Syntax syntax;
+    final int caseFoldFlag;
+
+    HashMap<String,NameEntry> nameTable;        // named entries
+
+    /* optimization info (string search, char-map and anchors) */
+    SearchAlgorithm searchAlgorithm;        /* optimize flag */
+    int thresholdLength;                    /* search str-length for apply optimize */
+    int anchor;                             /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */
+    int anchorDmin;                         /* (SEMI_)END_BUF anchor distance */
+    int anchorDmax;                         /* (SEMI_)END_BUF anchor distance */
+    int subAnchor;                          /* start-anchor for exact or map */
+
+    char[] exact;
+    int exactP;
+    int exactEnd;
+
+    byte[] map;                              /* used as BM skip or char-map */
+    int[] intMap;                            /* BM skip for exact_len > 255 */
+    int[] intMapBackward;                    /* BM skip for backward search */
+    int dMin;                               /* min-distance of exact or map */
+    int dMax;                               /* max-distance of exact or map */
+
+    char[][] templates;
+    int templateNum;
+
+    public Regex(CharSequence cs) {
+        this(cs.toString());
+    }
+
+    public Regex(String str) {
+        this(str.toCharArray(), 0, str.length(), 0);
+    }
+
+    public Regex(char[] chars) {
+        this(chars, 0, chars.length, 0);
+    }
+
+    public Regex(char[] chars, int p, int end) {
+        this(chars, p, end, 0);
+    }
+
+    public Regex(char[] chars, int p, int end, int option) {
+        this(chars, p, end, option, Syntax.RUBY, WarnCallback.DEFAULT);
+    }
+
+    // onig_new
+    public Regex(char[] chars, int p, int end, int option, Syntax syntax) {
+        this(chars, p, end, option, Config.ENC_CASE_FOLD_DEFAULT, syntax, WarnCallback.DEFAULT);
+    }
+
+    public Regex(char[]chars, int p, int end, int option, WarnCallback warnings) {
+        this(chars, p, end, option, Syntax.RUBY, warnings);
+    }
+
+    // onig_new
+    public Regex(char[] chars, int p, int end, int option, Syntax syntax, WarnCallback warnings) {
+        this(chars, p, end, option, Config.ENC_CASE_FOLD_DEFAULT, syntax, warnings);
+    }
+
+    // onig_alloc_init
+    public Regex(char[] chars, int p, int end, int option, int caseFoldFlag, Syntax syntax, WarnCallback warnings) {
+
+        if ((option & (Option.DONT_CAPTURE_GROUP | Option.CAPTURE_GROUP)) ==
+            (Option.DONT_CAPTURE_GROUP | Option.CAPTURE_GROUP)) {
+            throw new ValueException(ErrorMessages.ERR_INVALID_COMBINATION_OF_OPTIONS);
+        }
+
+        if ((option & Option.NEGATE_SINGLELINE) != 0) {
+            option |= syntax.options;
+            option &= ~Option.SINGLELINE;
+        } else {
+            option |= syntax.options;
+        }
+
+        this.options = option;
+        this.caseFoldFlag = caseFoldFlag;
+        this.warnings = warnings;
+
+        new Analyser(new ScanEnvironment(this, syntax), chars, p, end).compile();
+
+        this.warnings = null;
+    }
+
+    public Matcher matcher(char[] chars) {
+        return matcher(chars, 0, chars.length);
+    }
+
+    public Matcher matcher(char[] chars, int p, int end) {
+        return factory.create(this, chars, p, end);
+    }
+
+    public int numberOfCaptures() {
+        return numMem;
+    }
+
+    public int numberOfCaptureHistories() {
+        if (Config.USE_CAPTURE_HISTORY) {
+            int n = 0;
+            for (int i=0; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
+                if (bsAt(captureHistory, i)) n++;
+            }
+            return n;
+        } else {
+            return 0;
+        }
+    }
+
+    String nameTableToString() {
+        StringBuilder sb = new StringBuilder();
+
+        if (nameTable != null) {
+            sb.append("name table\n");
+            for (NameEntry ne : nameTable.values()) {
+                sb.append("  " + ne + "\n");
+            }
+            sb.append("\n");
+        }
+        return sb.toString();
+    }
+
+    NameEntry nameFind(char[] name, int nameP, int nameEnd) {
+        if (nameTable != null) return nameTable.get(new String(name, nameP, nameEnd - nameP));
+        return null;
+    }
+
+    void renumberNameTable(int[]map) {
+        if (nameTable != null) {
+            for (NameEntry e : nameTable.values()) {
+                if (e.backNum > 1) {
+                    for (int i=0; i<e.backNum; i++) {
+                        e.backRefs[i] = map[e.backRefs[i]];
+                    }
+                } else if (e.backNum == 1) {
+                    e.backRef1 = map[e.backRef1];
+                }
+            }
+        }
+    }
+
+    public int numberOfNames() {
+        return nameTable == null ? 0 : nameTable.size();
+    }
+
+    void nameAdd(char[] name, int nameP, int nameEnd, int backRef, Syntax syntax) {
+        if (nameEnd - nameP <= 0) throw new ValueException(ErrorMessages.ERR_EMPTY_GROUP_NAME);
+
+        NameEntry e = null;
+        if (nameTable == null) {
+            nameTable = new HashMap<String,NameEntry>(); // 13, oni defaults to 5
+        } else {
+            e = nameFind(name, nameP, nameEnd);
+        }
+
+        if (e == null) {
+            // dup the name here as oni does ?, what for ? (it has to manage it, we don't)
+            e = new NameEntry(name, nameP, nameEnd);
+            nameTable.put(new String(name, nameP, nameEnd - nameP), e);
+        } else if (e.backNum >= 1 && !syntax.allowMultiplexDefinitionName()) {
+            throw new ValueException(ErrorMessages.ERR_MULTIPLEX_DEFINED_NAME, new String(name, nameP, nameEnd - nameP));
+        }
+
+        e.addBackref(backRef);
+    }
+
+    NameEntry nameToGroupNumbers(char[] name, int nameP, int nameEnd) {
+        return nameFind(name, nameP, nameEnd);
+    }
+
+    public int nameToBackrefNumber(char[] name, int nameP, int nameEnd, Region region) {
+        NameEntry e = nameToGroupNumbers(name, nameP, nameEnd);
+        if (e == null) throw new ValueException(ErrorMessages.ERR_UNDEFINED_NAME_REFERENCE,
+                                                new String(name, nameP, nameEnd - nameP));
+
+        switch(e.backNum) {
+        case 0:
+            throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
+        case 1:
+            return e.backRef1;
+        default:
+            if (region != null) {
+                for (int i = e.backNum - 1; i >= 0; i--) {
+                    if (region.beg[e.backRefs[i]] != Region.REGION_NOTPOS) return e.backRefs[i];
+                }
+            }
+            return e.backRefs[e.backNum - 1];
+        }
+    }
+
+    public Iterator<NameEntry> namedBackrefIterator() {
+        return nameTable.values().iterator();
+    }
+
+    public boolean noNameGroupIsActive(Syntax syntax) {
+        if (isDontCaptureGroup(options)) return false;
+
+        if (Config.USE_NAMED_GROUP) {
+            if (numberOfNames() > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(options)) return false;
+        }
+        return true;
+    }
+
+    /* set skip map for Boyer-Moor search */
+    void setupBMSkipMap() {
+        char[] chars = exact;
+        int p = exactP;
+        int end = exactEnd;
+        int len = end - p;
+
+        if (len < Config.CHAR_TABLE_SIZE) {
+            // map/skip
+            if (map == null) map = new byte[Config.CHAR_TABLE_SIZE];
+
+            for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) map[i] = (byte)len;
+            for (int i=0; i<len-1; i++) map[chars[p + i] & 0xff] = (byte)(len - 1 -i); // oxff ??
+        } else {
+            if (intMap == null) intMap = new int[Config.CHAR_TABLE_SIZE];
+
+            for (int i=0; i<len-1; i++) intMap[chars[p + i] & 0xff] = len - 1 - i; // oxff ??
+        }
+    }
+
+    void setExactInfo(OptExactInfo e) {
+        if (e.length == 0) return;
+
+        // shall we copy that ?
+        exact = e.chars;
+        exactP = 0;
+        exactEnd = e.length;
+
+        if (e.ignoreCase) {
+            searchAlgorithm = new SearchAlgorithm.SLOW_IC(this);
+        } else {
+            if (e.length >= 2) {
+                setupBMSkipMap();
+                searchAlgorithm = SearchAlgorithm.BM;
+            } else {
+                searchAlgorithm = SearchAlgorithm.SLOW;
+            }
+        }
+
+        dMin = e.mmd.min;
+        dMax = e.mmd.max;
+
+        if (dMin != MinMaxLen.INFINITE_DISTANCE) {
+            thresholdLength = dMin + (exactEnd - exactP);
+        }
+    }
+
+    void setOptimizeMapInfo(OptMapInfo m) {
+        map = m.map;
+
+        searchAlgorithm = SearchAlgorithm.MAP;
+        dMin = m.mmd.min;
+        dMax = m.mmd.max;
+
+        if (dMin != MinMaxLen.INFINITE_DISTANCE) {
+            thresholdLength = dMin + 1;
+        }
+    }
+
+    void setSubAnchor(OptAnchorInfo anc) {
+        subAnchor |= anc.leftAnchor & AnchorType.BEGIN_LINE;
+        subAnchor |= anc.rightAnchor & AnchorType.END_LINE;
+    }
+
+    void clearOptimizeInfo() {
+        searchAlgorithm = SearchAlgorithm.NONE;
+        anchor = 0;
+        anchorDmax = 0;
+        anchorDmin = 0;
+        subAnchor = 0;
+
+        exact = null;
+        exactP = exactEnd = 0;
+    }
+
+    public String encStringToString(byte[]bytes, int p, int end) {
+        StringBuilder sb = new StringBuilder("\nPATTERN: /");
+
+        while (p < end) {
+            sb.append(new String(new byte[]{bytes[p]}));
+            p++;
+        }
+        return sb.append("/").toString();
+    }
+
+    public String optimizeInfoToString() {
+        String s = "";
+        s += "optimize: " + searchAlgorithm.getName() + "\n";
+        s += "  anchor:     " + OptAnchorInfo.anchorToString(anchor);
+
+        if ((anchor & AnchorType.END_BUF_MASK) != 0) {
+            s += MinMaxLen.distanceRangeToString(anchorDmin, anchorDmax);
+        }
+
+        s += "\n";
+
+        if (searchAlgorithm != SearchAlgorithm.NONE) {
+            s += "  sub anchor: " + OptAnchorInfo.anchorToString(subAnchor) + "\n";
+        }
+
+        s += "dmin: " + dMin + " dmax: " + dMax + "\n";
+        s += "threshold length: " + thresholdLength + "\n";
+
+        if (exact != null) {
+            s += "exact: [" + new String(exact, exactP, exactEnd - exactP) + "]: length: " + (exactEnd - exactP) + "\n";
+        } else if (searchAlgorithm == SearchAlgorithm.MAP) {
+            int n=0;
+            for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) if (map[i] != 0) n++;
+
+            s += "map: n = " + n + "\n";
+            if (n > 0) {
+                int c=0;
+                s += "[";
+                for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
+                    if (map[i] != 0) {
+                        if (c > 0) s += ", ";
+                        c++;
+                        // TODO if (enc.isPrint(i)
+                        s += ((char)i);
+                    }
+                }
+                s += "]\n";
+            }
+        }
+
+        return s;
+    }
+
+    public int getOptions() {
+        return options;
+    }
+
+    public void setUserOptions(int options) {
+        this.userOptions = options;
+    }
+
+    public int getUserOptions() {
+        return userOptions;
+    }
+
+    public void setUserObject(Object object) {
+        this.userObject = object;
+    }
+
+    public Object getUserObject() {
+        return userObject;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java
new file mode 100644
index 0000000..d685a24
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java
@@ -0,0 +1,66 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public final class Region {
+    static final int REGION_NOTPOS = -1;
+
+    public final int numRegs;
+    public final int[]beg;
+    public final int[]end;
+    public CaptureTreeNode historyRoot;
+
+    public Region(int num) {
+        this.numRegs = num;
+        this.beg = new int[num];
+        this.end = new int[num];
+    }
+
+    public Region(int begin, int end) {
+        this.numRegs = 1;
+        this.beg = new int[]{begin};
+        this.end = new int[]{end};
+    }
+
+    public Region clone() {
+        Region region = new Region(numRegs);
+        System.arraycopy(beg, 0, region.beg, 0, beg.length);
+        System.arraycopy(end, 0, region.end, 0, end.length);
+        if (historyRoot != null) region.historyRoot = historyRoot.cloneTree();
+        return region;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Region: \n");
+        for (int i=0; i<beg.length; i++) sb.append(" " + i + ": (" + beg[i] + "-" + end[i] + ")");
+        return sb.toString();
+    }
+
+    CaptureTreeNode getCaptureTree() {
+        return historyRoot;
+    }
+
+    void clear() {
+        for (int i=0; i<beg.length; i++) {
+            beg[i] = end[i] = REGION_NOTPOS;
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java
new file mode 100644
index 0000000..a604bfa
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java
@@ -0,0 +1,137 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsClear;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+
+public final class ScanEnvironment {
+
+    private static final int SCANENV_MEMNODES_SIZE = 8;
+
+    int option;
+    final int caseFoldFlag;
+    final public Syntax syntax;
+    int captureHistory;
+    int btMemStart;
+    int btMemEnd;
+    int backrefedMem;
+
+    final public Regex reg;
+
+    int numCall;
+    UnsetAddrList unsetAddrList; // USE_SUBEXP_CALL
+    public int numMem;
+
+    int numNamed; // USE_NAMED_GROUP
+
+    public Node memNodes[];
+
+    // USE_COMBINATION_EXPLOSION_CHECK
+    int numCombExpCheck;
+    int combExpMaxRegNum;
+    int currMaxRegNum;
+    boolean hasRecursion;
+
+    public ScanEnvironment(Regex regex, Syntax syntax) {
+        this.reg = regex;
+        option = regex.options;
+        caseFoldFlag = regex.caseFoldFlag;
+        this.syntax = syntax;
+    }
+
+    public void clear() {
+        captureHistory = bsClear();
+        btMemStart = bsClear();
+        btMemEnd = bsClear();
+        backrefedMem = bsClear();
+
+        numCall = 0;
+        numMem = 0;
+
+        numNamed = 0;
+
+        memNodes = null;
+
+        numCombExpCheck = 0;
+        combExpMaxRegNum = 0;
+        currMaxRegNum = 0;
+        hasRecursion = false;
+    }
+
+    public int addMemEntry() {
+        if (numMem++ == 0) {
+            memNodes = new Node[SCANENV_MEMNODES_SIZE];
+        } else if (numMem >= memNodes.length) {
+            Node[]tmp = new Node[memNodes.length << 1];
+            System.arraycopy(memNodes, 0, tmp, 0, memNodes.length);
+            memNodes = tmp;
+        }
+
+        return numMem;
+    }
+
+    public void setMemNode(int num, Node node) {
+        if (numMem >= num) {
+            memNodes[num] = node;
+        } else {
+            throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
+        }
+    }
+
+    public int convertBackslashValue(int c) {
+        if (syntax.opEscControlChars()) {
+            switch (c) {
+            case 'n': return '\n';
+            case 't': return '\t';
+            case 'r': return '\r';
+            case 'f': return '\f';
+            case 'a': return '\007';
+            case 'b': return '\010';
+            case 'e': return '\033';
+            case 'v':
+                if (syntax.op2EscVVtab()) return 11; // ???
+                break;
+            default:
+                break;
+            }
+        }
+        return c;
+    }
+
+    void ccEscWarn(String s) {
+        if (Config.USE_WARN) {
+            if (syntax.warnCCOpNotEscaped() && syntax.backSlashEscapeInCC()) {
+                reg.warnings.warn("character class has '" + s + "' without escape");
+            }
+        }
+    }
+
+    void closeBracketWithoutEscapeWarn(String s) {
+        if (Config.USE_WARN) {
+            if (syntax.warnCCOpNotEscaped()) {
+                reg.warnings.warn("regular expression has '" + s + "' without escape");
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScannerSupport.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScannerSupport.java
new file mode 100644
index 0000000..f3d8165
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScannerSupport.java
@@ -0,0 +1,178 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
+
+abstract class ScannerSupport extends IntHolder implements ErrorMessages {
+
+    protected final char[] chars;       // pattern
+    protected int p;                    // current scanner position
+    protected int stop;                 // pattern end (mutable)
+    private int lastFetched;            // last fetched value for unfetch support
+    protected int c;                    // current code point
+
+    private final int begin;            // pattern begin position for reset() support
+    private final int end;              // pattern end position for reset() support
+    protected int _p;                   // used by mark()/restore() to mark positions
+
+    protected ScannerSupport(char[] chars, int p, int end) {
+        this.chars = chars;
+        this.begin = p;
+        this.end = end;
+
+        reset();
+    }
+
+    protected int getBegin() {
+        return begin;
+    }
+
+    protected int getEnd() {
+        return end;
+    }
+
+    private final int INT_SIGN_BIT = 1 << 31;
+
+    protected final int scanUnsignedNumber() {
+        int last = c;
+        int num = 0; // long ???
+        while(left()) {
+            fetch();
+            if (Character.isDigit(c)) {
+                int onum = num;
+                num = num * 10 + EncodingHelper.digitVal(c);
+                if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
+            } else {
+                unfetch();
+                break;
+            }
+        }
+        c = last;
+        return num;
+    }
+
+    protected final int scanUnsignedHexadecimalNumber(int maxLength) {
+        int last = c;
+        int num = 0;
+        while(left() && maxLength-- != 0) {
+            fetch();
+            if (EncodingHelper.isXDigit(c)) {
+                int onum = num;
+                int val = EncodingHelper.xdigitVal(c);
+                num = (num << 4) + val;
+                if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
+            } else {
+                unfetch();
+                break;
+            }
+        }
+        c = last;
+        return num;
+    }
+
+    protected final int scanUnsignedOctalNumber(int maxLength) {
+        int last = c;
+        int num = 0;
+        while(left() && maxLength-- != 0) {
+            fetch();
+            if (Character.isDigit(c) && c < '8') {
+                int onum = num;
+                int val = EncodingHelper.odigitVal(c);
+                num = (num << 3) + val;
+                if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
+            } else {
+                unfetch();
+                break;
+            }
+        }
+        c = last;
+        return num;
+    }
+
+    protected final void reset() {
+        p = begin;
+        stop = end;
+    }
+
+    protected final void mark() {
+        _p = p;
+    }
+
+    protected final void restore() {
+        p = _p;
+    }
+
+    protected final void inc() {
+        lastFetched = p;
+        p++;
+    }
+
+    protected final void fetch() {
+        lastFetched = p;
+        c = chars[p++];
+    }
+
+    protected int fetchTo() {
+        lastFetched = p;
+        return chars[p++];
+    }
+
+    protected final void unfetch() {
+        p = lastFetched;
+    }
+
+    protected final int peek() {
+        return p < stop ? chars[p] : 0;
+    }
+
+    protected final boolean peekIs(int c) {
+        return peek() == c;
+    }
+
+    protected final boolean left() {
+        return p < stop;
+    }
+
+    protected void newSyntaxException(String message) {
+        throw new SyntaxException(message);
+    }
+
+    protected void newValueException(String message) {
+        throw new ValueException(message);
+    }
+
+    protected void newValueException(String message, String str) {
+        throw new ValueException(message, str);
+    }
+
+    protected void newValueException(String message, int p, int end) {
+        throw new ValueException(message, new String(chars, p, end - p));
+    }
+
+    protected void newInternalException(String message) {
+        throw new InternalException(message);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java
new file mode 100644
index 0000000..3b5a547
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java
@@ -0,0 +1,294 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public abstract class SearchAlgorithm {
+
+    public abstract String getName();
+    public abstract int search(Regex regex, char[] text, int textP, int textEnd, int textRange);
+    public abstract int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_);
+
+
+    public static final SearchAlgorithm NONE = new SearchAlgorithm() {
+
+        public final String getName() {
+            return "NONE";
+        }
+
+        public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
+            return textP;
+        }
+
+        public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
+            return textP;
+        }
+
+    };
+
+    public static final SearchAlgorithm SLOW = new SearchAlgorithm() {
+
+        public final String getName() {
+            return "EXACT";
+        }
+
+        public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
+            char[] target = regex.exact;
+            int targetP = regex.exactP;
+            int targetEnd = regex.exactEnd;
+
+
+            int end = textEnd;
+            end -= targetEnd - targetP - 1;
+
+            if (end > textRange) end = textRange;
+
+            int s = textP;
+
+            while (s < end) {
+                if (text[s] == target[targetP]) {
+                    int p = s + 1;
+                    int t = targetP + 1;
+                    while (t < targetEnd) {
+                        if (target[t] != text[p++]) break;
+                        t++;
+                    }
+
+                    if (t == targetEnd) return s;
+                }
+                s++;
+            }
+
+            return -1;
+        }
+
+        public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
+            char[] target = regex.exact;
+            int targetP = regex.exactP;
+            int targetEnd = regex.exactEnd;
+
+            int s = textEnd;
+            s -= targetEnd - targetP;
+
+            if (s > textStart) {
+                s = textStart;
+            }
+
+            while (s >= textP) {
+                if (text[s] == target[targetP]) {
+                    int p = s + 1;
+                    int t = targetP + 1;
+                    while (t < targetEnd) {
+                        if (target[t] != text[p++]) break;
+                        t++;
+                    }
+                    if (t == targetEnd) return s;
+                }
+                // s = enc.prevCharHead or s = s <= adjustText ? -1 : s - 1;
+                s--;
+            }
+            return -1;
+        }
+    };
+
+    public static final class SLOW_IC extends SearchAlgorithm {
+        private final int caseFoldFlag;
+
+        public SLOW_IC(Regex regex) {
+            this.caseFoldFlag = regex.caseFoldFlag;
+        }
+
+        public final String getName() {
+            return "EXACT_IC";
+        }
+
+        public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
+            char[] target = regex.exact;
+            int targetP = regex.exactP;
+            int targetEnd = regex.exactEnd;
+
+            int end = textEnd;
+            end -= targetEnd - targetP - 1;
+
+            if (end > textRange) end = textRange;
+            int s = textP;
+
+            while (s < end) {
+                if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) return s;
+                s++;
+            }
+            return -1;
+        }
+
+        public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
+            char[] target = regex.exact;
+            int targetP = regex.exactP;
+            int targetEnd = regex.exactEnd;
+
+            int s = textEnd;
+            s -= targetEnd - targetP;
+
+            if (s > textStart) {
+                s = textStart;
+            }
+
+            while (s >= textP) {
+                if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) return s;
+                s = EncodingHelper.prevCharHead(adjustText, s);
+            }
+            return -1;
+        }
+
+        private boolean lowerCaseMatch(char[] t, int tP, int tEnd,
+                                       char[] chars, int p, int end) {
+
+            while (tP < tEnd) {
+                if (t[tP++] != Character.toLowerCase(chars[p++])) return false;
+            }
+            return true;
+        }
+    };
+
+    public static final SearchAlgorithm BM = new SearchAlgorithm() {
+
+        public final String getName() {
+            return "EXACT_BM";
+        }
+
+        public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
+            char[] target = regex.exact;
+            int targetP = regex.exactP;
+            int targetEnd = regex.exactEnd;
+
+            int end = textRange + (targetEnd - targetP) - 1;
+            if (end > textEnd) end = textEnd;
+
+            int tail = targetEnd - 1;
+            int s = textP + (targetEnd - targetP) - 1;
+
+            if (regex.intMap == null) {
+                while (s < end) {
+                    int p = s;
+                    int t = tail;
+
+                    while (text[p] == target[t]) {
+                        if (t == targetP) return p;
+                        p--; t--;
+                    }
+
+                    s += regex.map[text[s] & 0xff];
+                }
+            } else { /* see int_map[] */
+                while (s < end) {
+                    int p = s;
+                    int t = tail;
+
+                    while (text[p] == target[t]) {
+                        if (t == targetP) return p;
+                        p--; t--;
+                    }
+
+                    s += regex.intMap[text[s] & 0xff];
+                }
+            }
+            return -1;
+        }
+
+        private static final int BM_BACKWARD_SEARCH_LENGTH_THRESHOLD = 100;
+
+        public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
+            char[] target = regex.exact;
+            int targetP = regex.exactP;
+            int targetEnd = regex.exactEnd;
+
+            if (regex.intMapBackward == null) {
+                if (s_ - range_ < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD) {
+                    // goto exact_method;
+                    return SLOW.searchBackward(regex, text, textP, adjustText, textEnd, textStart, s_, range_);
+                }
+                setBmBackwardSkip(regex, target, targetP, targetEnd);
+            }
+
+            int s = textEnd - (targetEnd - targetP);
+
+            if (textStart < s) {
+                s = textStart;
+            }
+
+            while (s >= textP) {
+                int p = s;
+                int t = targetP;
+                while (t < targetEnd && text[p] == target[t]) {
+                    p++; t++;
+                }
+                if (t == targetEnd) return s;
+
+                s -= regex.intMapBackward[text[s] & 0xff];
+            }
+            return -1;
+        }
+
+
+        private void setBmBackwardSkip(Regex regex, char[] chars, int p, int end) {
+            int[] skip;
+            if (regex.intMapBackward == null) {
+                skip = new int[Config.CHAR_TABLE_SIZE];
+                regex.intMapBackward = skip;
+            } else {
+                skip = regex.intMapBackward;
+            }
+
+            int len = end - p;
+
+            for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) skip[i] = len;
+            for (int i=len-1; i>0; i--) skip[chars[i] & 0xff] = i;
+        }
+    };
+
+    public static final SearchAlgorithm MAP = new SearchAlgorithm() {
+
+        public final String getName() {
+            return "MAP";
+        }
+
+        public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
+            byte[] map = regex.map;
+            int s = textP;
+
+            while (s < textRange) {
+                if (text[s] > 0xff || map[text[s]] != 0) return s;
+                s++;
+            }
+            return -1;
+        }
+
+        public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
+            byte[] map = regex.map;
+            int s = textStart;
+
+            if (s >= textEnd) s = textEnd - 1;
+            while (s >= textP) {
+                if (text[s] > 0xff || map[text[s]] != 0) return s;
+                s--;
+            }
+            return -1;
+        }
+    };
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackEntry.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackEntry.java
new file mode 100644
index 0000000..9161336
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackEntry.java
@@ -0,0 +1,164 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+final class StackEntry {
+    int type;
+    private int E1, E2, E3, E4;
+
+    // first union member
+    /* byte code position */
+    void setStatePCode(int pcode) {
+        E1 = pcode;
+    }
+    int getStatePCode() {
+        return E1;
+    }
+    /* string position */
+    void setStatePStr(int pstr) {
+        E2 = pstr;
+    }
+    int getStatePStr() {
+        return E2;
+    }
+    /* previous char position of pstr */
+    void setStatePStrPrev(int pstrPrev) {
+        E3 = pstrPrev;
+    }
+    int getStatePStrPrev() {
+        return E3;
+    }
+
+    void setStateCheck(int check) {
+        E4 = check;
+    }
+    int getStateCheck() {
+        return E4;
+    }
+
+    // second union member
+    /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
+    void setRepeatCount(int count) {
+        E1 = count;
+    }
+    int getRepeatCount() {
+        return E1;
+    }
+    void decreaseRepeatCount() {
+        E1--;
+    }
+    void increaseRepeatCount() {
+        E1++;
+    }
+    /* byte code position (head of repeated target) */
+    void setRepeatPCode(int pcode) {
+        E2 = pcode;
+    }
+    int getRepeatPCode() {
+        return E2;
+    }
+    /* repeat id */
+    void setRepeatNum(int num) {
+        E3 = num;
+    }
+    int getRepeatNum() {
+        return E3;
+    }
+
+    // third union member
+    /* index of stack */ /*int repeat_inc struct*/
+    void setSi(int si) {
+        E1 = si;
+    }
+    int getSi() {
+        return E1;
+    }
+
+    // fourth union member
+    /* memory num */
+    void setMemNum(int num) {
+        E1 = num;
+    }
+    int getMemNum() {
+        return E1;
+    }
+    /* start/end position */
+    void setMemPstr(int pstr) {
+        E2 = pstr;
+    }
+    int getMemPStr() {
+        return E2;
+    }
+
+    /* Following information is set, if this stack type is MEM-START */
+    /* prev. info (for backtrack  "(...)*" ) */
+    void setMemStart(int start) {
+        E3 = start;
+    }
+    int getMemStart() {
+        return E3;
+    }
+    /* prev. info (for backtrack  "(...)*" ) */
+    void setMemEnd(int end) {
+        E4 = end;
+    }
+    int getMemEnd() {
+        return E4;
+    }
+
+    // fifth union member
+    /* null check id */
+    void setNullCheckNum(int num) {
+        E1 = num;
+    }
+    int getNullCheckNum() {
+        return E1;
+    }
+    /* start position */
+    void setNullCheckPStr(int pstr) {
+        E2 = pstr;
+    }
+    int getNullCheckPStr() {
+        return E2;
+    }
+
+    // sixth union member
+    /* byte code position */
+    void setCallFrameRetAddr(int addr) {
+        E1 = addr;
+    }
+    int getCallFrameRetAddr() {
+        return E1;
+    }
+    /* null check id */
+    void setCallFrameNum(int num) {
+        E2 = num;
+    }
+    int getCallFrameNum() {
+        return E2;
+    }
+    /* string position */
+    void setCallFramePStr(int pstr) {
+        E3 = pstr;
+    }
+    int getCallFramePStr() {
+        return E3;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackMachine.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackMachine.java
new file mode 100644
index 0000000..898a4f1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackMachine.java
@@ -0,0 +1,621 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
+
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+
+import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.StackType;
+
+abstract class StackMachine extends Matcher implements StackType {
+    protected static final int INVALID_INDEX = -1;
+
+    protected StackEntry[]stack;
+    protected int stk;  // stkEnd
+
+    protected final int[]repeatStk;
+    protected final int memStartStk, memEndStk;
+
+    // CEC
+    protected byte[] stateCheckBuff; // move to int[] ?
+    int stateCheckBuffSize;
+
+    protected StackMachine(Regex regex, char[] chars, int p , int end) {
+        super(regex, chars, p, end);
+
+        this.stack = regex.stackNeeded ? fetchStack() : null;
+        int n = regex.numRepeat + (regex.numMem << 1);
+        this.repeatStk = n > 0 ? new int[n] : null;
+
+        memStartStk = regex.numRepeat - 1;
+        memEndStk   = memStartStk + regex.numMem;
+        /* for index start from 1, mem_start_stk[1]..mem_start_stk[num_mem] */
+        /* for index start from 1, mem_end_stk[1]..mem_end_stk[num_mem] */
+    }
+
+    private static StackEntry[] allocateStack() {
+        StackEntry[]stack = new StackEntry[Config.INIT_MATCH_STACK_SIZE];
+        stack[0] = new StackEntry();
+        return stack;
+    }
+
+    private void doubleStack() {
+        StackEntry[] newStack = new StackEntry[stack.length << 1];
+        System.arraycopy(stack, 0, newStack, 0, stack.length);
+        stack = newStack;
+    }
+
+    static final ThreadLocal<WeakReference<StackEntry[]>> stacks
+            = new ThreadLocal<WeakReference<StackEntry[]>>() {
+        @Override
+        protected WeakReference<StackEntry[]> initialValue() {
+            return new WeakReference<StackEntry[]>(allocateStack());
+        }
+    };
+
+    private static StackEntry[] fetchStack() {
+        WeakReference<StackEntry[]> ref = stacks.get();
+        StackEntry[] stack = ref.get();
+        if (stack == null) {
+            ref = new WeakReference<StackEntry[]>(stack = allocateStack());
+            stacks.set(ref);
+        }
+        return stack;
+    }
+
+    protected final void init() {
+        if (stack != null) pushEnsured(ALT, regex.codeLength - 1); /* bottom stack */
+        if (repeatStk != null) {
+            for (int i=1; i<=regex.numMem; i++) {
+                repeatStk[i + memStartStk] = repeatStk[i + memEndStk] = INVALID_INDEX;
+            }
+        }
+    }
+
+    protected final StackEntry ensure1() {
+        if (stk >= stack.length) doubleStack();
+        StackEntry e = stack[stk];
+        if (e == null) stack[stk] = e = new StackEntry();
+        return e;
+    }
+
+    protected final void pushType(int type) {
+        ensure1().type = type;
+        stk++;
+    }
+
+    // CEC
+
+    // STATE_CHECK_POS
+    private int stateCheckPos(int s, int snum) {
+        return (s - str) * regex.numCombExpCheck + (snum - 1);
+    }
+
+    // STATE_CHECK_VAL
+    protected final boolean stateCheckVal(int s, int snum) {
+        if (stateCheckBuff != null) {
+            int x = stateCheckPos(s, snum);
+            return (stateCheckBuff[x / 8] & (1 << (x % 8))) != 0;
+        }
+        return false;
+    }
+
+    // ELSE_IF_STATE_CHECK_MARK
+    private void stateCheckMark() {
+        StackEntry e = stack[stk];
+        int x = stateCheckPos(e.getStatePStr(), e.getStateCheck());
+        stateCheckBuff[x / 8] |= (1 << (x % 8));
+    }
+
+    // STATE_CHECK_BUFF_INIT
+    private static final int STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE = 16;
+    protected final void stateCheckBuffInit(int strLength, int offset, int stateNum) {
+        if (stateNum > 0 && strLength >= Config.CHECK_STRING_THRESHOLD_LEN) {
+            int size = ((strLength + 1) * stateNum + 7) >>> 3;
+            offset = (offset * stateNum) >>> 3;
+
+            if (size > 0 && offset < size && size < Config.CHECK_BUFF_MAX_SIZE) {
+                if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {
+                    stateCheckBuff = new byte[size];
+                } else {
+                    // same impl, reduce...
+                    stateCheckBuff = new byte[size];
+                }
+                Arrays.fill(stateCheckBuff, offset, (size - offset), (byte)0);
+                stateCheckBuffSize = size;
+            } else {
+                stateCheckBuff = null; // reduce
+                stateCheckBuffSize = 0;
+            }
+        } else {
+            stateCheckBuff = null; // reduce
+            stateCheckBuffSize = 0;
+        }
+    }
+
+    protected final void stateCheckBuffClear() {
+        stateCheckBuff = null;
+        stateCheckBuffSize = 0;
+    }
+
+    private void push(int type, int pat, int s, int prev) {
+        StackEntry e = ensure1();
+        e.type = type;
+        e.setStatePCode(pat);
+        e.setStatePStr(s);
+        e.setStatePStrPrev(prev);
+        if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
+        stk++;
+    }
+
+    protected final void pushEnsured(int type, int pat) {
+        StackEntry e = stack[stk];
+        e.type = type;
+        e.setStatePCode(pat);
+        if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
+        stk++;
+    }
+
+    protected final void pushAltWithStateCheck(int pat, int s, int sprev, int snum) {
+        StackEntry e = ensure1();
+        e.type = ALT;
+        e.setStatePCode(pat);
+        e.setStatePStr(s);
+        e.setStatePStrPrev(sprev);
+        if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(stateCheckBuff != null ? snum : 0);
+        stk++;
+    }
+
+    protected final void pushStateCheck(int s, int snum) {
+        if (stateCheckBuff != null) {
+            StackEntry e = ensure1();
+            e.type = STATE_CHECK_MARK;
+            e.setStatePStr(s);
+            e.setStateCheck(snum);
+            stk++;
+        }
+    }
+
+    protected final void pushAlt(int pat, int s, int prev) {
+        push(ALT, pat, s, prev);
+    }
+
+    protected final void pushPos(int s, int prev) {
+        push(POS, -1 /*NULL_UCHARP*/, s, prev);
+    }
+
+    protected final void pushPosNot(int pat, int s, int prev) {
+        push(POS_NOT, pat, s, prev);
+    }
+
+    protected final void pushStopBT() {
+        pushType(STOP_BT);
+    }
+
+    protected final void pushLookBehindNot(int pat, int s, int sprev) {
+        push(LOOK_BEHIND_NOT, pat, s, sprev);
+    }
+
+    protected final void pushRepeat(int id, int pat) {
+        StackEntry e = ensure1();
+        e.type = REPEAT;
+        e.setRepeatNum(id);
+        e.setRepeatPCode(pat);
+        e.setRepeatCount(0);
+        stk++;
+    }
+
+    protected final void pushRepeatInc(int sindex) {
+        StackEntry e = ensure1();
+        e.type = REPEAT_INC;
+        e.setSi(sindex);
+        stk++;
+    }
+
+    protected final void pushMemStart(int mnum, int s) {
+        StackEntry e = ensure1();
+        e.type = MEM_START;
+        e.setMemNum(mnum);
+        e.setMemPstr(s);
+        e.setMemStart(repeatStk[memStartStk + mnum]);
+        e.setMemEnd(repeatStk[memEndStk + mnum]);
+        repeatStk[memStartStk + mnum] = stk;
+        repeatStk[memEndStk + mnum] = INVALID_INDEX;
+        stk++;
+    }
+
+    protected final void pushMemEnd(int mnum, int s) {
+        StackEntry e = ensure1();
+        e.type = MEM_END;
+        e.setMemNum(mnum);
+        e.setMemPstr(s);
+        e.setMemStart(repeatStk[memStartStk + mnum]);
+        e.setMemEnd(repeatStk[memEndStk + mnum]);
+        repeatStk[memEndStk + mnum] = stk;
+        stk++;
+    }
+
+    protected final void pushMemEndMark(int mnum) {
+        StackEntry e = ensure1();
+        e.type = MEM_END_MARK;
+        e.setMemNum(mnum);
+        stk++;
+    }
+
+    protected final int getMemStart(int mnum) {
+        int level = 0;
+        int stkp = stk;
+
+        while (stkp > 0) {
+            stkp--;
+            StackEntry e = stack[stkp];
+            if ((e.type & MASK_MEM_END_OR_MARK) != 0 && e.getMemNum() == mnum) {
+                level++;
+            } else if (e.type == MEM_START && e.getMemNum() == mnum) {
+                if (level == 0) break;
+                level--;
+            }
+        }
+        return stkp;
+    }
+
+    protected final void pushNullCheckStart(int cnum, int s) {
+        StackEntry e = ensure1();
+        e.type = NULL_CHECK_START;
+        e.setNullCheckNum(cnum);
+        e.setNullCheckPStr(s);
+        stk++;
+    }
+
+    protected final void pushNullCheckEnd(int cnum) {
+        StackEntry e = ensure1();
+        e.type = NULL_CHECK_END;
+        e.setNullCheckNum(cnum);
+        stk++;
+    }
+
+    protected final void pushCallFrame(int pat) {
+        StackEntry e = ensure1();
+        e.type = CALL_FRAME;
+        e.setCallFrameRetAddr(pat);
+        stk++;
+    }
+
+    protected final void pushReturn() {
+        StackEntry e = ensure1();
+        e.type = RETURN;
+        stk++;
+    }
+
+    // stack debug routines here
+    // ...
+
+    protected final void popOne() {
+        stk--;
+    }
+
+    protected final StackEntry pop() {
+        switch (regex.stackPopLevel) {
+        case StackPopLevel.FREE:
+            return popFree();
+        case StackPopLevel.MEM_START:
+            return popMemStart();
+        default:
+            return popDefault();
+        }
+    }
+
+    private StackEntry popFree() {
+        while (true) {
+            StackEntry e = stack[--stk];
+
+            if ((e.type & MASK_POP_USED) != 0) {
+                return e;
+            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+                if (e.type == STATE_CHECK_MARK) stateCheckMark();
+            }
+        }
+    }
+
+    private StackEntry popMemStart() {
+        while (true) {
+            StackEntry e = stack[--stk];
+
+            if ((e.type & MASK_POP_USED) != 0) {
+                return e;
+            } else if (e.type == MEM_START) {
+                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
+                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
+            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+                if (e.type == STATE_CHECK_MARK) stateCheckMark();
+            }
+        }
+    }
+
+    private StackEntry popDefault() {
+        while (true) {
+            StackEntry e = stack[--stk];
+
+            if ((e.type & MASK_POP_USED) != 0) {
+                return e;
+            } else if (e.type == MEM_START) {
+                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
+                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
+            } else if (e.type == REPEAT_INC) {
+                //int si = stack[stk + IREPEAT_INC_SI];
+                //stack[si + IREPEAT_COUNT]--;
+                stack[e.getSi()].decreaseRepeatCount();
+            } else if (e.type == MEM_END) {
+                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
+                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
+            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+                if (e.type == STATE_CHECK_MARK) stateCheckMark();
+            }
+        }
+    }
+
+    protected final void popTilPosNot() {
+        while (true) {
+            stk--;
+            StackEntry e = stack[stk];
+
+            if (e.type == POS_NOT) {
+                break;
+            } else if (e.type == MEM_START) {
+                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
+                repeatStk[memEndStk + e.getMemNum()] = e.getMemStart();
+            } else if (e.type == REPEAT_INC) {
+                //int si = stack[stk + IREPEAT_INC_SI];
+                //stack[si + IREPEAT_COUNT]--;
+                stack[e.getSi()].decreaseRepeatCount();
+            } else if (e.type == MEM_END){
+                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
+                repeatStk[memEndStk + e.getMemNum()] = e.getMemStart();
+            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+                if (e.type == STATE_CHECK_MARK) stateCheckMark();
+            }
+        }
+    }
+
+    protected final void popTilLookBehindNot() {
+        while (true) {
+            stk--;
+            StackEntry e = stack[stk];
+
+            if (e.type == LOOK_BEHIND_NOT) {
+                break;
+            } else if (e.type == MEM_START) {
+                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
+                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
+            } else if (e.type == REPEAT_INC) {
+                //int si = stack[stk + IREPEAT_INC_SI];
+                //stack[si + IREPEAT_COUNT]--;
+                stack[e.getSi()].decreaseRepeatCount();
+            } else if (e.type == MEM_END) {
+                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
+                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
+            } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+                if (e.type == STATE_CHECK_MARK) stateCheckMark();
+            }
+        }
+    }
+
+    protected final int posEnd() {
+        int k = stk;
+        while (true) {
+            k--;
+            StackEntry e = stack[k];
+            if ((e.type & MASK_TO_VOID_TARGET) != 0) {
+                e.type = VOID;
+            } else if (e.type == POS) {
+                e.type = VOID;
+                break;
+            }
+        }
+        return k;
+    }
+
+    protected final void stopBtEnd() {
+        int k = stk;
+        while (true) {
+            k--;
+            StackEntry e = stack[k];
+
+            if ((e.type & MASK_TO_VOID_TARGET) != 0) {
+                e.type = VOID;
+            } else if (e.type == STOP_BT) {
+                e.type = VOID;
+                break;
+            }
+        }
+    }
+
+    // int for consistency with other null check routines
+    protected final int nullCheck(int id, int s) {
+        int k = stk;
+        while (true) {
+            k--;
+            StackEntry e = stack[k];
+
+            if (e.type == NULL_CHECK_START) {
+                if (e.getNullCheckNum() == id) {
+                    return e.getNullCheckPStr() == s ? 1 : 0;
+                }
+            }
+        }
+    }
+
+    protected final int nullCheckRec(int id, int s) {
+        int level = 0;
+        int k = stk;
+        while (true) {
+            k--;
+            StackEntry e = stack[k];
+
+            if (e.type == NULL_CHECK_START) {
+                if (e.getNullCheckNum() == id) {
+                    if (level == 0) {
+                        return e.getNullCheckPStr() == s ? 1 : 0;
+                    } else {
+                        level--;
+                    }
+                }
+            } else if (e.type == NULL_CHECK_END) {
+                level++;
+            }
+        }
+    }
+
+    protected final int nullCheckMemSt(int id, int s) {
+        int k = stk;
+        int isNull;
+        while (true) {
+            k--;
+            StackEntry e = stack[k];
+
+            if (e.type == NULL_CHECK_START) {
+                if (e.getNullCheckNum() == id) {
+                    if (e.getNullCheckPStr() != s) {
+                        isNull = 0;
+                        break;
+                    } else {
+                        int endp;
+                        isNull = 1;
+                        while (k < stk) {
+                            if (e.type == MEM_START) {
+                                if (e.getMemEnd() == INVALID_INDEX) {
+                                    isNull = 0;
+                                    break;
+                                }
+                                if (bsAt(regex.btMemEnd, e.getMemNum())) {
+                                    endp = stack[e.getMemEnd()].getMemPStr();
+                                } else {
+                                    endp = e.getMemEnd();
+                                }
+                                if (stack[e.getMemStart()].getMemPStr() != endp) {
+                                    isNull = 0;
+                                    break;
+                                } else if (endp != s) {
+                                    isNull = -1; /* empty, but position changed */
+                                }
+                            }
+                            k++;
+                            e = stack[k]; // !!
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+        return isNull;
+    }
+
+    protected final int nullCheckMemStRec(int id, int s) {
+        int level = 0;
+        int k = stk;
+        int isNull;
+        while (true) {
+            k--;
+            StackEntry e = stack[k];
+
+            if (e.type == NULL_CHECK_START) {
+                if (e.getNullCheckNum() == id) {
+                    if (level == 0) {
+                        if (e.getNullCheckPStr() != s) {
+                            isNull = 0;
+                            break;
+                        } else {
+                            int endp;
+                            isNull = 1;
+                            while (k < stk) {
+                                if (e.type == MEM_START) {
+                                    if (e.getMemEnd() == INVALID_INDEX) {
+                                        isNull = 0;
+                                        break;
+                                    }
+                                    if (bsAt(regex.btMemEnd, e.getMemNum())) {
+                                        endp = stack[e.getMemEnd()].getMemPStr();
+                                    } else {
+                                        endp = e.getMemEnd();
+                                    }
+                                    if (stack[e.getMemStart()].getMemPStr() != endp) {
+                                        isNull = 0;
+                                        break;
+                                    } else if (endp != s) {
+                                        isNull = -1;; /* empty, but position changed */
+                                    }
+                                }
+                                k++;
+                                e = stack[k];
+                            }
+                            break;
+                        }
+                    } else {
+                        level--;
+                    }
+                }
+            } else if (e.type == NULL_CHECK_END) {
+                if (e.getNullCheckNum() == id) level++;
+            }
+        }
+        return isNull;
+    }
+
+    protected final int getRepeat(int id) {
+        int level = 0;
+        int k = stk;
+        while (true) {
+            k--;
+            StackEntry e = stack[k];
+
+            if (e.type == REPEAT) {
+                if (level == 0) {
+                    if (e.getRepeatNum() == id) return k;
+                }
+            } else if (e.type == CALL_FRAME) {
+                level--;
+            } else if (e.type == RETURN) {
+                level++;
+            }
+        }
+    }
+
+    protected final int sreturn() {
+        int level = 0;
+        int k = stk;
+        while (true) {
+            k--;
+            StackEntry e = stack[k];
+
+            if (e.type == CALL_FRAME) {
+                if (level == 0) {
+                    return e.getCallFrameRetAddr();
+                } else {
+                    level--;
+                }
+            } else if (e.type == RETURN) {
+                level++;
+            }
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java
new file mode 100644
index 0000000..07b5262
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java
@@ -0,0 +1,628 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.constants.MetaChar.INEFFECTIVE_META_CHAR;
+
+import jdk.nashorn.internal.runtime.regexp.joni.constants.SyntaxProperties;
+
+public final class Syntax implements SyntaxProperties{
+    private final int op;
+    private final int op2;
+    private final int behavior;
+    public final int options;
+    public final MetaCharTable metaCharTable;
+
+    public Syntax(int op, int op2, int behavior, int options, MetaCharTable metaCharTable) {
+        this.op = op;
+        this.op2 = op2;
+        this.behavior = behavior;
+        this.options = options;
+        this.metaCharTable = metaCharTable;
+    }
+
+    public static class MetaCharTable {
+        public final int esc;
+        public final int anyChar;
+        public final int anyTime;
+        public final int zeroOrOneTime;
+        public final int oneOrMoreTime;
+        public final int anyCharAnyTime;
+
+        public MetaCharTable(int esc, int anyChar, int anyTime,
+                             int zeroOrOneTime, int oneOrMoreTime, int anyCharAnyTime) {
+            this.esc = esc;
+            this.anyChar = anyChar;
+            this.anyTime = anyTime;
+            this.zeroOrOneTime = zeroOrOneTime;
+            this.oneOrMoreTime = oneOrMoreTime;
+            this.anyCharAnyTime = anyCharAnyTime;
+        }
+    }
+
+    /**
+     * OP
+     *
+     */
+    protected boolean isOp(int opm) {
+        return (op & opm) != 0;
+    }
+
+    public boolean opVariableMetaCharacters() {
+        return isOp(OP_VARIABLE_META_CHARACTERS);
+    }
+
+    public boolean opDotAnyChar() {
+        return isOp(OP_DOT_ANYCHAR);
+    }
+
+    public boolean opAsteriskZeroInf() {
+        return isOp(OP_ASTERISK_ZERO_INF);
+    }
+
+    public boolean opEscAsteriskZeroInf() {
+        return isOp(OP_ESC_ASTERISK_ZERO_INF);
+    }
+
+    public boolean opPlusOneInf() {
+        return isOp(OP_PLUS_ONE_INF);
+    }
+
+    public boolean opEscPlusOneInf() {
+        return isOp(OP_ESC_PLUS_ONE_INF);
+    }
+
+    public boolean opQMarkZeroOne() {
+        return isOp(OP_QMARK_ZERO_ONE);
+    }
+
+    public boolean opEscQMarkZeroOne() {
+        return isOp(OP_ESC_QMARK_ZERO_ONE);
+    }
+
+    public boolean opBraceInterval() {
+        return isOp(OP_BRACE_INTERVAL);
+    }
+
+    public boolean opEscBraceInterval() {
+        return isOp(OP_ESC_BRACE_INTERVAL);
+    }
+
+    public boolean opVBarAlt() {
+        return isOp(OP_VBAR_ALT);
+    }
+
+    public boolean opEscVBarAlt() {
+        return isOp(OP_ESC_VBAR_ALT);
+    }
+
+    public boolean opLParenSubexp() {
+        return isOp(OP_LPAREN_SUBEXP);
+    }
+
+    public boolean opEscLParenSubexp() {
+        return isOp(OP_ESC_LPAREN_SUBEXP);
+    }
+
+    public boolean opEscAZBufAnchor() {
+        return isOp(OP_ESC_AZ_BUF_ANCHOR);
+    }
+
+    public boolean opEscCapitalGBeginAnchor() {
+        return isOp(OP_ESC_CAPITAL_G_BEGIN_ANCHOR);
+    }
+
+    public boolean opDecimalBackref() {
+        return isOp(OP_DECIMAL_BACKREF);
+    }
+
+    public boolean opBracketCC() {
+        return isOp(OP_BRACKET_CC);
+    }
+
+    public boolean opEscWWord() {
+        return isOp(OP_ESC_W_WORD);
+    }
+
+    public boolean opEscLtGtWordBeginEnd() {
+        return isOp(OP_ESC_LTGT_WORD_BEGIN_END);
+    }
+
+    public boolean opEscBWordBound() {
+        return isOp(OP_ESC_B_WORD_BOUND);
+    }
+
+    public boolean opEscSWhiteSpace() {
+        return isOp(OP_ESC_S_WHITE_SPACE);
+    }
+
+    public boolean opEscDDigit() {
+        return isOp(OP_ESC_D_DIGIT);
+    }
+
+    public boolean opLineAnchor() {
+        return isOp(OP_LINE_ANCHOR);
+    }
+
+    public boolean opPosixBracket() {
+        return isOp(OP_POSIX_BRACKET);
+    }
+
+    public boolean opQMarkNonGreedy() {
+        return isOp(OP_QMARK_NON_GREEDY);
+    }
+
+    public boolean opEscControlChars() {
+        return isOp(OP_ESC_CONTROL_CHARS);
+    }
+
+    public boolean opEscCControl() {
+        return isOp(OP_ESC_C_CONTROL);
+    }
+
+    public boolean opEscOctal3() {
+        return isOp(OP_ESC_OCTAL3);
+    }
+
+    public boolean opEscXHex2() {
+        return isOp(OP_ESC_X_HEX2);
+    }
+
+    public boolean opEscXBraceHex8() {
+        return isOp(OP_ESC_X_BRACE_HEX8);
+    }
+
+
+    /**
+     * OP
+     *
+     */
+    protected boolean isOp2(int opm) {
+        return (op2 & opm) != 0;
+    }
+
+    public boolean op2EscCapitalQQuote() {
+        return isOp2(OP2_ESC_CAPITAL_Q_QUOTE);
+    }
+
+    public boolean op2QMarkGroupEffect() {
+        return isOp2(OP2_QMARK_GROUP_EFFECT);
+    }
+
+    public boolean op2OptionPerl() {
+        return isOp2(OP2_OPTION_PERL);
+    }
+
+    public boolean op2OptionRuby() {
+        return isOp2(OP2_OPTION_RUBY);
+    }
+
+    public boolean op2PlusPossessiveRepeat() {
+        return isOp2(OP2_PLUS_POSSESSIVE_REPEAT);
+    }
+
+    public boolean op2PlusPossessiveInterval() {
+        return isOp2(OP2_PLUS_POSSESSIVE_INTERVAL);
+    }
+
+    public boolean op2CClassSetOp() {
+        return isOp2(OP2_CCLASS_SET_OP);
+    }
+
+    public boolean op2QMarkLtNamedGroup() {
+        return isOp2(OP2_QMARK_LT_NAMED_GROUP);
+    }
+
+    public boolean op2EscKNamedBackref() {
+        return isOp2(OP2_ESC_K_NAMED_BACKREF);
+    }
+
+    public boolean op2EscGSubexpCall() {
+        return isOp2(OP2_ESC_G_SUBEXP_CALL);
+    }
+
+    public boolean op2AtMarkCaptureHistory() {
+        return isOp2(OP2_ATMARK_CAPTURE_HISTORY);
+    }
+
+    public boolean op2EscCapitalCBarControl() {
+        return isOp2(OP2_ESC_CAPITAL_C_BAR_CONTROL);
+    }
+
+    public boolean op2EscCapitalMBarMeta() {
+        return isOp2(OP2_ESC_CAPITAL_M_BAR_META);
+    }
+
+    public boolean op2EscVVtab() {
+        return isOp2(OP2_ESC_V_VTAB);
+    }
+
+    public boolean op2EscUHex4() {
+        return isOp2(OP2_ESC_U_HEX4);
+    }
+
+    public boolean op2EscGnuBufAnchor() {
+        return isOp2(OP2_ESC_GNU_BUF_ANCHOR);
+    }
+
+    public boolean op2EscPBraceCharProperty() {
+        return isOp2(OP2_ESC_P_BRACE_CHAR_PROPERTY);
+    }
+
+    public boolean op2EscPBraceCircumflexNot() {
+        return isOp2(OP2_ESC_P_BRACE_CIRCUMFLEX_NOT);
+    }
+
+    public boolean op2EscHXDigit() {
+        return isOp2(OP2_ESC_H_XDIGIT);
+    }
+
+    public boolean op2IneffectiveEscape() {
+        return isOp2(OP2_INEFFECTIVE_ESCAPE);
+    }
+
+    /**
+     * BEHAVIOR
+     *
+     */
+    protected boolean isBehavior(int bvm) {
+        return (behavior & bvm) != 0;
+    }
+
+    public boolean contextIndepRepeatOps() {
+        return isBehavior(CONTEXT_INDEP_REPEAT_OPS);
+    }
+
+    public boolean contextInvalidRepeatOps() {
+        return isBehavior(CONTEXT_INVALID_REPEAT_OPS);
+    }
+
+    public boolean allowUnmatchedCloseSubexp() {
+        return isBehavior(ALLOW_UNMATCHED_CLOSE_SUBEXP);
+    }
+
+    public boolean allowInvalidInterval() {
+        return isBehavior(ALLOW_INVALID_INTERVAL);
+    }
+
+    public boolean allowIntervalLowAbbrev() {
+        return isBehavior(ALLOW_INTERVAL_LOW_ABBREV);
+    }
+
+    public boolean strictCheckBackref() {
+        return isBehavior(STRICT_CHECK_BACKREF);
+    }
+
+    public boolean differentLengthAltLookBehind() {
+        return isBehavior(DIFFERENT_LEN_ALT_LOOK_BEHIND);
+    }
+
+    public boolean captureOnlyNamedGroup() {
+        return isBehavior(CAPTURE_ONLY_NAMED_GROUP);
+    }
+
+    public boolean allowMultiplexDefinitionName() {
+        return isBehavior(ALLOW_MULTIPLEX_DEFINITION_NAME);
+    }
+
+    public boolean fixedIntervalIsGreedyOnly() {
+        return isBehavior(FIXED_INTERVAL_IS_GREEDY_ONLY);
+    }
+
+
+    public boolean notNewlineInNegativeCC() {
+        return isBehavior(NOT_NEWLINE_IN_NEGATIVE_CC);
+    }
+
+    public boolean backSlashEscapeInCC() {
+        return isBehavior(BACKSLASH_ESCAPE_IN_CC);
+    }
+
+    public boolean allowEmptyRangeInCC() {
+        return isBehavior(ALLOW_EMPTY_RANGE_IN_CC);
+    }
+
+    public boolean allowDoubleRangeOpInCC() {
+        return isBehavior(ALLOW_DOUBLE_RANGE_OP_IN_CC);
+    }
+
+    public boolean warnCCOpNotEscaped() {
+        return isBehavior(WARN_CC_OP_NOT_ESCAPED);
+    }
+
+    public boolean warnReduntantNestedRepeat() {
+        return isBehavior(WARN_REDUNDANT_NESTED_REPEAT);
+    }
+
+    public static final Syntax RUBY = new Syntax(
+        (( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
+        OP_ESC_OCTAL3 | OP_ESC_X_HEX2 |
+        OP_ESC_X_BRACE_HEX8 | OP_ESC_CONTROL_CHARS |
+        OP_ESC_C_CONTROL )
+        & ~OP_ESC_LTGT_WORD_BEGIN_END ),
+
+        ( OP2_QMARK_GROUP_EFFECT |
+        OP2_OPTION_RUBY |
+        OP2_QMARK_LT_NAMED_GROUP | OP2_ESC_K_NAMED_BACKREF |
+        OP2_ESC_G_SUBEXP_CALL |
+        OP2_ESC_P_BRACE_CHAR_PROPERTY  |
+        OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
+        OP2_PLUS_POSSESSIVE_REPEAT |
+        OP2_CCLASS_SET_OP | OP2_ESC_CAPITAL_C_BAR_CONTROL |
+        OP2_ESC_CAPITAL_M_BAR_META | OP2_ESC_V_VTAB |
+        OP2_ESC_H_XDIGIT ),
+
+        ( GNU_REGEX_BV |
+        ALLOW_INTERVAL_LOW_ABBREV |
+        DIFFERENT_LEN_ALT_LOOK_BEHIND |
+        CAPTURE_ONLY_NAMED_GROUP |
+        ALLOW_MULTIPLEX_DEFINITION_NAME |
+        FIXED_INTERVAL_IS_GREEDY_ONLY |
+        WARN_CC_OP_NOT_ESCAPED |
+        WARN_REDUNDANT_NESTED_REPEAT ),
+
+        Option.NONE,
+
+        new MetaCharTable(
+            '\\',                           /* esc */
+            INEFFECTIVE_META_CHAR,          /* anychar '.' */
+            INEFFECTIVE_META_CHAR,          /* anytime '*' */
+            INEFFECTIVE_META_CHAR,          /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,          /* one or more time '+' */
+            INEFFECTIVE_META_CHAR           /* anychar anytime */
+        )
+    );
+
+    public static final Syntax DEFAULT = RUBY;
+
+    public static final Syntax ASIS = new Syntax(
+        0,
+
+        OP2_INEFFECTIVE_ESCAPE,
+
+        0,
+
+        Option.NONE,
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+
+    public static final Syntax PosixBasic = new Syntax(
+        (POSIX_COMMON_OP | OP_ESC_LPAREN_SUBEXP |
+        OP_ESC_BRACE_INTERVAL ),
+
+        0,
+
+        0,
+
+        ( Option.SINGLELINE | Option.MULTILINE ),
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+
+    public static final Syntax PosixExtended = new Syntax(
+        ( POSIX_COMMON_OP | OP_LPAREN_SUBEXP |
+        OP_BRACE_INTERVAL |
+        OP_PLUS_ONE_INF | OP_QMARK_ZERO_ONE |OP_VBAR_ALT ),
+
+        0,
+
+        ( CONTEXT_INDEP_ANCHORS |
+        CONTEXT_INDEP_REPEAT_OPS | CONTEXT_INVALID_REPEAT_OPS |
+        ALLOW_UNMATCHED_CLOSE_SUBEXP |
+        ALLOW_DOUBLE_RANGE_OP_IN_CC ),
+
+        ( Option.SINGLELINE | Option.MULTILINE ),
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+
+    public static final Syntax Emacs = new Syntax(
+        ( OP_DOT_ANYCHAR | OP_BRACKET_CC |
+        OP_ESC_BRACE_INTERVAL |
+        OP_ESC_LPAREN_SUBEXP | OP_ESC_VBAR_ALT |
+        OP_ASTERISK_ZERO_INF | OP_PLUS_ONE_INF |
+        OP_QMARK_ZERO_ONE | OP_DECIMAL_BACKREF |
+        OP_LINE_ANCHOR | OP_ESC_CONTROL_CHARS ),
+
+        OP2_ESC_GNU_BUF_ANCHOR,
+
+        ALLOW_EMPTY_RANGE_IN_CC,
+
+        Option.NONE,
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+
+    public static final Syntax Grep = new Syntax(
+        ( OP_DOT_ANYCHAR | OP_BRACKET_CC | OP_POSIX_BRACKET |
+        OP_ESC_BRACE_INTERVAL | OP_ESC_LPAREN_SUBEXP |
+        OP_ESC_VBAR_ALT |
+        OP_ASTERISK_ZERO_INF | OP_ESC_PLUS_ONE_INF |
+        OP_ESC_QMARK_ZERO_ONE | OP_LINE_ANCHOR |
+        OP_ESC_W_WORD | OP_ESC_B_WORD_BOUND |
+        OP_ESC_LTGT_WORD_BEGIN_END | OP_DECIMAL_BACKREF ),
+
+        0,
+
+        ( ALLOW_EMPTY_RANGE_IN_CC | NOT_NEWLINE_IN_NEGATIVE_CC ),
+
+        Option.NONE,
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+
+    public static final Syntax GnuRegex = new Syntax(
+        GNU_REGEX_OP,
+        0,
+        GNU_REGEX_BV,
+
+        Option.NONE,
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+
+    public static final Syntax Java = new Syntax(
+        (( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
+        OP_ESC_CONTROL_CHARS | OP_ESC_C_CONTROL |
+        OP_ESC_OCTAL3 | OP_ESC_X_HEX2 )
+        & ~OP_ESC_LTGT_WORD_BEGIN_END ),
+
+        ( OP2_ESC_CAPITAL_Q_QUOTE | OP2_QMARK_GROUP_EFFECT |
+        OP2_OPTION_PERL | OP2_PLUS_POSSESSIVE_REPEAT |
+        OP2_PLUS_POSSESSIVE_INTERVAL | OP2_CCLASS_SET_OP |
+        OP2_ESC_V_VTAB | OP2_ESC_U_HEX4 |
+        OP2_ESC_P_BRACE_CHAR_PROPERTY ),
+
+        ( GNU_REGEX_BV | DIFFERENT_LEN_ALT_LOOK_BEHIND ),
+
+        Option.SINGLELINE,
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+
+    public static final Syntax Perl = new Syntax(
+        (( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
+        OP_ESC_OCTAL3 | OP_ESC_X_HEX2 |
+        OP_ESC_X_BRACE_HEX8 | OP_ESC_CONTROL_CHARS |
+        OP_ESC_C_CONTROL )
+        & ~OP_ESC_LTGT_WORD_BEGIN_END ),
+
+        ( OP2_ESC_CAPITAL_Q_QUOTE |
+        OP2_QMARK_GROUP_EFFECT | OP2_OPTION_PERL |
+        OP2_ESC_P_BRACE_CHAR_PROPERTY |
+        OP2_ESC_P_BRACE_CIRCUMFLEX_NOT ),
+
+        GNU_REGEX_BV,
+
+        Option.SINGLELINE,
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+
+    public static final Syntax PerlNG = new Syntax(
+        (( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
+        OP_ESC_OCTAL3 | OP_ESC_X_HEX2 |
+        OP_ESC_X_BRACE_HEX8 | OP_ESC_CONTROL_CHARS |
+        OP_ESC_C_CONTROL )
+        & ~OP_ESC_LTGT_WORD_BEGIN_END ),
+
+        ( OP2_ESC_CAPITAL_Q_QUOTE |
+        OP2_QMARK_GROUP_EFFECT | OP2_OPTION_PERL |
+        OP2_ESC_P_BRACE_CHAR_PROPERTY  |
+        OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
+        OP2_QMARK_LT_NAMED_GROUP       |
+        OP2_ESC_K_NAMED_BACKREF        |
+        OP2_ESC_G_SUBEXP_CALL ),
+
+        ( GNU_REGEX_BV |
+        CAPTURE_ONLY_NAMED_GROUP |
+        ALLOW_MULTIPLEX_DEFINITION_NAME ),
+
+        Option.SINGLELINE,
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+
+    public static final Syntax JAVASCRIPT = new Syntax(
+        (( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
+        OP_ESC_CONTROL_CHARS | OP_ESC_C_CONTROL | OP_ESC_X_HEX2)
+        & ~OP_ESC_LTGT_WORD_BEGIN_END ),
+
+        ( OP2_QMARK_GROUP_EFFECT | OP2_CCLASS_SET_OP |
+        OP2_ESC_V_VTAB | OP2_ESC_U_HEX4 ),
+
+        ( GNU_REGEX_BV | DIFFERENT_LEN_ALT_LOOK_BEHIND ),
+
+        Option.SINGLELINE,
+
+        new MetaCharTable(
+            '\\',                          /* esc */
+            INEFFECTIVE_META_CHAR,         /* anychar '.' */
+            INEFFECTIVE_META_CHAR,         /* anytime '*' */
+            INEFFECTIVE_META_CHAR,         /* zero or one time '?' */
+            INEFFECTIVE_META_CHAR,         /* one or more time '+' */
+            INEFFECTIVE_META_CHAR          /* anychar anytime */
+        )
+    );
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Token.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Token.java
new file mode 100644
index 0000000..bcaf352
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Token.java
@@ -0,0 +1,172 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.constants.TokenType;
+
+final class Token {
+    TokenType type;
+    boolean escaped;
+    int base;               /* is number: 8, 16 (used in [....]) */
+    int backP;
+
+    // union fields
+    private int INT1, INT2, INT3, INT4, INT5;
+    private int []INTA1;
+
+    // union accessors
+    int getC() {
+        return INT1;
+    }
+    void setC(int c) {
+        INT1 = c;
+    }
+
+    int getCode() {
+        return INT1;
+    }
+    void setCode(int code) {
+        INT1 = code;
+    }
+
+    int getAnchor() {
+        return INT1;
+    }
+    void setAnchor(int anchor) {
+        INT1 = anchor;
+    }
+
+    int getSubtype() {
+        return INT1;
+    }
+    void setSubtype(int subtype) {
+        INT1 = subtype;
+    }
+
+    // repeat union member
+    int getRepeatLower() {
+        return INT1;
+    }
+    void setRepeatLower(int lower) {
+        INT1 = lower;
+    }
+
+    int getRepeatUpper() {
+        return INT2;
+    }
+    void setRepeatUpper(int upper) {
+        INT2 = upper;
+    }
+
+    boolean getRepeatGreedy() {
+        return INT3 != 0;
+    }
+    void setRepeatGreedy(boolean greedy) {
+        INT3 = greedy ? 1 : 0;
+    }
+
+    boolean getRepeatPossessive() {
+        return INT4 != 0;
+    }
+    void setRepeatPossessive(boolean possessive) {
+        INT4 = possessive ? 1 : 0;
+    }
+
+    // backref union member
+    int getBackrefNum() {
+        return INT1;
+    }
+    void setBackrefNum(int num) {
+        INT1 = num;
+    }
+
+    int getBackrefRef1() {
+        return INT2;
+    }
+    void setBackrefRef1(int ref1) {
+        INT2 = ref1;
+    }
+
+    int[]getBackrefRefs() {
+        return INTA1;
+    }
+    void setBackrefRefs(int[]refs) {
+        INTA1 = refs;
+    }
+
+    boolean getBackrefByName() {
+        return INT3 != 0;
+    }
+    void setBackrefByName(boolean byName) {
+        INT3 = byName ? 1 : 0;
+    }
+
+    // USE_BACKREF_AT_LEVEL
+    boolean getBackrefExistLevel() {
+        return INT4 != 0;
+    }
+    void setBackrefExistLevel(boolean existLevel) {
+        INT4 = existLevel ? 1 : 0;
+    }
+
+    int getBackrefLevel() {
+        return INT5;
+    }
+    void setBackrefLevel(int level) {
+        INT5 = level;
+    }
+
+    // call union member
+    int getCallNameP() {
+        return INT1;
+    }
+    void setCallNameP(int nameP) {
+        INT1 = nameP;
+    }
+
+    int getCallNameEnd() {
+        return INT2;
+    }
+    void setCallNameEnd(int nameEnd) {
+        INT2 = nameEnd;
+    }
+
+    int getCallGNum() {
+        return INT3;
+    }
+    void setCallGNum(int gnum) {
+        INT3 = gnum;
+    }
+
+    // prop union member
+    int getPropCType() {
+        return INT1;
+    }
+    void setPropCType(int ctype) {
+        INT1 = ctype;
+    }
+
+    boolean getPropNot() {
+        return INT2 != 0;
+    }
+    void setPropNot(boolean not) {
+        INT2 = not ? 1 : 0;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/UnsetAddrList.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/UnsetAddrList.java
new file mode 100644
index 0000000..ca72e16
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/UnsetAddrList.java
@@ -0,0 +1,69 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+
+public final class UnsetAddrList {
+    int num;
+    Node[]targets;
+    int[]offsets;
+
+    public UnsetAddrList(int size) {
+        targets = new Node[size];
+        offsets = new int[size];
+    }
+
+    public void add(int offset, Node node) {
+        if (num >= offsets.length) {
+            Node []ttmp = new Node[targets.length << 1];
+            System.arraycopy(targets, 0, ttmp, 0, num);
+            targets = ttmp;
+            int[]otmp = new int[offsets.length << 1];
+            System.arraycopy(offsets, 0, otmp, 0, num);
+            offsets = otmp;
+        }
+        targets[num] = node;
+        offsets[num] = offset;
+
+        num++;
+    }
+
+    public void fix(Regex regex) {
+        for (int i=0; i<num; i++) {
+            EncloseNode en = (EncloseNode)targets[i];
+            if (!en.isAddrFixed()) new InternalException(ErrorMessages.ERR_PARSER_BUG);
+            regex.code[offsets[i]] = en.callAddr; // is this safe ?
+        }
+    }
+
+    public String toString() {
+        StringBuilder value = new StringBuilder();
+        if (num > 0) {
+            for (int i=0; i<num; i++) {
+                value.append("offset + " + offsets[i] + " target: " + targets[i].getAddressName());
+            }
+        }
+        return value.toString();
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/WarnCallback.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/WarnCallback.java
new file mode 100644
index 0000000..f2a0353
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/WarnCallback.java
@@ -0,0 +1,33 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+/**
+ * @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
+ */
+public interface WarnCallback {
+    WarnCallback DEFAULT = new WarnCallback() {
+        public void warn(String message) {
+            System.err.println(message);
+        }
+    };
+
+    void warn(String message);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Warnings.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Warnings.java
new file mode 100644
index 0000000..890a081
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Warnings.java
@@ -0,0 +1,26 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni;
+
+public interface Warnings {
+    final String INVALID_BACKREFERENCE =            "invalid back reference";
+    final String INVALID_SUBEXP_CALL =              "invalid subexp call";
+    final String INVALID_UNICODE_PROPERTY =         "invalid Unicode Property \\<%n>";
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnchorNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnchorNode.java
new file mode 100644
index 0000000..d07a269
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnchorNode.java
@@ -0,0 +1,92 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+
+public final class AnchorNode extends Node implements AnchorType {
+    public int type;
+    public Node target;
+    public int charLength;
+
+    public AnchorNode(int type) {
+        this.type = type;
+        charLength = -1;
+    }
+
+    @Override
+    public int getType() {
+        return ANCHOR;
+    }
+
+    @Override
+    protected void setChild(Node newChild) {
+        target = newChild;
+    }
+
+    @Override
+    protected Node getChild() {
+        return target;
+    }
+
+    public void setTarget(Node tgt) {
+        target = tgt;
+        tgt.parent = this;
+    }
+
+    @Override
+    public String getName() {
+        return "Anchor";
+    }
+
+    @Override
+    public String toString(int level) {
+        StringBuilder value = new StringBuilder();
+        value.append("\n  type: " + typeToString());
+        value.append("\n  target: " + pad(target, level + 1));
+        return value.toString();
+    }
+
+    public String typeToString() {
+        StringBuilder type = new StringBuilder();
+        if (isType(BEGIN_BUF)) type.append("BEGIN_BUF ");
+        if (isType(BEGIN_LINE)) type.append("BEGIN_LINE ");
+        if (isType(BEGIN_POSITION)) type.append("BEGIN_POSITION ");
+        if (isType(END_BUF)) type.append("END_BUF ");
+        if (isType(SEMI_END_BUF)) type.append("SEMI_END_BUF ");
+        if (isType(END_LINE)) type.append("END_LINE ");
+        if (isType(WORD_BOUND)) type.append("WORD_BOUND ");
+        if (isType(NOT_WORD_BOUND)) type.append("NOT_WORD_BOUND ");
+        if (isType(WORD_BEGIN)) type.append("WORD_BEGIN ");
+        if (isType(WORD_END)) type.append("WORD_END ");
+        if (isType(PREC_READ)) type.append("PREC_READ ");
+        if (isType(PREC_READ_NOT)) type.append("PREC_READ_NOT ");
+        if (isType(LOOK_BEHIND)) type.append("LOOK_BEHIND ");
+        if (isType(LOOK_BEHIND_NOT)) type.append("LOOK_BEHIND_NOT ");
+        if (isType(ANYCHAR_STAR)) type.append("ANYCHAR_STAR ");
+        if (isType(ANYCHAR_STAR_ML)) type.append("ANYCHAR_STAR_ML ");
+        return type.toString();
+    }
+
+    private boolean isType(int type) {
+        return (this.type & type) != 0;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnyCharNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnyCharNode.java
new file mode 100644
index 0000000..9558ce2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnyCharNode.java
@@ -0,0 +1,40 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+public final class AnyCharNode extends Node {
+    public AnyCharNode(){}
+
+    @Override
+    public int getType() {
+        return CANY;
+    }
+
+    @Override
+    public String getName() {
+        return "Any Char";
+    }
+
+    @Override
+    public String toString(int level) {
+        String value = "";
+        return value;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/BackRefNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/BackRefNode.java
new file mode 100644
index 0000000..dde4f88
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/BackRefNode.java
@@ -0,0 +1,98 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
+
+public final class BackRefNode extends StateNode {
+    //private static int NODE_BACKREFS_SIZE = 6;
+
+    //int state;
+    public int backNum;
+    public int back[];
+
+    public int nestLevel;
+
+    public BackRefNode(int backNum, int[]backRefs, boolean byName, ScanEnvironment env) {
+        this.backNum = backNum;
+        if (byName) setNameRef();
+
+        for (int i=0; i<backNum; i++) {
+            if (backRefs[i] <= env.numMem && env.memNodes[backRefs[i]] == null) {
+                setRecursion(); /* /...(\1).../ */
+                break;
+            }
+        }
+
+        back = new int[backNum];
+        System.arraycopy(backRefs, 0, back, 0, backNum); // shall we really dup it ???
+    }
+
+    // #ifdef USE_BACKREF_AT_LEVEL
+    public BackRefNode(int backNum, int[]backRefs, boolean byName, boolean existLevel, int nestLevel, ScanEnvironment env) {
+        this(backNum, backRefs, byName, env);
+
+        if (existLevel) {
+            //state |= NST_NEST_LEVEL;
+            setNestLevel();
+            this.nestLevel = nestLevel;
+        }
+    }
+
+    @Override
+    public int getType() {
+        return BREF;
+    }
+
+    @Override
+    public String getName() {
+        return "Back Ref";
+    }
+
+    @Override
+    public String toString(int level) {
+        StringBuilder value = new StringBuilder(super.toString(level));
+        value.append("\n  backNum: " + backNum);
+        String backs = "";
+        for (int i=0; i<back.length; i++) backs += back[i] + ", ";
+        value.append("\n  back: " + backs);
+        value.append("\n  nextLevel: " + nestLevel);
+        return value.toString();
+    }
+
+    public void renumber(int[]map) {
+        if (!isNameRef()) throw new ValueException(ErrorMessages.ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
+
+        int oldNum = backNum;
+
+        int pos = 0;
+        for (int i=0; i<oldNum; i++) {
+            int n = map[back[i]];
+            if (n > 0) {
+                back[pos] = n;
+                pos++;
+            }
+        }
+        backNum = pos;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CClassNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CClassNode.java
new file mode 100644
index 0000000..4a73e26
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CClassNode.java
@@ -0,0 +1,545 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import jdk.nashorn.internal.runtime.regexp.joni.*;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.CCSTATE;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.CCVALTYPE;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.AsciiTables;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
+import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
+
+public final class CClassNode extends Node {
+    private static final int FLAG_NCCLASS_NOT = 1<<0;
+    private static final int FLAG_NCCLASS_SHARE = 1<<1;
+
+    int flags;
+    public final BitSet bs = new BitSet();  // conditional creation ?
+    public CodeRangeBuffer mbuf;            /* multi-byte info or NULL */
+
+    private int ctype;                      // for hashing purposes
+
+    // node_new_cclass
+    public CClassNode() {}
+
+    public CClassNode(int ctype, boolean not, int sbOut, int[]ranges) {
+        this(not, sbOut, ranges);
+        this.ctype = ctype;
+    }
+
+    public void clear() {
+        bs.clear();
+        flags = 0;
+        mbuf = null;
+    }
+
+    // node_new_cclass_by_codepoint_range, only used by shared Char Classes
+    public CClassNode(boolean not, int sbOut, int[]ranges) {
+        if (not) setNot();
+        // bs.clear();
+
+        if (sbOut > 0 && ranges != null) {
+            int n = ranges[0];
+            for (int i=0; i<n; i++) {
+                int from = ranges[i * 2 + 1];
+                int to = ranges[i * 2 + 2];
+                for (int j=from; j<=to; j++) {
+                    if (j >= sbOut) {
+                        setupBuffer(ranges);
+                        return;
+                    }
+                    bs.set(j);
+                }
+            }
+        }
+        setupBuffer(ranges);
+    }
+
+    @Override
+    public int getType() {
+        return CCLASS;
+    }
+
+    @Override
+    public String getName() {
+        return "Character Class";
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (!(other instanceof CClassNode)) return false;
+        CClassNode cc = (CClassNode)other;
+        return ctype == cc.ctype && isNot() == cc.isNot();
+    }
+
+    @Override
+    public int hashCode() {
+        if (Config.USE_SHARED_CCLASS_TABLE) {
+            int hash = 0;
+            hash += ctype;
+            if (isNot()) hash++;
+            return hash + (hash >> 5);
+        } else {
+            return super.hashCode();
+        }
+    }
+
+    @Override
+    public String toString(int level) {
+        StringBuilder value = new StringBuilder();
+        value.append("\n  flags: " + flagsToString());
+        value.append("\n  bs: " + pad(bs, level + 1));
+        value.append("\n  mbuf: " + pad(mbuf, level + 1));
+
+        return value.toString();
+    }
+
+    public String flagsToString() {
+        StringBuilder flags = new StringBuilder();
+        if (isNot()) flags.append("NOT ");
+        if (isShare()) flags.append("SHARE ");
+        return flags.toString();
+    }
+
+    private void setupBuffer(int[]ranges) {
+        if (ranges != null) {
+            if (ranges[0] == 0) return;
+            mbuf = new CodeRangeBuffer(ranges);
+        }
+    }
+
+    public boolean isEmpty() {
+        return mbuf == null && bs.isEmpty();
+    }
+
+    public void addCodeRangeToBuf(int from, int to) {
+        mbuf = CodeRangeBuffer.addCodeRangeToBuff(mbuf, from, to);
+    }
+
+    public void addCodeRange(ScanEnvironment env, int from, int to) {
+        mbuf = CodeRangeBuffer.addCodeRange(mbuf, env, from, to);
+    }
+
+    public void addAllMultiByteRange() {
+        mbuf = CodeRangeBuffer.addAllMultiByteRange(mbuf);
+    }
+
+    public void clearNotFlag() {
+        if (isNot()) {
+            bs.invert();
+
+            mbuf = CodeRangeBuffer.notCodeRangeBuff(mbuf);
+            clearNot();
+        }
+    }
+
+    // and_cclass
+    public void and(CClassNode other) {
+        boolean not1 = isNot();
+        BitSet bsr1 = bs;
+        CodeRangeBuffer buf1 = mbuf;
+        boolean not2 = other.isNot();
+        BitSet bsr2 = other.bs;
+        CodeRangeBuffer buf2 = other.mbuf;
+
+        if (not1) {
+            BitSet bs1 = new BitSet();
+            bsr1.invertTo(bs1);
+            bsr1 = bs1;
+        }
+
+        if (not2) {
+            BitSet bs2 = new BitSet();
+            bsr2.invertTo(bs2);
+            bsr2 = bs2;
+        }
+
+        bsr1.and(bsr2);
+
+        if (bsr1 != bs) {
+            bs.copy(bsr1);
+            bsr1 = bs;
+        }
+
+        if (not1) {
+            bs.invert();
+        }
+
+        CodeRangeBuffer pbuf = null;
+
+        if (not1 && not2) {
+            pbuf = CodeRangeBuffer.orCodeRangeBuff(buf1, false, buf2, false);
+        } else {
+            pbuf = CodeRangeBuffer.andCodeRangeBuff(buf1, not1, buf2, not2);
+
+            if (not1) {
+                pbuf = CodeRangeBuffer.notCodeRangeBuff(pbuf);
+            }
+        }
+        mbuf = pbuf;
+
+    }
+
+    // or_cclass
+    public void or(CClassNode other) {
+        boolean not1 = isNot();
+        BitSet bsr1 = bs;
+        CodeRangeBuffer buf1 = mbuf;
+        boolean not2 = other.isNot();
+        BitSet bsr2 = other.bs;
+        CodeRangeBuffer buf2 = other.mbuf;
+
+        if (not1) {
+            BitSet bs1 = new BitSet();
+            bsr1.invertTo(bs1);
+            bsr1 = bs1;
+        }
+
+        if (not2) {
+            BitSet bs2 = new BitSet();
+            bsr2.invertTo(bs2);
+            bsr2 = bs2;
+        }
+
+        bsr1.or(bsr2);
+
+        if (bsr1 != bs) {
+            bs.copy(bsr1);
+            bsr1 = bs;
+        }
+
+        if (not1) {
+            bs.invert();
+        }
+
+        CodeRangeBuffer pbuf = null;
+        if (not1 && not2) {
+            pbuf = CodeRangeBuffer.andCodeRangeBuff(buf1, false, buf2, false);
+        } else {
+            pbuf = CodeRangeBuffer.orCodeRangeBuff(buf1, not1, buf2, not2);
+            if (not1) {
+                pbuf = CodeRangeBuffer.notCodeRangeBuff(pbuf);
+            }
+        }
+        mbuf = pbuf;
+    }
+
+    // add_ctype_to_cc_by_range // Encoding out!
+    public void addCTypeByRange(int ctype, boolean not, int sbOut, int mbr[]) {
+        int n = mbr[0];
+
+        if (!not) {
+            for (int i=0; i<n; i++) {
+                for (int j=mbr[i * 2 + 1]; j<=mbr[i * 2 + 2]; j++) {
+                    if (j >= sbOut) {
+                        if (Config.VANILLA) {
+                            if (j == mbr[i * 2 + 2]) {
+                                i++;
+                            } else if (j > mbr[i * 2 + 1]) {
+                                addCodeRangeToBuf(j, mbr[i * 2 + 2]);
+                                i++;
+                            }
+                        } else {
+                            if (j >= mbr[i * 2 + 1]) {
+                                addCodeRangeToBuf(j, mbr[i * 2 + 2]);
+                                i++;
+                            }
+                        }
+                        // !goto sb_end!, remove duplication!
+                        for (; i<n; i++) {
+                            addCodeRangeToBuf(mbr[2 * i + 1], mbr[2 * i + 2]);
+                        }
+                        return;
+                    }
+                    bs.set(j);
+                }
+            }
+            // !sb_end:!
+            for (int i=0; i<n; i++) {
+                addCodeRangeToBuf(mbr[2 * i + 1], mbr[2 * i + 2]);
+            }
+
+        } else {
+            int prev = 0;
+
+            for (int i=0; i<n; i++) {
+                for (int j=prev; j < mbr[2 * i + 1]; j++) {
+                    if (j >= sbOut) {
+                        // !goto sb_end2!, remove duplication
+                        prev = sbOut;
+                        for (i=0; i<n; i++) {
+                            if (prev < mbr[2 * i + 1]) addCodeRangeToBuf(prev, mbr[i * 2 + 1] - 1);
+                            prev = mbr[i * 2 + 2] + 1;
+                        }
+                        if (prev < 0x7fffffff/*!!!*/) addCodeRangeToBuf(prev, 0x7fffffff);
+                        return;
+                    }
+                    bs.set(j);
+                }
+                prev = mbr[2 * i + 2] + 1;
+            }
+
+            for (int j=prev; j<sbOut; j++) {
+                bs.set(j);
+            }
+
+            // !sb_end2:!
+            prev = sbOut;
+            for (int i=0; i<n; i++) {
+                if (prev < mbr[2 * i + 1]) addCodeRangeToBuf(prev, mbr[i * 2 + 1] - 1);
+                prev = mbr[i * 2 + 2] + 1;
+            }
+            if (prev < 0x7fffffff/*!!!*/) addCodeRangeToBuf(prev, 0x7fffffff);
+        }
+    }
+
+    public void addCType(int ctype, boolean not, ScanEnvironment env, IntHolder sbOut) {
+        if (Config.NON_UNICODE_SDW) {
+            switch(ctype) {
+            case CharacterType.D:
+            case CharacterType.S:
+            case CharacterType.W:
+                ctype ^= CharacterType.SPECIAL_MASK;
+
+                if (env.syntax == Syntax.JAVASCRIPT && ctype == CharacterType.SPACE) {
+                    // \s in JavaScript includes unicode characters.
+                    break;
+                }
+
+                if (not) {
+                    for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
+                        // if (!ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
+                        if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) == 0) bs.set(c);
+                    }
+                    addAllMultiByteRange();
+                } else {
+                    for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
+                        // if (ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
+                        if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) != 0) bs.set(c);
+                    }
+                }
+                return;
+            }
+        }
+
+        int[] ranges = EncodingHelper.ctypeCodeRange(ctype, sbOut);
+        if (ranges != null) {
+            addCTypeByRange(ctype, not, sbOut.value, ranges);
+            return;
+        }
+
+        switch(ctype) {
+        case CharacterType.ALPHA:
+        case CharacterType.BLANK:
+        case CharacterType.CNTRL:
+        case CharacterType.DIGIT:
+        case CharacterType.LOWER:
+        case CharacterType.PUNCT:
+        case CharacterType.SPACE:
+        case CharacterType.UPPER:
+        case CharacterType.XDIGIT:
+        case CharacterType.ASCII:
+        case CharacterType.ALNUM:
+            if (not) {
+                for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+                    if (!EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
+                }
+                addAllMultiByteRange();
+            } else {
+                for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+                    if (EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
+                }
+            }
+            break;
+
+        case CharacterType.GRAPH:
+        case CharacterType.PRINT:
+            if (not) {
+                for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+                    if (!EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
+                }
+            } else {
+                for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+                    if (EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
+                }
+                addAllMultiByteRange();
+            }
+            break;
+
+        case CharacterType.WORD:
+            if (!not) {
+                for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+                    if (EncodingHelper.isWord(c)) bs.set(c);
+                }
+
+                addAllMultiByteRange();
+            } else {
+                for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+                    if (!EncodingHelper.isWord(c)) bs.set(c);
+                }
+            }
+            break;
+
+        default:
+            throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
+        } // switch
+    }
+
+    public static final class CCStateArg {
+        public int v;
+        public int vs;
+        public boolean vsIsRaw;
+        public boolean vIsRaw;
+        public CCVALTYPE inType;
+        public CCVALTYPE type;
+        public CCSTATE state;
+    }
+
+    public void nextStateClass(CCStateArg arg, ScanEnvironment env) {
+        if (arg.state == CCSTATE.RANGE) throw new SyntaxException(ErrorMessages.ERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE);
+
+        if (arg.state == CCSTATE.VALUE && arg.type != CCVALTYPE.CLASS) {
+            if (arg.type == CCVALTYPE.SB) {
+                bs.set(arg.vs);
+            } else if (arg.type == CCVALTYPE.CODE_POINT) {
+                addCodeRange(env, arg.vs, arg.vs);
+            }
+        }
+        arg.state = CCSTATE.VALUE;
+        arg.type = CCVALTYPE.CLASS;
+    }
+
+    public void nextStateValue(CCStateArg arg, ScanEnvironment env) {
+
+        switch(arg.state) {
+        case VALUE:
+            if (arg.type == CCVALTYPE.SB) {
+                if (arg.vs > 0xff) throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
+                bs.set(arg.vs);
+            } else if (arg.type == CCVALTYPE.CODE_POINT) {
+                addCodeRange(env, arg.vs, arg.vs);
+            }
+            break;
+
+        case RANGE:
+            if (arg.inType == arg.type) {
+                if (arg.inType == CCVALTYPE.SB) {
+                    if (arg.vs > 0xff || arg.v > 0xff) throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
+
+                    if (arg.vs > arg.v) {
+                        if (env.syntax.allowEmptyRangeInCC()) {
+                            // goto ccs_range_end
+                            arg.state = CCSTATE.COMPLETE;
+                            break;
+                        } else {
+                            throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
+                        }
+                    }
+                    bs.setRange(arg.vs, arg.v);
+                } else {
+                    addCodeRange(env, arg.vs, arg.v);
+                }
+            } else {
+                if (arg.vs > arg.v) {
+                    if (env.syntax.allowEmptyRangeInCC()) {
+                        // goto ccs_range_end
+                        arg.state = CCSTATE.COMPLETE;
+                        break;
+                    } else {
+                        throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
+                    }
+                }
+                bs.setRange(arg.vs, arg.v < 0xff ? arg.v : 0xff);
+                addCodeRange(env, arg.vs, arg.v);
+            }
+            // ccs_range_end:
+            arg.state = CCSTATE.COMPLETE;
+            break;
+
+        case COMPLETE:
+        case START:
+            arg.state = CCSTATE.VALUE;
+            break;
+
+        default:
+            break;
+
+        } // switch
+
+        arg.vsIsRaw = arg.vIsRaw;
+        arg.vs = arg.v;
+        arg.type = arg.inType;
+    }
+
+    // onig_is_code_in_cc_len
+    public boolean isCodeInCCLength(int code) {
+        boolean found;
+
+        if (code > 0xff) {
+            if (mbuf == null) {
+                found = false;
+            } else {
+                found = EncodingHelper.isInCodeRange(mbuf.getCodeRange(), code);
+            }
+        } else {
+            found = bs.at(code);
+        }
+
+        if (isNot()) {
+            return !found;
+        } else {
+            return found;
+        }
+    }
+
+    // onig_is_code_in_cc
+    public boolean isCodeInCC(int code) {
+         return isCodeInCCLength(code);
+    }
+
+    public void setNot() {
+        flags |= FLAG_NCCLASS_NOT;
+    }
+
+    public void clearNot() {
+        flags &= ~FLAG_NCCLASS_NOT;
+    }
+
+    public boolean isNot() {
+        return (flags & FLAG_NCCLASS_NOT) != 0;
+    }
+
+    public void setShare() {
+        flags |= FLAG_NCCLASS_SHARE;
+    }
+
+    public void clearShare() {
+        flags &= ~FLAG_NCCLASS_SHARE;
+    }
+
+    public boolean isShare() {
+        return (flags & FLAG_NCCLASS_SHARE) != 0;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CTypeNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CTypeNode.java
new file mode 100644
index 0000000..b03f990
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CTypeNode.java
@@ -0,0 +1,50 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+public final class CTypeNode extends Node {
+    public int ctype;
+    public boolean not;
+
+    public CTypeNode(int type, boolean not) {
+        this.ctype= type;
+        this.not = not;
+    }
+
+    @Override
+    public int getType() {
+        return CTYPE;
+    }
+
+    @Override
+    public String getName() {
+        return "Character Type";
+    }
+
+    @Override
+    public String toString(int level) {
+        StringBuilder value = new StringBuilder();
+        value.append("\n  ctype: " + ctype);
+        value.append("\n  not: " + not);
+
+        return value.toString();
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CallNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CallNode.java
new file mode 100644
index 0000000..361471b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CallNode.java
@@ -0,0 +1,86 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import java.util.Set;
+
+import jdk.nashorn.internal.runtime.regexp.joni.UnsetAddrList;
+import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
+
+public final class CallNode extends StateNode {
+    public char[] name;
+    public int nameP;
+    public int nameEnd;
+
+    public int groupNum;
+    public Node target;             // is it an EncloseNode always ?
+    public UnsetAddrList unsetAddrList;
+
+    public CallNode(char[] name, int nameP, int nameEnd, int gnum) {
+        this.name = name;
+        this.nameP = nameP;
+        this.nameEnd = nameEnd;
+        this.groupNum = gnum; /* call by number if gnum != 0 */
+    }
+
+    @Override
+    public int getType() {
+        return CALL;
+    }
+
+    @Override
+    protected void setChild(Node newChild) {
+        target = newChild;
+    }
+
+    @Override
+    protected Node getChild() {
+        return target;
+    }
+
+    public void setTarget(Node tgt) {
+        target = tgt;
+        tgt.parent = this;
+    }
+
+    @Override
+    public String getName() {
+        return "Call";
+    }
+
+    @Override
+    public void verifyTree(Set<Node> set, WarnCallback warnings) {
+        if (target == null || target.parent == this)
+            warnings.warn(this.getAddressName() + " doesn't point to a target or the target has been stolen");
+        // do not recurse here
+    }
+
+    @Override
+    public String toString(int level) {
+        StringBuilder value = new StringBuilder(super.toString(level));
+        value.append("\n  name: " + new String(name, nameP, nameEnd - nameP));
+        value.append("\n  groupNum: " + groupNum);
+        value.append("\n  target: " + pad(target.getAddressName(), level + 1));
+        value.append("\n  unsetAddrList: " + pad(unsetAddrList, level + 1));
+
+        return value.toString();
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/ConsAltNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/ConsAltNode.java
new file mode 100644
index 0000000..e8bcb30
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/ConsAltNode.java
@@ -0,0 +1,152 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import java.util.Set;
+
+import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+
+public final class ConsAltNode extends Node {
+    public Node car;
+    public ConsAltNode cdr;
+    private int type;           // List or Alt
+
+    private ConsAltNode(Node car, ConsAltNode cdr, int type) {
+        this.car = car;
+        if (car != null) car.parent = this;
+        this.cdr = cdr;
+        if (cdr != null) cdr.parent = this;
+
+        this.type = type;
+    }
+
+    public static ConsAltNode newAltNode(Node left, ConsAltNode right) {
+        return new ConsAltNode(left, right, ALT);
+    }
+
+    public static ConsAltNode newListNode(Node left, ConsAltNode right) {
+        return new ConsAltNode(left, right, LIST);
+    }
+
+    public static ConsAltNode listAdd(ConsAltNode list, Node x) {
+        ConsAltNode n = newListNode(x, null);
+
+        if (list != null) {
+            while (list.cdr != null) {
+                list = list.cdr;
+            }
+            list.setCdr(n);
+        }
+        return n;
+    }
+
+    public void toListNode() {
+        type = LIST;
+    }
+
+    public void toAltNode() {
+        type = ALT;
+    }
+
+    @Override
+    public int getType() {
+        return type;
+    }
+
+    @Override
+    protected void setChild(Node newChild) {
+        car = newChild;
+    }
+
+    @Override
+    protected Node getChild() {
+        return car;
+    }
+
+    @Override
+    public void swap(Node with) {
+        if (cdr != null) {
+            cdr.parent = with;
+            if (with instanceof ConsAltNode) {
+                ConsAltNode withCan = (ConsAltNode)with;
+                withCan.cdr.parent = this;
+                ConsAltNode tmp = cdr;
+                cdr = withCan.cdr;
+                withCan.cdr = tmp;
+            }
+        }
+        super.swap(with);
+    }
+
+    @Override
+    public void verifyTree(Set<Node> set, WarnCallback warnings) {
+        if (!set.contains(this)) {
+            set.add(this);
+            if (car != null) {
+                if (car.parent != this) {
+                    warnings.warn("broken list car: " + this.getAddressName() + " -> " +  car.getAddressName());
+                }
+                car.verifyTree(set,warnings);
+            }
+            if (cdr != null) {
+                if (cdr.parent != this) {
+                    warnings.warn("broken list cdr: " + this.getAddressName() + " -> " +  cdr.getAddressName());
+                }
+                cdr.verifyTree(set,warnings);
+            }
+        }
+    }
+
+    public Node setCar(Node ca) {
+        car = ca;
+        ca.parent = this;
+        return car;
+    }
+
+    public ConsAltNode setCdr(ConsAltNode cd) {
+        cdr = cd;
+        cd.parent = this;
+        return cdr;
+    }
+
+    @Override
+    public String getName() {
+        switch (type) {
+        case ALT:
+            return "Alt";
+        case LIST:
+            return "List";
+        default:
+            throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
+        }
+    }
+
+    @Override
+    public String toString(int level) {
+        StringBuilder value = new StringBuilder();
+        value.append("\n  car: " + pad(car, level + 1));
+        value.append("\n  cdr: " + (cdr == null ? "NULL" : cdr.toString()));
+
+        return value.toString();
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java
new file mode 100644
index 0000000..a60afb1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java
@@ -0,0 +1,151 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import jdk.nashorn.internal.runtime.regexp.joni.Config;
+import jdk.nashorn.internal.runtime.regexp.joni.Option;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
+
+public final class EncloseNode extends StateNode implements EncloseType {
+
+    public int type;                // enclose type
+    public int regNum;
+    public int option;
+    public Node target;             /* EncloseNode : ENCLOSE_MEMORY */
+    public int callAddr;            // AbsAddrType
+    public int minLength;           // OnigDistance
+    public int maxLength;           // OnigDistance
+    public int charLength;
+    public int optCount;            // referenced count in optimize_node_left()
+
+    // node_new_enclose / onig_node_new_enclose
+    public EncloseNode(int type) {
+        this.type = type;
+        callAddr = -1;
+    }
+
+    // node_new_enclose_memory
+    public EncloseNode(int option, boolean isNamed) {
+        this(MEMORY);
+        if (isNamed) setNamedGroup();
+        if (Config.USE_SUBEXP_CALL) this.option = option;
+    }
+
+    // node_new_option
+    public EncloseNode(int option, int i) {
+        this(OPTION);
+        this.option = option;
+    }
+
+    @Override
+    public int getType() {
+        return ENCLOSE;
+    }
+
+    @Override
+    protected void setChild(Node newChild) {
+        target = newChild;
+    }
+
+    @Override
+    protected Node getChild() {
+        return target;
+    }
+
+    public void setTarget(Node tgt) {
+        target = tgt;
+        tgt.parent = this;
+    }
+
+    @Override
+    public String getName() {
+        return "Enclose";
+    }
+
+    @Override
+    public String toString(int level) {
+        StringBuilder value = new StringBuilder(super.toString(level));
+        value.append("\n  type: " + typeToString());
+        value.append("\n  regNum: " + regNum);
+        value.append("\n  option: " + Option.toString(option));
+        value.append("\n  target: " + pad(target, level + 1));
+        value.append("\n  callAddr: " + callAddr);
+        value.append("\n  minLength: " + minLength);
+        value.append("\n  maxLength: " + maxLength);
+        value.append("\n  charLength: " + charLength);
+        value.append("\n  optCount: " + optCount);
+
+        return value.toString();
+    }
+
+    public String typeToString() {
+        StringBuilder types = new StringBuilder();
+        if (isStopBacktrack()) types.append("STOP_BACKTRACK ");
+        if (isMemory()) types.append("MEMORY ");
+        if (isOption()) types.append("OPTION ");
+
+        return types.toString();
+    }
+
+    public void setEncloseStatus(int flag) {
+        state |= flag;
+    }
+
+    public void clearEncloseStatus(int flag) {
+        state &= ~flag;
+    }
+
+    public void clearMemory() {
+        type &= ~MEMORY;
+    }
+
+    public void setMemory() {
+        type |= MEMORY;
+    }
+
+    public boolean isMemory() {
+        return (type & MEMORY) != 0;
+    }
+
+    public void clearOption() {
+        type &= ~OPTION;
+    }
+
+    public void setOption() {
+        type |= OPTION;
+    }
+
+    public boolean isOption() {
+        return (type & OPTION) != 0;
+    }
+
+    public void clearStopBacktrack() {
+        type &= ~STOP_BACKTRACK;
+    }
+
+    public void setStopBacktrack() {
+        type |= STOP_BACKTRACK;
+    }
+
+    public boolean isStopBacktrack() {
+        return (type & STOP_BACKTRACK) != 0;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/Node.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/Node.java
new file mode 100644
index 0000000..5bdf348
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/Node.java
@@ -0,0 +1,135 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import java.util.Set;
+
+import jdk.nashorn.internal.runtime.regexp.joni.Config;
+import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
+
+public abstract class Node implements NodeType {
+    public Node parent;
+
+    public abstract int getType();
+
+    public final int getType2Bit() {
+        return 1 << getType();
+    }
+
+    protected void setChild(Node tgt){}         // default definition
+    protected Node getChild(){return null;};    // default definition
+
+    public void swap(Node with) {
+        Node tmp;
+
+        //if (getChild() != null) getChild().parent = with;
+        //if (with.getChild() != null) with.getChild().parent = this;
+
+        //tmp = getChild();
+        //setChild(with.getChild());
+        //with.setChild(tmp);
+
+        if (parent != null) parent.setChild(with);
+
+        if (with.parent != null) with.parent.setChild(this);
+
+        tmp = parent;
+        parent = with.parent;
+        with.parent = tmp;
+    }
+
+    // overridden by ConsAltNode and CallNode
+    public void verifyTree(Set<Node> set, WarnCallback warnings) {
+        if (!set.contains(this) && getChild() != null) {
+            set.add(this);
+            if (getChild().parent != this) {
+                warnings.warn("broken link to child: " + this.getAddressName() + " -> " + getChild().getAddressName());
+            }
+            getChild().verifyTree(set, warnings);
+        }
+    }
+
+    public abstract String getName();
+    protected abstract String toString(int level);
+
+    public String getAddressName() {
+        return getName() + ":0x" + Integer.toHexString(System.identityHashCode(this));
+    }
+
+    public final String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("<" + getAddressName() + " (" + (parent == null ? "NULL" : parent.getAddressName())  + ")>");
+        return s + toString(0);
+    }
+
+    protected static String pad(Object value, int level) {
+        if (value == null) return "NULL";
+
+        StringBuilder pad = new StringBuilder("  ");
+        for (int i=0; i<level; i++) pad.append(pad);
+
+        return value.toString().replace("\n",  "\n" + pad);
+    }
+
+    public final boolean isInvalidQuantifier() {
+        if (!Config.VANILLA) return false;
+
+        ConsAltNode node;
+
+        switch(getType()) {
+
+        case ANCHOR:
+            return true;
+
+        case ENCLOSE:
+            /* allow enclosed elements */
+            /* return is_invalid_quantifier_target(NENCLOSE(node)->target); */
+            break;
+
+        case LIST:
+            node = (ConsAltNode)this;
+            do {
+                if (!node.car.isInvalidQuantifier()) return false;
+            } while ((node = node.cdr) != null);
+            return false;
+
+        case ALT:
+            node = (ConsAltNode)this;
+            do {
+                if (node.car.isInvalidQuantifier()) return true;
+            } while ((node = node.cdr) != null);
+            break;
+
+        default:
+            break;
+        }
+
+        return false;
+    }
+
+    public final boolean isAllowedInLookBehind() {
+        return (getType2Bit() & ALLOWED_IN_LB) != 0;
+    }
+
+    public final boolean isSimple() {
+        return (getType2Bit() & SIMPLE) != 0;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java
new file mode 100644
index 0000000..76a5868
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java
@@ -0,0 +1,272 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import jdk.nashorn.internal.runtime.regexp.joni.Config;
+import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
+
+public final class QuantifierNode extends StateNode {
+
+    public Node target;
+    public int lower;
+    public int upper;
+    public boolean greedy;
+
+    public int targetEmptyInfo;
+
+    public Node headExact;
+    public Node nextHeadExact;
+    public boolean isRefered;           /* include called node. don't eliminate even if {0} */
+
+    // USE_COMBINATION_EXPLOSION_CHECK
+    public int  combExpCheckNum;        /* 1,2,3...: check,  0: no check  */
+
+    public QuantifierNode(int lower, int upper, boolean byNumber) {
+        this.lower = lower;
+        this.upper = upper;
+        greedy = true;
+        targetEmptyInfo = TargetInfo.ISNOT_EMPTY;
+
+        if (byNumber) setByNumber();
+    }
+
+    @Override
+    public int getType() {
+        return QTFR;
+    }
+
+    @Override
+    protected void setChild(Node newChild) {
+        target = newChild;
+    }
+
+    @Override
+    protected Node getChild() {
+        return target;
+    }
+
+    public void setTarget(Node tgt) {
+        target = tgt;
+        tgt.parent = this;
+    }
+
+    public StringNode convertToString(int flag) {
+        StringNode sn = new StringNode();
+        sn.flag = flag;
+        sn.swap(this);
+        return sn;
+    }
+
+    @Override
+    public String getName() {
+        return "Quantifier";
+    }
+
+    @Override
+    public String toString(int level) {
+        StringBuilder value = new StringBuilder(super.toString(level));
+        value.append("\n  target: " + pad(target, level + 1));
+        value.append("\n  lower: " + lower);
+        value.append("\n  upper: " + upper);
+        value.append("\n  greedy: " + greedy);
+        value.append("\n  targetEmptyInfo: " + targetEmptyInfo);
+        value.append("\n  headExact: " + pad(headExact, level + 1));
+        value.append("\n  nextHeadExact: " + pad(nextHeadExact, level + 1));
+        value.append("\n  isRefered: " + isRefered);
+        value.append("\n  combExpCheckNum: " + combExpCheckNum);
+
+        return value.toString();
+    }
+
+    public boolean isAnyCharStar() {
+        return greedy && isRepeatInfinite(upper) && target.getType() == CANY;
+    }
+
+    /* ?:0, *:1, +:2, ??:3, *?:4, +?:5 */
+    protected int popularNum() {
+        if (greedy) {
+            if (lower == 0) {
+                if (upper == 1) return 0;
+                else if (isRepeatInfinite(upper)) return 1;
+            } else if (lower == 1) {
+                if (isRepeatInfinite(upper)) return 2;
+            }
+        } else {
+            if (lower == 0) {
+                if (upper == 1) return 3;
+                else if (isRepeatInfinite(upper)) return 4;
+            } else if (lower == 1) {
+                if (isRepeatInfinite(upper)) return 5;
+            }
+        }
+        return -1;
+    }
+
+    protected void set(QuantifierNode other) {
+        setTarget(other.target);
+        other.target = null;
+        lower = other.lower;
+        upper = other.upper;
+        greedy = other.greedy;
+        targetEmptyInfo = other.targetEmptyInfo;
+
+        //setHeadExact(other.headExact);
+        //setNextHeadExact(other.nextHeadExact);
+        headExact = other.headExact;
+        nextHeadExact = other.nextHeadExact;
+        isRefered = other.isRefered;
+        combExpCheckNum = other.combExpCheckNum;
+    }
+
+    public void reduceNestedQuantifier(QuantifierNode other) {
+        int pnum = popularNum();
+        int cnum = other.popularNum();
+
+        if (pnum < 0 || cnum < 0) return;
+
+        switch(Reduce.REDUCE_TABLE[cnum][pnum]) {
+        case DEL:
+            // no need to set the parent here...
+            // swap ?
+            set(other); // *pnode = *cnode; ???
+            break;
+
+        case A:
+            setTarget(other.target);
+            lower = 0;
+            upper = REPEAT_INFINITE;
+            greedy = true;
+            break;
+
+        case AQ:
+            setTarget(other.target);
+            lower = 0;
+            upper = REPEAT_INFINITE;
+            greedy = false;
+            break;
+
+        case QQ:
+            setTarget(other.target);
+            lower = 0;
+            upper = 1;
+            greedy = false;
+            break;
+
+        case P_QQ:
+            setTarget(other);
+            lower = 0;
+            upper = 1;
+            greedy = false;
+            other.lower = 1;
+            other.upper = REPEAT_INFINITE;
+            other.greedy = true;
+            return;
+
+        case PQ_Q:
+            setTarget(other);
+            lower = 0;
+            upper = 1;
+            greedy = true;
+            other.lower = 1;
+            other.upper = REPEAT_INFINITE;
+            other.greedy = false;
+            return;
+
+        case ASIS:
+            setTarget(other);
+            return;
+        }
+        // ??? remove the parent from target ???
+        other.target = null; // remove target from reduced quantifier
+    }
+
+    public int setQuantifier(Node tgt, boolean group, ScanEnvironment env, char[] chars, int p, int end) {
+        if (lower == 1 && upper == 1) return 1;
+
+        switch(tgt.getType()) {
+
+        case STR:
+            if (!group) {
+                StringNode sn = (StringNode)tgt;
+                if (sn.canBeSplit()) {
+                    StringNode n = sn.splitLastChar();
+                    if (n != null) {
+                        setTarget(n);
+                        return 2;
+                    }
+                }
+            }
+            break;
+
+        case QTFR:
+            /* check redundant double repeat. */
+            /* verbose warn (?:.?)? etc... but not warn (.?)? etc... */
+            QuantifierNode qnt = (QuantifierNode)tgt;
+            int nestQNum = popularNum();
+            int targetQNum = qnt.popularNum();
+
+            if (Config.USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR) {
+                if (!isByNumber() && !qnt.isByNumber() && env.syntax.warnReduntantNestedRepeat()) {
+                    switch(Reduce.REDUCE_TABLE[targetQNum][nestQNum]) {
+                    case ASIS:
+                        break;
+
+                    case DEL:
+                        env.reg.warnings.warn(new String(chars, p, end) +
+                                " redundant nested repeat operator");
+                        break;
+
+                    default:
+                        env.reg.warnings.warn(new String(chars, p, end) +
+                                " nested repeat operator " + Reduce.PopularQStr[targetQNum] +
+                                " and " + Reduce.PopularQStr[nestQNum] + " was replaced with '" +
+                                Reduce.ReduceQStr[Reduce.REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'");
+                    }
+                }
+            } // USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
+
+            if (targetQNum >= 0) {
+                if (nestQNum >= 0) {
+                    reduceNestedQuantifier(qnt);
+                    return 0;
+                } else if (targetQNum == 1 || targetQNum == 2) { /* * or + */
+                    /* (?:a*){n,m}, (?:a+){n,m} => (?:a*){n,n}, (?:a+){n,n} */
+                    if (!isRepeatInfinite(upper) && upper > 1 && greedy) {
+                        upper = lower == 0 ? 1 : lower;
+                    }
+                }
+            }
+
+        default:
+            break;
+        }
+
+        setTarget(tgt);
+        return 0;
+    }
+
+    public static final int REPEAT_INFINITE         = -1;
+    public static boolean isRepeatInfinite(int n) {
+        return n == REPEAT_INFINITE;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java
new file mode 100644
index 0000000..18101a4
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java
@@ -0,0 +1,232 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeStatus;
+
+public abstract class StateNode extends Node implements NodeStatus {
+    protected int state;
+
+    @Override
+    public String toString(int level) {
+        return "\n  state: " + stateToString();
+    }
+
+    public String stateToString() {
+        StringBuilder states = new StringBuilder();
+        if (isMinFixed()) states.append("MIN_FIXED ");
+        if (isMaxFixed()) states.append("MAX_FIXED ");
+        if (isMark1()) states.append("MARK1 ");
+        if (isMark2()) states.append("MARK2 ");
+        if (isMemBackrefed()) states.append("MEM_BACKREFED ");
+        if (isStopBtSimpleRepeat()) states.append("STOP_BT_SIMPLE_REPEAT ");
+        if (isRecursion()) states.append("RECURSION ");
+        if (isCalled()) states.append("CALLED ");
+        if (isAddrFixed()) states.append("ADDR_FIXED ");
+        if (isNamedGroup()) states.append("NAMED_GROUP ");
+        if (isNameRef()) states.append("NAME_REF ");
+        if (isInRepeat()) states.append("IN_REPEAT ");
+        if (isNestLevel()) states.append("NEST_LEVEL ");
+        if (isByNumber()) states.append("BY_NUMBER ");
+
+        return states.toString();
+    }
+
+    public boolean isMinFixed() {
+        return (state & NST_MIN_FIXED) != 0;
+    }
+
+    public void setMinFixed() {
+        state |= NST_MIN_FIXED;
+    }
+
+    public void clearMinFixed() {
+        state &= ~NST_MIN_FIXED;
+    }
+
+    public boolean isMaxFixed() {
+        return (state & NST_MAX_FIXED) != 0;
+    }
+
+    public void setMaxFixed() {
+        state |= NST_MAX_FIXED;
+    }
+
+    public void clearMaxFixed() {
+        state &= ~NST_MAX_FIXED;
+    }
+
+    public boolean isCLenFixed() {
+        return (state & NST_CLEN_FIXED) != 0;
+    }
+
+    public void setCLenFixed() {
+        state |= NST_CLEN_FIXED;
+    }
+
+    public void clearCLenFixed() {
+        state &= ~NST_CLEN_FIXED;
+    }
+
+    public boolean isMark1() {
+        return (state & NST_MARK1) != 0;
+    }
+
+    public void setMark1() {
+        state |= NST_MARK1;
+    }
+
+    public void clearMark1() {
+        state &= ~NST_MARK1;
+    }
+
+    public boolean isMark2() {
+        return (state & NST_MARK2) != 0;
+    }
+
+    public void setMark2() {
+        state |= NST_MARK2;
+    }
+
+    public void clearMark2() {
+        state &= ~NST_MARK2;
+    }
+
+    public boolean isMemBackrefed() {
+        return (state & NST_MEM_BACKREFED) != 0;
+    }
+
+    public void setMemBackrefed() {
+        state |= NST_MEM_BACKREFED;
+    }
+
+    public void clearMemBackrefed() {
+        state &= ~NST_MEM_BACKREFED;
+    }
+
+    public boolean isStopBtSimpleRepeat() {
+        return (state & NST_STOP_BT_SIMPLE_REPEAT) != 0;
+    }
+
+    public void setStopBtSimpleRepeat() {
+        state |= NST_STOP_BT_SIMPLE_REPEAT;
+    }
+
+    public void clearStopBtSimpleRepeat() {
+        state &= ~NST_STOP_BT_SIMPLE_REPEAT;
+    }
+
+    public boolean isRecursion() {
+        return (state & NST_RECURSION) != 0;
+    }
+
+    public void setRecursion() {
+        state |= NST_RECURSION;
+    }
+
+    public void clearRecursion() {
+        state &= ~NST_RECURSION;
+    }
+
+    public boolean isCalled() {
+        return (state & NST_CALLED) != 0;
+    }
+
+    public void setCalled() {
+        state |= NST_CALLED;
+    }
+
+    public void clearCAlled() {
+        state &= ~NST_CALLED;
+    }
+
+    public boolean isAddrFixed() {
+        return (state & NST_ADDR_FIXED) != 0;
+    }
+
+    public void setAddrFixed() {
+        state |= NST_ADDR_FIXED;
+    }
+
+    public void clearAddrFixed() {
+        state &= ~NST_ADDR_FIXED;
+    }
+
+    public boolean isNamedGroup() {
+        return (state & NST_NAMED_GROUP) != 0;
+    }
+
+    public void setNamedGroup() {
+        state |= NST_NAMED_GROUP;
+    }
+
+    public void clearNamedGroup() {
+        state &= ~NST_NAMED_GROUP;
+    }
+
+    public boolean isNameRef() {
+        return (state & NST_NAME_REF) != 0;
+    }
+
+    public void setNameRef() {
+        state |= NST_NAME_REF;
+    }
+
+    public void clearNameRef() {
+        state &= ~NST_NAME_REF;
+    }
+
+    public boolean isInRepeat() {
+        return (state & NST_IN_REPEAT) != 0;
+    }
+
+    public void setInRepeat() {
+        state |= NST_IN_REPEAT;
+    }
+
+    public void clearInRepeat() {
+        state &= ~NST_IN_REPEAT;
+    }
+
+    public boolean isNestLevel() {
+        return (state & NST_NEST_LEVEL) != 0;
+    }
+
+    public void setNestLevel() {
+        state |= NST_NEST_LEVEL;
+    }
+
+    public void clearNestLevel() {
+        state &= ~NST_NEST_LEVEL;
+    }
+
+    public boolean isByNumber() {
+        return (state & NST_BY_NUMBER) != 0;
+    }
+
+    public void setByNumber() {
+        state |= NST_BY_NUMBER;
+    }
+
+    public void clearByNumber() {
+        state &= ~NST_BY_NUMBER;
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StringNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StringNode.java
new file mode 100644
index 0000000..941b5c0
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StringNode.java
@@ -0,0 +1,207 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+import jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper;
+import jdk.nashorn.internal.runtime.regexp.joni.constants.StringType;
+
+public final class StringNode extends Node implements StringType {
+
+    private static final int NODE_STR_MARGIN = 16;
+    private static final int NODE_STR_BUF_SIZE = 24;
+    public static final StringNode EMPTY = new StringNode(null, Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+    public char[] chars;
+    public int p;
+    public int end;
+
+    public int flag;
+
+    public StringNode() {
+        this.chars = new char[NODE_STR_BUF_SIZE];
+    }
+
+    public StringNode(char[] chars, int p, int end) {
+        this.chars = chars;
+        this.p = p;
+        this.end = end;
+        setShared();
+    }
+
+    public StringNode(char c) {
+        this();
+        chars[end++] = c;
+    }
+
+    /* Ensure there is ahead bytes available in node's buffer
+     * (assumes that the node is not shared)
+     */
+    public void ensure(int ahead) {
+        int len = (end - p) + ahead;
+        if (len >= chars.length) {
+            char[] tmp = new char[len + NODE_STR_MARGIN];
+            System.arraycopy(chars, p, tmp, 0, end - p);
+            chars = tmp;
+        }
+    }
+
+    /* COW and/or ensure there is ahead bytes available in node's buffer
+     */
+    private void modifyEnsure(int ahead) {
+        if (isShared()) {
+            int len = (end - p) + ahead;
+            char[] tmp = new char[len + NODE_STR_MARGIN];
+            System.arraycopy(chars, p, tmp, 0, end - p);
+            chars = tmp;
+            end = end - p;
+            p = 0;
+            clearShared();
+        } else {
+            ensure(ahead);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return STR;
+    }
+
+    @Override
+    public String getName() {
+        return "String";
+    }
+
+    @Override
+    public String toString(int level) {
+        StringBuilder value = new StringBuilder();
+        value.append("\n  bytes: '");
+        for (int i=p; i<end; i++) {
+            if (chars[i] >= 0x20 && chars[i] < 0x7f) {
+                value.append(chars[i]);
+            } else {
+                value.append(String.format("[0x%04x]", chars[i]));
+            }
+        }
+        value.append("'");
+        return value.toString();
+    }
+
+    public int length() {
+        return end - p;
+    }
+
+    public StringNode splitLastChar() {
+        StringNode n = null;
+
+        if (end > p) {
+            int prev = EncodingHelper.prevCharHead(p, end);
+            if (prev != -1 && prev > p) { /* can be splitted. */
+                n = new StringNode(chars, prev, end);
+                if (isRaw()) n.setRaw();
+                end = prev;
+            }
+        }
+        return n;
+    }
+
+    public boolean canBeSplit() {
+        if (end > p) {
+            return 1 < (end - p);
+        }
+        return false;
+    }
+
+    public void set(char[] chars, int p, int end) {
+        this.chars = chars;
+        this.p = p;
+        this.end = end;
+        setShared();
+    }
+
+    public void cat(char[] cat, int catP, int catEnd) {
+        int len = catEnd - catP;
+        modifyEnsure(len);
+        System.arraycopy(cat, catP, chars, end, len);
+        end += len;
+    }
+
+    public void cat(char c) {
+        modifyEnsure(1);
+        chars[end++] = c;
+    }
+
+    public void catCode(int code) {
+        cat((char)code);
+    }
+
+    public void clear() {
+        if (chars.length > NODE_STR_BUF_SIZE) chars = new char[NODE_STR_BUF_SIZE];
+        flag = 0;
+        p = end = 0;
+    }
+
+    public void setRaw() {
+        flag |= NSTR_RAW;
+    }
+
+    public void clearRaw() {
+        flag &= ~NSTR_RAW;
+    }
+
+    public boolean isRaw() {
+        return (flag & NSTR_RAW) != 0;
+    }
+
+    public void setAmbig() {
+        flag |= NSTR_AMBIG;
+    }
+
+    public void clearAmbig() {
+        flag &= ~NSTR_AMBIG;
+    }
+
+    public boolean isAmbig() {
+        return (flag & NSTR_AMBIG) != 0;
+    }
+
+    public void setDontGetOptInfo() {
+        flag |= NSTR_DONT_GET_OPT_INFO;
+    }
+
+    public void clearDontGetOptInfo() {
+        flag &= ~NSTR_DONT_GET_OPT_INFO;
+    }
+
+    public boolean isDontGetOptInfo() {
+        return (flag & NSTR_DONT_GET_OPT_INFO) != 0;
+    }
+
+    public void setShared() {
+        flag |= NSTR_SHARED;
+    }
+
+    public void clearShared() {
+        flag &= ~NSTR_SHARED;
+    }
+
+    public boolean isShared() {
+        return (flag & NSTR_SHARED) != 0;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/AbstractBench.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/AbstractBench.java
new file mode 100644
index 0000000..9751b51
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/AbstractBench.java
@@ -0,0 +1,49 @@
+package jdk.nashorn.internal.runtime.regexp.joni.bench;
+
+import jdk.nashorn.internal.runtime.regexp.joni.Option;
+import jdk.nashorn.internal.runtime.regexp.joni.Regex;
+import jdk.nashorn.internal.runtime.regexp.joni.Syntax;
+
+public abstract class AbstractBench {
+    protected void bench(String _reg, String _str, int warmup, int times) throws Exception {
+        char[] reg = _reg.toCharArray();
+        char[] str = _str.toCharArray();
+
+        Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,Syntax.DEFAULT);
+
+        System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
+
+        for(int j=0;j<warmup;j++) {
+            long before = System.currentTimeMillis();
+            for(int i = 0; i < times; i++) {
+                p.matcher(str, 0, str.length).search(0, str.length, Option.NONE);
+            }
+            long time = System.currentTimeMillis() - before;
+            System.err.println(":  " + time + "ms");
+        }
+    }
+
+    protected void benchBestOf(String _reg, String _str, int warmup, int times) throws Exception {
+        char[] reg = _reg.toCharArray();
+        char[] str = _str.toCharArray();
+
+        Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,Syntax.DEFAULT);
+
+        System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
+
+        long best = Long.MAX_VALUE;
+
+        for(int j=0;j<warmup;j++) {
+            long before = System.currentTimeMillis();
+            for(int i = 0; i < times; i++) {
+                p.matcher(str, 0, str.length).search(0, str.length, Option.NONE);
+            }
+            long time = System.currentTimeMillis() - before;
+            if(time < best) {
+                best = time;
+            }
+            System.err.print(".");
+        }
+        System.err.println(":  " + best + "ms");
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchGreedyBacktrack.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchGreedyBacktrack.java
new file mode 100644
index 0000000..116352d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchGreedyBacktrack.java
@@ -0,0 +1,7 @@
+package jdk.nashorn.internal.runtime.regexp.joni.bench;
+
+public class BenchGreedyBacktrack extends AbstractBench {
+    public static void main(String[] args) throws Exception {
+        new BenchGreedyBacktrack().bench(".*_p","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,1000000);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchRailsRegs.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchRailsRegs.java
new file mode 100644
index 0000000..eb339af
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchRailsRegs.java
@@ -0,0 +1,31 @@
+package jdk.nashorn.internal.runtime.regexp.joni.bench;
+
+public class BenchRailsRegs extends AbstractBench {
+    public static void main(String[] args) throws Exception {
+        final String[][] regexps = {{"a.*?[b-z]{2,4}aaaaaa","afdgdsgderaabxxaaaaaaaaaaaaaaaaaaaaaaaa"},
+                                    {"://","/shop/viewCategory.shtml?category=DOGS"},
+                                    {"^\\w+\\://[^/]+(/.*|$)$","/shop/viewCategory.shtml?category=DOGS"},
+                                    {"\\A/?\\Z","/shop/viewCategory.shtml"},
+                                    {"\\A/shop/signonForm\\.shtml/?\\Z","/shop/viewCategory.shtml"},
+                                    {"\\A/shop/newAccountForm\\.shtml/?\\Z","/shop/viewCategory.shtml"},
+                                    {"\\A/shop/newAccount\\.shtml/?\\Z","/shop/viewCategory.shtml"},
+                                    {"\\A/shop/viewCart\\.shtml/?\\Z","/shop/viewCategory.shtml"},
+                                    {"\\A/shop/index\\.shtml/?\\Z","/shop/viewCategory.shtml"},
+                                    {"\\A/shop/viewCategory\\.shtml/?\\Z","/shop/viewCategory.shtml"},
+                                    {"\\A(?:::)?([A-Z]\\w*(?:::[A-Z]\\w*)*)\\z","CategoriesController"},
+                                    {"\\Ainsert","SELECT * FROM sessions WHERE (session_id = '1b341ffe23b5298676d535fcabd3d0d7')  LIMIT 1"},
+                                    {"\\A\\(?\\s*(select|show)","SELECT * FROM sessions WHERE (session_id = '1b341ffe23b5298676d535fcabd3d0d7')  LIMIT 1"},
+                                    {".*?\n","1b341ffe23b5298676d535fcabd3d0d7"},
+                                    {"^find_(all_by|by)_([_a-zA-Z]\\w*)$","find_by_string_id"},
+                                    {"\\.rjs$","categories/show.rhtml"},
+                                    {"^[-a-z]+://","petstore.css"},
+                                    {"^get$",""},
+                                    {"^post$",""},
+                                    {"^[^:]+","www.example.com"},
+                                    {"(=|\\?|_before_type_cast)$", "updated_on"},
+                                    {"^(.*?)=(.*?);","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/"}};
+        for(String[] reg : regexps) {
+            new BenchRailsRegs().benchBestOf(reg[0],reg[1],10,1000000);
+        }
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchSeveralRegexps.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchSeveralRegexps.java
new file mode 100644
index 0000000..3c118cf
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchSeveralRegexps.java
@@ -0,0 +1,17 @@
+package jdk.nashorn.internal.runtime.regexp.joni.bench;
+
+public class BenchSeveralRegexps extends AbstractBench {
+    public static void main(String[] args) throws Exception {
+        int BASE = 1000000;
+
+        new BenchSeveralRegexps().benchBestOf("a"," a",10,4*BASE);
+
+        new BenchSeveralRegexps().benchBestOf(".*?=","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,BASE);
+
+        new BenchSeveralRegexps().benchBestOf("^(.*?)=(.*?);","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,BASE);
+
+        new BenchSeveralRegexps().benchBestOf(".*_p","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,4*BASE);
+
+        new BenchSeveralRegexps().benchBestOf(".*=","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,4*BASE);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AnchorType.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AnchorType.java
new file mode 100644
index 0000000..d3e8ccb
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AnchorType.java
@@ -0,0 +1,58 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface AnchorType {
+    final int BEGIN_BUF         = (1<<0);
+    final int BEGIN_LINE        = (1<<1);
+    final int BEGIN_POSITION    = (1<<2);
+    final int END_BUF           = (1<<3);
+    final int SEMI_END_BUF      = (1<<4);
+    final int END_LINE          = (1<<5);
+
+    final int WORD_BOUND        = (1<<6);
+    final int NOT_WORD_BOUND    = (1<<7);
+    final int WORD_BEGIN        = (1<<8);
+    final int WORD_END          = (1<<9);
+    final int PREC_READ         = (1<<10);
+    final int PREC_READ_NOT     = (1<<11);
+    final int LOOK_BEHIND       = (1<<12);
+    final int LOOK_BEHIND_NOT   = (1<<13);
+
+    final int ANYCHAR_STAR      = (1<<14);   /* ".*" optimize info */
+    final int ANYCHAR_STAR_ML   = (1<<15);   /* ".*" optimize info (multi-line) */
+
+    final int ANYCHAR_STAR_MASK = (ANYCHAR_STAR | ANYCHAR_STAR_ML);
+    final int END_BUF_MASK      = (END_BUF | SEMI_END_BUF);
+
+    final int ALLOWED_IN_LB =     ( LOOK_BEHIND |
+                                    BEGIN_LINE |
+                                    END_LINE |
+                                    BEGIN_BUF |
+                                    BEGIN_POSITION );
+
+    final int ALLOWED_IN_LB_NOT = ( LOOK_BEHIND |
+                                    LOOK_BEHIND_NOT |
+                                    BEGIN_LINE |
+                                    END_LINE |
+                                    BEGIN_BUF |
+                                    BEGIN_POSITION );
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Arguments.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Arguments.java
new file mode 100644
index 0000000..543b170
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Arguments.java
@@ -0,0 +1,31 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface Arguments {
+    final int SPECIAL       = -1;
+    final int NON           = 0;
+    final int RELADDR       = 1;
+    final int ABSADDR       = 2;
+    final int LENGTH        = 3;
+    final int MEMNUM        = 4;
+    final int OPTION        = 5;
+    final int STATE_CHECK   = 6;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AsmConstants.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AsmConstants.java
new file mode 100644
index 0000000..afde761
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AsmConstants.java
@@ -0,0 +1,49 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface AsmConstants {
+    final int THIS = 0;
+
+    // argument indexes
+    final int RANGE             = 1;
+    final int SSTART            = 2;
+    final int SPREV             = 3;
+
+    // local var indexes
+    final int S                 = 4;            // current index
+    final int BYTES             = 5;            // string
+    final int LAST_INDEX        = BYTES + 1;
+
+    // frequently used field names (all ints)
+    final String STR            = "str";
+    final String END            = "end";
+    final String MSA_START      = "msaStart";
+    final String MSA_OPTONS     = "msaOptions";
+    final String MSA_BEST_LEN   = "msaBestLen";
+    final String MSA_BEST_S     = "msaBestS";
+    final String MSA_BEGIN      = "msaBegin";
+    final String MSA_END        = "msaEnd";
+
+    // generated field names
+    final String BITSET         = "bitset";
+    final String CODERANGE      = "range";
+    final String TEMPLATE       = "template";
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCSTATE.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCSTATE.java
new file mode 100644
index 0000000..6760b6a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCSTATE.java
@@ -0,0 +1,27 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public enum CCSTATE {
+    VALUE,
+    RANGE,
+    COMPLETE,
+    START
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCVALTYPE.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCVALTYPE.java
new file mode 100644
index 0000000..fa20a4c
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCVALTYPE.java
@@ -0,0 +1,26 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public enum CCVALTYPE {
+    SB,
+    CODE_POINT,
+    CLASS
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/EncloseType.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/EncloseType.java
new file mode 100644
index 0000000..88aba98
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/EncloseType.java
@@ -0,0 +1,29 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface EncloseType {
+    final int MEMORY                = 1<<0;
+    final int OPTION                = 1<<1;
+    final int STOP_BACKTRACK        = 1<<2;
+
+    final int ALLOWED_IN_LB         = MEMORY;
+    final int ALLOWED_IN_LB_NOT     = 0;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/MetaChar.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/MetaChar.java
new file mode 100644
index 0000000..2c9d338
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/MetaChar.java
@@ -0,0 +1,31 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface MetaChar {
+    final int ESCAPE            = 0;
+    final int ANYCHAR           = 1;
+    final int ANYTIME           = 2;
+    final int ZERO_OR_ONE_TIME  = 3;
+    final int ONE_OR_MORE_TIME  = 4;
+    final int ANYCHAR_ANYTIME   = 5;
+
+    final int INEFFECTIVE_META_CHAR = 0;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeStatus.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeStatus.java
new file mode 100644
index 0000000..ef983d7
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeStatus.java
@@ -0,0 +1,39 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface NodeStatus {
+    /* status bits */
+    final int NST_MIN_FIXED            = (1<<0);
+    final int NST_MAX_FIXED            = (1<<1);
+    final int NST_CLEN_FIXED           = (1<<2);
+    final int NST_MARK1                = (1<<3);
+    final int NST_MARK2                = (1<<4);
+    final int NST_MEM_BACKREFED        = (1<<5);
+    final int NST_STOP_BT_SIMPLE_REPEAT= (1<<6);
+    final int NST_RECURSION            = (1<<7);
+    final int NST_CALLED               = (1<<8);
+    final int NST_ADDR_FIXED           = (1<<9);
+    final int NST_NAMED_GROUP          = (1<<10);
+    final int NST_NAME_REF             = (1<<11);
+    final int NST_IN_REPEAT            = (1<<12);   /* STK_REPEAT is nested in stack. */
+    final int NST_NEST_LEVEL           = (1<<13);
+    final int NST_BY_NUMBER            = (1<<14);   /* {n,m} */
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeType.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeType.java
new file mode 100644
index 0000000..c3061ff
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeType.java
@@ -0,0 +1,66 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface NodeType {
+    /* node type */
+    final int  STR        = 0;
+    final int  CCLASS     = 1;
+    final int  CTYPE      = 2;
+    final int  CANY       = 3;
+    final int  BREF       = 4;
+    final int  QTFR       = 5;
+    final int  ENCLOSE    = 6;
+    final int  ANCHOR     = 7;
+    final int  LIST       = 8;
+    final int  ALT        = 9;
+    final int  CALL       = 10;
+
+    final int BIT_STR        = 1 << STR;
+    final int BIT_CCLASS     = 1 << CCLASS;
+    final int BIT_CTYPE      = 1 << CTYPE;
+    final int BIT_CANY       = 1 << CANY;
+    final int BIT_BREF       = 1 << BREF;
+    final int BIT_QTFR       = 1 << QTFR;
+    final int BIT_ENCLOSE    = 1 << ENCLOSE;
+    final int BIT_ANCHOR     = 1 << ANCHOR;
+    final int BIT_LIST       = 1 << LIST;
+    final int BIT_ALT        = 1 << ALT;
+    final int BIT_CALL       = 1 << CALL;
+
+    /* allowed node types in look-behind */
+    final int ALLOWED_IN_LB = ( BIT_LIST |
+                                BIT_ALT |
+                                BIT_STR |
+                                BIT_CCLASS |
+                                BIT_CTYPE |
+                                BIT_CANY |
+                                BIT_ANCHOR |
+                                BIT_ENCLOSE |
+                                BIT_QTFR |
+                                BIT_CALL );
+
+    final int SIMPLE =        ( BIT_STR |
+                                BIT_CCLASS |
+                                BIT_CTYPE |
+                                BIT_CANY |
+                                BIT_BREF);
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPCode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPCode.java
new file mode 100644
index 0000000..7f2c534
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPCode.java
@@ -0,0 +1,387 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+import jdk.nashorn.internal.runtime.regexp.joni.Config;
+
+public interface OPCode {
+    final int FINISH                        = 0;            /* matching process terminator (no more alternative) */
+    final int END                           = 1;            /* pattern code terminator (success end) */
+
+    final int EXACT1                        = 2;            /* single byte, N = 1 */
+    final int EXACT2                        = 3;            /* single byte, N = 2 */
+    final int EXACT3                        = 4;            /* single byte, N = 3 */
+    final int EXACT4                        = 5;            /* single byte, N = 4 */
+    final int EXACT5                        = 6;            /* single byte, N = 5 */
+    final int EXACTN                        = 7;            /* single byte */
+    final int EXACTMB2N1                    = 8;            /* mb-length = 2 N = 1 */
+    final int EXACTMB2N2                    = 9;            /* mb-length = 2 N = 2 */
+    final int EXACTMB2N3                    = 10;           /* mb-length = 2 N = 3 */
+    final int EXACTMB2N                     = 11;           /* mb-length = 2 */
+    final int EXACTMB3N                     = 12;           /* mb-length = 3 */
+    final int EXACTMBN                      = 13;           /* other length */
+
+    final int EXACT1_IC                     = 14;           /* single byte, N = 1, ignore case */
+    final int EXACTN_IC                     = 15;           /* single byte,        ignore case */
+
+    final int CCLASS                        = 16;
+    final int CCLASS_MB                     = 17;
+    final int CCLASS_MIX                    = 18;
+    final int CCLASS_NOT                    = 19;
+    final int CCLASS_MB_NOT                 = 20;
+    final int CCLASS_MIX_NOT                = 21;
+    final int CCLASS_NODE                   = 22;           /* pointer to CClassNode node */
+
+    final int ANYCHAR                       = 23;           /* "."  */
+    final int ANYCHAR_ML                    = 24;           /* "."  multi-line */
+    final int ANYCHAR_STAR                  = 25;           /* ".*" */
+    final int ANYCHAR_ML_STAR               = 26;           /* ".*" multi-line */
+    final int ANYCHAR_STAR_PEEK_NEXT        = 27;
+    final int ANYCHAR_ML_STAR_PEEK_NEXT     = 28;
+
+    final int WORD                          = 29;
+    final int NOT_WORD                      = 30;
+    final int WORD_BOUND                    = 31;
+    final int NOT_WORD_BOUND                = 32;
+    final int WORD_BEGIN                    = 33;
+    final int WORD_END                      = 34;
+
+    final int BEGIN_BUF                     = 35;
+    final int END_BUF                       = 36;
+    final int BEGIN_LINE                    = 37;
+    final int END_LINE                      = 38;
+    final int SEMI_END_BUF                  = 39;
+    final int BEGIN_POSITION                = 40;
+
+    final int BACKREF1                      = 41;
+    final int BACKREF2                      = 42;
+    final int BACKREFN                      = 43;
+    final int BACKREFN_IC                   = 44;
+    final int BACKREF_MULTI                 = 45;
+    final int BACKREF_MULTI_IC              = 46;
+    final int BACKREF_WITH_LEVEL            = 47;           /* \k<xxx+n>, \k<xxx-n> */
+
+    final int MEMORY_START                  = 48;
+    final int MEMORY_START_PUSH             = 49;           /* push back-tracker to stack */
+    final int MEMORY_END_PUSH               = 50;           /* push back-tracker to stack */
+    final int MEMORY_END_PUSH_REC           = 51;           /* push back-tracker to stack */
+    final int MEMORY_END                    = 52;
+    final int MEMORY_END_REC                = 53;           /* push marker to stack */
+
+    final int FAIL                          = 54;           /* pop stack and move */
+    final int JUMP                          = 55;
+    final int PUSH                          = 56;
+    final int POP                           = 57;
+    final int PUSH_OR_JUMP_EXACT1           = 58;           /* if match exact then push, else jump. */
+    final int PUSH_IF_PEEK_NEXT             = 59;           /* if match exact then push, else none. */
+
+    final int REPEAT                        = 60;           /* {n,m} */
+    final int REPEAT_NG                     = 61;           /* {n,m}? (non greedy) */
+    final int REPEAT_INC                    = 62;
+    final int REPEAT_INC_NG                 = 63;           /* non greedy */
+    final int REPEAT_INC_SG                 = 64;           /* search and get in stack */
+    final int REPEAT_INC_NG_SG              = 65;           /* search and get in stack (non greedy) */
+
+    final int NULL_CHECK_START              = 66;           /* null loop checker start */
+    final int NULL_CHECK_END                = 67;           /* null loop checker end   */
+    final int NULL_CHECK_END_MEMST          = 68;           /* null loop checker end (with capture status) */
+    final int NULL_CHECK_END_MEMST_PUSH     = 69;           /* with capture status and push check-end */
+
+    final int PUSH_POS                      = 70;           /* (?=...)  start */
+    final int POP_POS                       = 71;           /* (?=...)  end   */
+    final int PUSH_POS_NOT                  = 72;           /* (?!...)  start */
+    final int FAIL_POS                      = 73;           /* (?!...)  end   */
+    final int PUSH_STOP_BT                  = 74;           /* (?>...)  start */
+    final int POP_STOP_BT                   = 75;           /* (?>...)  end   */
+    final int LOOK_BEHIND                   = 76;           /* (?<=...) start (no needs end opcode) */
+    final int PUSH_LOOK_BEHIND_NOT          = 77;           /* (?<!...) start */
+    final int FAIL_LOOK_BEHIND_NOT          = 78;           /* (?<!...) end   */
+
+    final int CALL                          = 79;           /* \g<name> */
+    final int RETURN                        = 80;
+
+    final int STATE_CHECK_PUSH              = 81;           /* combination explosion check and push */
+    final int STATE_CHECK_PUSH_OR_JUMP      = 82;           /* check ok -> push, else jump  */
+    final int STATE_CHECK                   = 83;           /* check only */
+    final int STATE_CHECK_ANYCHAR_STAR      = 84;
+    final int STATE_CHECK_ANYCHAR_ML_STAR   = 85;
+
+      /* no need: IS_DYNAMIC_OPTION() == 0 */
+    final int SET_OPTION_PUSH               = 86;           /* set option and push recover option */
+    final int SET_OPTION                    = 87;           /* set option */
+
+    // single byte versions
+    final int ANYCHAR_SB                    = 88;           /* "."  */
+    final int ANYCHAR_ML_SB                 = 89;           /* "."  multi-line */
+    final int ANYCHAR_STAR_SB               = 90;           /* ".*" */
+    final int ANYCHAR_ML_STAR_SB            = 91;           /* ".*" multi-line */
+    final int ANYCHAR_STAR_PEEK_NEXT_SB     = 92;
+    final int ANYCHAR_ML_STAR_PEEK_NEXT_SB  = 93;
+    final int STATE_CHECK_ANYCHAR_STAR_SB   = 94;
+    final int STATE_CHECK_ANYCHAR_ML_STAR_SB= 95;
+
+    final int CCLASS_SB                     = 96;
+    final int CCLASS_NOT_SB                 = 97;
+    final int WORD_SB                       = 98;
+    final int NOT_WORD_SB                   = 99;
+    final int WORD_BOUND_SB                 = 100;
+    final int NOT_WORD_BOUND_SB             = 101;
+    final int WORD_BEGIN_SB                 = 102;
+    final int WORD_END_SB                   = 103;
+
+    final int LOOK_BEHIND_SB                = 104;
+
+    final int EXACT1_IC_SB                  = 105;           /* single byte, N = 1, ignore case */
+    final int EXACTN_IC_SB                  = 106;           /* single byte,        ignore case */
+
+
+    public final String OpCodeNames[] = Config.DEBUG_COMPILE ? new String[] {
+        "finish", /*OP_FINISH*/
+        "end", /*OP_END*/
+        "exact1", /*OP_EXACT1*/
+        "exact2", /*OP_EXACT2*/
+        "exact3", /*OP_EXACT3*/
+        "exact4", /*OP_EXACT4*/
+        "exact5", /*OP_EXACT5*/
+        "exactn", /*OP_EXACTN*/
+        "exactmb2-n1", /*OP_EXACTMB2N1*/
+        "exactmb2-n2", /*OP_EXACTMB2N2*/
+        "exactmb2-n3", /*OP_EXACTMB2N3*/
+        "exactmb2-n", /*OP_EXACTMB2N*/
+        "exactmb3n", /*OP_EXACTMB3N*/
+        "exactmbn", /*OP_EXACTMBN*/
+        "exact1-ic", /*OP_EXACT1_IC*/
+        "exactn-ic", /*OP_EXACTN_IC*/
+        "cclass", /*OP_CCLASS*/
+        "cclass-mb", /*OP_CCLASS_MB*/
+        "cclass-mix", /*OP_CCLASS_MIX*/
+        "cclass-not", /*OP_CCLASS_NOT*/
+        "cclass-mb-not", /*OP_CCLASS_MB_NOT*/
+        "cclass-mix-not", /*OP_CCLASS_MIX_NOT*/
+        "cclass-node", /*OP_CCLASS_NODE*/
+        "anychar", /*OP_ANYCHAR*/
+        "anychar-ml", /*OP_ANYCHAR_ML*/
+        "anychar*", /*OP_ANYCHAR_STAR*/
+        "anychar-ml*", /*OP_ANYCHAR_ML_STAR*/
+        "anychar*-peek-next", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
+        "anychar-ml*-peek-next", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
+        "word", /*OP_WORD*/
+        "not-word", /*OP_NOT_WORD*/
+        "word-bound", /*OP_WORD_BOUND*/
+        "not-word-bound", /*OP_NOT_WORD_BOUND*/
+        "word-begin", /*OP_WORD_BEGIN*/
+        "word-end", /*OP_WORD_END*/
+        "begin-buf", /*OP_BEGIN_BUF*/
+        "end-buf", /*OP_END_BUF*/
+        "begin-line", /*OP_BEGIN_LINE*/
+        "end-line", /*OP_END_LINE*/
+        "semi-end-buf", /*OP_SEMI_END_BUF*/
+        "begin-position", /*OP_BEGIN_POSITION*/
+        "backref1", /*OP_BACKREF1*/
+        "backref2", /*OP_BACKREF2*/
+        "backrefn", /*OP_BACKREFN*/
+        "backrefn-ic", /*OP_BACKREFN_IC*/
+        "backref_multi", /*OP_BACKREF_MULTI*/
+        "backref_multi-ic", /*OP_BACKREF_MULTI_IC*/
+        "backref_at_level", /*OP_BACKREF_AT_LEVEL*/
+        "mem-start", /*OP_MEMORY_START*/
+        "mem-start-push", /*OP_MEMORY_START_PUSH*/
+        "mem-end-push", /*OP_MEMORY_END_PUSH*/
+        "mem-end-push-rec", /*OP_MEMORY_END_PUSH_REC*/
+        "mem-end", /*OP_MEMORY_END*/
+        "mem-end-rec", /*OP_MEMORY_END_REC*/
+        "fail", /*OP_FAIL*/
+        "jump", /*OP_JUMP*/
+        "push", /*OP_PUSH*/
+        "pop", /*OP_POP*/
+        "push-or-jump-e1", /*OP_PUSH_OR_JUMP_EXACT1*/
+        "push-if-peek-next", /*OP_PUSH_IF_PEEK_NEXT*/
+        "repeat", /*OP_REPEAT*/
+        "repeat-ng", /*OP_REPEAT_NG*/
+        "repeat-inc", /*OP_REPEAT_INC*/
+        "repeat-inc-ng", /*OP_REPEAT_INC_NG*/
+        "repeat-inc-sg", /*OP_REPEAT_INC_SG*/
+        "repeat-inc-ng-sg", /*OP_REPEAT_INC_NG_SG*/
+        "null-check-start", /*OP_NULL_CHECK_START*/
+        "null-check-end", /*OP_NULL_CHECK_END*/
+        "null-check-end-memst", /*OP_NULL_CHECK_END_MEMST*/
+        "null-check-end-memst-push", /*OP_NULL_CHECK_END_MEMST_PUSH*/
+        "push-pos", /*OP_PUSH_POS*/
+        "pop-pos", /*OP_POP_POS*/
+        "push-pos-not", /*OP_PUSH_POS_NOT*/
+        "fail-pos", /*OP_FAIL_POS*/
+        "push-stop-bt", /*OP_PUSH_STOP_BT*/
+        "pop-stop-bt", /*OP_POP_STOP_BT*/
+        "look-behind", /*OP_LOOK_BEHIND*/
+        "push-look-behind-not", /*OP_PUSH_LOOK_BEHIND_NOT*/
+        "fail-look-behind-not", /*OP_FAIL_LOOK_BEHIND_NOT*/
+        "call", /*OP_CALL*/
+        "return", /*OP_RETURN*/
+        "state-check-push", /*OP_STATE_CHECK_PUSH*/
+        "state-check-push-or-jump", /*OP_STATE_CHECK_PUSH_OR_JUMP*/
+        "state-check", /*OP_STATE_CHECK*/
+        "state-check-anychar*", /*OP_STATE_CHECK_ANYCHAR_STAR*/
+        "state-check-anychar-ml*", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
+        "set-option-push", /*OP_SET_OPTION_PUSH*/
+        "set-option", /*OP_SET_OPTION*/
+
+        // single byte versions
+        "anychar-sb", /*OP_ANYCHAR*/
+        "anychar-ml-sb", /*OP_ANYCHAR_ML*/
+        "anychar*-sb", /*OP_ANYCHAR_STAR*/
+        "anychar-ml*-sb", /*OP_ANYCHAR_ML_STAR*/
+        "anychar*-peek-next-sb", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
+        "anychar-ml*-peek-next-sb", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
+        "state-check-anychar*-sb", /*OP_STATE_CHECK_ANYCHAR_STAR*/
+        "state-check-anychar-ml*-sb", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
+
+        "cclass-sb", /*OP_CCLASS*/
+        "cclass-not-sb", /*OP_CCLASS_NOT*/
+
+        "word-sb", /*OP_WORD*/
+        "not-word-sb", /*OP_NOT_WORD*/
+        "word-bound-sb", /*OP_WORD_BOUND*/
+        "not-word-bound-sb", /*OP_NOT_WORD_BOUND*/
+        "word-begin-sb", /*OP_WORD_BEGIN*/
+        "word-end-sb", /*OP_WORD_END*/
+
+        "look-behind-sb", /*OP_LOOK_BEHIND*/
+
+        "exact1-ic-sb", /*OP_EXACT1_IC*/
+        "exactn-ic-sb", /*OP_EXACTN_IC*/
+
+    } : null;
+
+    public final int OpCodeArgTypes[] = Config.DEBUG_COMPILE ? new int[] {
+        Arguments.NON, /*OP_FINISH*/
+        Arguments.NON, /*OP_END*/
+        Arguments.SPECIAL, /*OP_EXACT1*/
+        Arguments.SPECIAL, /*OP_EXACT2*/
+        Arguments.SPECIAL, /*OP_EXACT3*/
+        Arguments.SPECIAL, /*OP_EXACT4*/
+        Arguments.SPECIAL, /*OP_EXACT5*/
+        Arguments.SPECIAL, /*OP_EXACTN*/
+        Arguments.SPECIAL, /*OP_EXACTMB2N1*/
+        Arguments.SPECIAL, /*OP_EXACTMB2N2*/
+        Arguments.SPECIAL, /*OP_EXACTMB2N3*/
+        Arguments.SPECIAL, /*OP_EXACTMB2N*/
+        Arguments.SPECIAL, /*OP_EXACTMB3N*/
+        Arguments.SPECIAL, /*OP_EXACTMBN*/
+        Arguments.SPECIAL, /*OP_EXACT1_IC*/
+        Arguments.SPECIAL, /*OP_EXACTN_IC*/
+        Arguments.SPECIAL, /*OP_CCLASS*/
+        Arguments.SPECIAL, /*OP_CCLASS_MB*/
+        Arguments.SPECIAL, /*OP_CCLASS_MIX*/
+        Arguments.SPECIAL, /*OP_CCLASS_NOT*/
+        Arguments.SPECIAL, /*OP_CCLASS_MB_NOT*/
+        Arguments.SPECIAL, /*OP_CCLASS_MIX_NOT*/
+        Arguments.SPECIAL, /*OP_CCLASS_NODE*/
+        Arguments.NON, /*OP_ANYCHAR*/
+        Arguments.NON, /*OP_ANYCHAR_ML*/
+        Arguments.NON, /*OP_ANYCHAR_STAR*/
+        Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
+        Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
+        Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
+        Arguments.NON, /*OP_WORD*/
+        Arguments.NON, /*OP_NOT_WORD*/
+        Arguments.NON, /*OP_WORD_BOUND*/
+        Arguments.NON, /*OP_NOT_WORD_BOUND*/
+        Arguments.NON, /*OP_WORD_BEGIN*/
+        Arguments.NON, /*OP_WORD_END*/
+        Arguments.NON, /*OP_BEGIN_BUF*/
+        Arguments.NON, /*OP_END_BUF*/
+        Arguments.NON, /*OP_BEGIN_LINE*/
+        Arguments.NON, /*OP_END_LINE*/
+        Arguments.NON, /*OP_SEMI_END_BUF*/
+        Arguments.NON, /*OP_BEGIN_POSITION*/
+        Arguments.NON, /*OP_BACKREF1*/
+        Arguments.NON, /*OP_BACKREF2*/
+        Arguments.MEMNUM, /*OP_BACKREFN*/
+        Arguments.SPECIAL, /*OP_BACKREFN_IC*/
+        Arguments.SPECIAL, /*OP_BACKREF_MULTI*/
+        Arguments.SPECIAL, /*OP_BACKREF_MULTI_IC*/
+        Arguments.SPECIAL, /*OP_BACKREF_AT_LEVEL*/
+        Arguments.MEMNUM, /*OP_MEMORY_START*/
+        Arguments.MEMNUM, /*OP_MEMORY_START_PUSH*/
+        Arguments.MEMNUM, /*OP_MEMORY_END_PUSH*/
+        Arguments.MEMNUM, /*OP_MEMORY_END_PUSH_REC*/
+        Arguments.MEMNUM, /*OP_MEMORY_END*/
+        Arguments.MEMNUM, /*OP_MEMORY_END_REC*/
+        Arguments.NON, /*OP_FAIL*/
+        Arguments.RELADDR, /*OP_JUMP*/
+        Arguments.RELADDR, /*OP_PUSH*/
+        Arguments.NON, /*OP_POP*/
+        Arguments.SPECIAL, /*OP_PUSH_OR_JUMP_EXACT1*/
+        Arguments.SPECIAL, /*OP_PUSH_IF_PEEK_NEXT*/
+        Arguments.SPECIAL, /*OP_REPEAT*/
+        Arguments.SPECIAL, /*OP_REPEAT_NG*/
+        Arguments.MEMNUM, /*OP_REPEAT_INC*/
+        Arguments.MEMNUM, /*OP_REPEAT_INC_NG*/
+        Arguments.MEMNUM, /*OP_REPEAT_INC_SG*/
+        Arguments.MEMNUM, /*OP_REPEAT_INC_NG_SG*/
+        Arguments.MEMNUM, /*OP_NULL_CHECK_START*/
+        Arguments.MEMNUM, /*OP_NULL_CHECK_END*/
+        Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST*/
+        Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST_PUSH*/
+        Arguments.NON, /*OP_PUSH_POS*/
+        Arguments.NON, /*OP_POP_POS*/
+        Arguments.RELADDR, /*OP_PUSH_POS_NOT*/
+        Arguments.NON, /*OP_FAIL_POS*/
+        Arguments.NON, /*OP_PUSH_STOP_BT*/
+        Arguments.NON, /*OP_POP_STOP_BT*/
+        Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
+        Arguments.SPECIAL, /*OP_PUSH_LOOK_BEHIND_NOT*/
+        Arguments.NON, /*OP_FAIL_LOOK_BEHIND_NOT*/
+        Arguments.ABSADDR, /*OP_CALL*/
+        Arguments.NON, /*OP_RETURN*/
+        Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH*/
+        Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH_OR_JUMP*/
+        Arguments.STATE_CHECK, /*OP_STATE_CHECK*/
+        Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
+        Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
+        Arguments.OPTION, /*OP_SET_OPTION_PUSH*/
+        Arguments.OPTION, /*OP_SET_OPTION*/
+
+        // single byte versions
+        Arguments.NON, /*OP_ANYCHAR*/
+        Arguments.NON, /*OP_ANYCHAR_ML*/
+        Arguments.NON, /*OP_ANYCHAR_STAR*/
+        Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
+        Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
+        Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
+        Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
+        Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
+
+        Arguments.SPECIAL, /*OP_CCLASS*/
+        Arguments.SPECIAL, /*OP_CCLASS_NOT*/
+
+        Arguments.NON, /*OP_WORD*/
+        Arguments.NON, /*OP_NOT_WORD*/
+        Arguments.NON, /*OP_WORD_BOUND*/
+        Arguments.NON, /*OP_NOT_WORD_BOUND*/
+        Arguments.NON, /*OP_WORD_BEGIN*/
+        Arguments.NON, /*OP_WORD_END*/
+
+        Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
+
+        Arguments.SPECIAL, /*OP_EXACT1_IC*/
+        Arguments.SPECIAL, /*OP_EXACTN_IC*/
+    } : null;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPSize.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPSize.java
new file mode 100644
index 0000000..c0a8b14
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPSize.java
@@ -0,0 +1,76 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface OPSize {
+
+    // this might be helpful for potential byte[] migration
+    final int OPCODE                = 1;
+    final int RELADDR               = 1;
+    final int ABSADDR               = 1;
+    final int LENGTH                = 1;
+    final int MEMNUM                = 1;
+    final int STATE_CHECK_NUM       = 1;
+    final int REPEATNUM             = 1;
+    final int OPTION                = 1;
+    final int CODE_POINT            = 1;
+    final int POINTER               = 1;
+    final int INDEX                 = 1;
+
+    /* op-code + arg size */
+
+    final int ANYCHAR_STAR                  = OPCODE;
+    final int ANYCHAR_STAR_PEEK_NEXT        = (OPCODE + 1);
+    final int JUMP                          = (OPCODE + RELADDR);
+    final int PUSH                          = (OPCODE + RELADDR);
+    final int POP                           = OPCODE;
+    final int PUSH_OR_JUMP_EXACT1           = (OPCODE + RELADDR + 1);
+    final int PUSH_IF_PEEK_NEXT             = (OPCODE + RELADDR + 1);
+    final int REPEAT_INC                    = (OPCODE + MEMNUM);
+    final int REPEAT_INC_NG                 = (OPCODE + MEMNUM);
+    final int PUSH_POS                      = OPCODE;
+    final int PUSH_POS_NOT                  = (OPCODE + RELADDR);
+    final int POP_POS                       = OPCODE;
+    final int FAIL_POS                      = OPCODE;
+    final int SET_OPTION                    = (OPCODE + OPTION);
+    final int SET_OPTION_PUSH               = (OPCODE + OPTION);
+    final int FAIL                          = OPCODE;
+    final int MEMORY_START                  = (OPCODE + MEMNUM);
+    final int MEMORY_START_PUSH             = (OPCODE + MEMNUM);
+    final int MEMORY_END_PUSH               = (OPCODE + MEMNUM);
+    final int MEMORY_END_PUSH_REC           = (OPCODE + MEMNUM);
+    final int MEMORY_END                    = (OPCODE + MEMNUM);
+    final int MEMORY_END_REC                = (OPCODE + MEMNUM);
+    final int PUSH_STOP_BT                  = OPCODE;
+    final int POP_STOP_BT                   = OPCODE;
+    final int NULL_CHECK_START              = (OPCODE + MEMNUM);
+    final int NULL_CHECK_END                = (OPCODE + MEMNUM);
+    final int LOOK_BEHIND                   = (OPCODE + LENGTH);
+    final int PUSH_LOOK_BEHIND_NOT          = (OPCODE + RELADDR + LENGTH);
+    final int FAIL_LOOK_BEHIND_NOT          = OPCODE;
+    final int CALL                          = (OPCODE + ABSADDR);
+    final int RETURN                        = OPCODE;
+
+    // #ifdef USE_COMBINATION_EXPLOSION_CHECK
+    final int STATE_CHECK                   = (OPCODE + STATE_CHECK_NUM);
+    final int STATE_CHECK_PUSH              = (OPCODE + STATE_CHECK_NUM + RELADDR);
+    final int STATE_CHECK_PUSH_OR_JUMP      = (OPCODE + STATE_CHECK_NUM + RELADDR);
+    final int STATE_CHECK_ANYCHAR_STAR      = (OPCODE + STATE_CHECK_NUM);
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Reduce.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Reduce.java
new file mode 100644
index 0000000..a906e84
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Reduce.java
@@ -0,0 +1,61 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.A;
+import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.AQ;
+import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.ASIS;
+import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.DEL;
+import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.PQ_Q;
+import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.P_QQ;
+import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.QQ;
+
+public interface Reduce {
+
+    enum ReduceType {
+        ASIS,       /* as is */
+        DEL,        /* delete parent */
+        A,          /* to '*'    */
+        AQ,         /* to '*?'   */
+        QQ,         /* to '??'   */
+        P_QQ,       /* to '+)??' */
+        PQ_Q,       /* to '+?)?' */
+    }
+
+    final ReduceType[][]REDUCE_TABLE = {
+      {DEL,     A,      A,      QQ,     AQ,     ASIS}, /* '?'  */
+      {DEL,     DEL,    DEL,    P_QQ,   P_QQ,   DEL},  /* '*'  */
+      {A,       A,      DEL,    ASIS,   P_QQ,   DEL},  /* '+'  */
+      {DEL,     AQ,     AQ,     DEL,    AQ,     AQ},   /* '??' */
+      {DEL,     DEL,    DEL,    DEL,    DEL,    DEL},  /* '*?' */
+      {ASIS,    PQ_Q,   DEL,    AQ,     AQ,     DEL}   /* '+?' */
+    };
+
+
+    final String PopularQStr[] = new String[] {
+        "?", "*", "+", "??", "*?", "+?"
+    };
+
+    String ReduceQStr[]= new String[] {
+        "", "", "*", "*?", "??", "+ and ??", "+? and ?"
+    };
+
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/RegexState.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/RegexState.java
new file mode 100644
index 0000000..dd3bd6d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/RegexState.java
@@ -0,0 +1,28 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+// we dont need this ATM
+public interface RegexState {
+    final int NORMAL          = 0;
+    final int SEARCHING       = 1;
+    final int COMPILING       = -1;
+    final int MODIFY          = -2;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackPopLevel.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackPopLevel.java
new file mode 100644
index 0000000..efe7e4f
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackPopLevel.java
@@ -0,0 +1,27 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface StackPopLevel {
+    final int FREE      = 0;
+    final int MEM_START = 1;
+    final int ALL       = 2;
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackType.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackType.java
new file mode 100644
index 0000000..0e0ebc6
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackType.java
@@ -0,0 +1,51 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface StackType {
+    /** stack **/
+    final int INVALID_STACK_INDEX           = -1;
+
+    /* stack type */
+    /* used by normal-POP */
+    final int ALT                           = 0x0001;
+    final int LOOK_BEHIND_NOT               = 0x0002;
+    final int POS_NOT                       = 0x0003;
+    /* handled by normal-POP */
+    final int MEM_START                     = 0x0100;
+    final int MEM_END                       = 0x8200;
+    final int REPEAT_INC                    = 0x0300;
+    final int STATE_CHECK_MARK              = 0x1000;
+    /* avoided by normal-POP */
+    final int NULL_CHECK_START              = 0x3000;
+    final int NULL_CHECK_END                = 0x5000;  /* for recursive call */
+    final int MEM_END_MARK                  = 0x8400;
+    final int POS                           = 0x0500;  /* used when POP-POS */
+    final int STOP_BT                       = 0x0600;  /* mark for "(?>...)" */
+    final int REPEAT                        = 0x0700;
+    final int CALL_FRAME                    = 0x0800;
+    final int RETURN                        = 0x0900;
+    final int VOID                          = 0x0a00;  /* for fill a blank */
+
+    /* stack type check mask */
+    final int MASK_POP_USED                 = 0x00ff;
+    final int MASK_TO_VOID_TARGET           = 0x10ff;
+    final int MASK_MEM_END_OR_MARK          = 0x8000;  /* MEM_END or MEM_END_MARK */
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StringType.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StringType.java
new file mode 100644
index 0000000..d16c93e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StringType.java
@@ -0,0 +1,27 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface StringType {
+    final int NSTR_RAW               = 1<<0;
+    final int NSTR_AMBIG             = 1<<1;
+    final int NSTR_DONT_GET_OPT_INFO = 1<<2;
+    final int NSTR_SHARED            = 1<<3;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/SyntaxProperties.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/SyntaxProperties.java
new file mode 100644
index 0000000..3da439a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/SyntaxProperties.java
@@ -0,0 +1,124 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface SyntaxProperties {
+    /* syntax (operators); */
+    final int OP_VARIABLE_META_CHARACTERS    = (1<<0);
+    final int OP_DOT_ANYCHAR                 = (1<<1);   /* . */
+    final int OP_ASTERISK_ZERO_INF           = (1<<2);   /* * */
+    final int OP_ESC_ASTERISK_ZERO_INF       = (1<<3);
+    final int OP_PLUS_ONE_INF                = (1<<4);   /* + */
+    final int OP_ESC_PLUS_ONE_INF            = (1<<5);
+    final int OP_QMARK_ZERO_ONE              = (1<<6);   /* ? */
+    final int OP_ESC_QMARK_ZERO_ONE          = (1<<7);
+    final int OP_BRACE_INTERVAL              = (1<<8);   /* {lower,upper} */
+    final int OP_ESC_BRACE_INTERVAL          = (1<<9);   /* \{lower,upper\} */
+    final int OP_VBAR_ALT                    = (1<<10);   /* | */
+    final int OP_ESC_VBAR_ALT                = (1<<11);  /* \| */
+    final int OP_LPAREN_SUBEXP               = (1<<12);  /* (...);   */
+    final int OP_ESC_LPAREN_SUBEXP           = (1<<13);  /* \(...\); */
+    final int OP_ESC_AZ_BUF_ANCHOR           = (1<<14);  /* \A, \Z, \z */
+    final int OP_ESC_CAPITAL_G_BEGIN_ANCHOR  = (1<<15);  /* \G     */
+    final int OP_DECIMAL_BACKREF             = (1<<16);  /* \num   */
+    final int OP_BRACKET_CC                  = (1<<17);  /* [...]  */
+    final int OP_ESC_W_WORD                  = (1<<18);  /* \w, \W */
+    final int OP_ESC_LTGT_WORD_BEGIN_END     = (1<<19);  /* \<. \> */
+    final int OP_ESC_B_WORD_BOUND            = (1<<20);  /* \b, \B */
+    final int OP_ESC_S_WHITE_SPACE           = (1<<21);  /* \s, \S */
+    final int OP_ESC_D_DIGIT                 = (1<<22);  /* \d, \D */
+    final int OP_LINE_ANCHOR                 = (1<<23);  /* ^, $   */
+    final int OP_POSIX_BRACKET               = (1<<24);  /* [:xxxx:] */
+    final int OP_QMARK_NON_GREEDY            = (1<<25);  /* ??,*?,+?,{n,m}? */
+    final int OP_ESC_CONTROL_CHARS           = (1<<26);  /* \n,\r,\t,\a ... */
+    final int OP_ESC_C_CONTROL               = (1<<27);  /* \cx  */
+    final int OP_ESC_OCTAL3                  = (1<<28);  /* \OOO */
+    final int OP_ESC_X_HEX2                  = (1<<29);  /* \xHH */
+    final int OP_ESC_X_BRACE_HEX8            = (1<<30);  /* \x{7HHHHHHH} */
+
+    final int OP2_ESC_CAPITAL_Q_QUOTE        = (1<<0);  /* \Q...\E */
+    final int OP2_QMARK_GROUP_EFFECT         = (1<<1);  /* (?...); */
+    final int OP2_OPTION_PERL                = (1<<2);  /* (?imsx);,(?-imsx); */
+    final int OP2_OPTION_RUBY                = (1<<3);  /* (?imx);, (?-imx);  */
+    final int OP2_PLUS_POSSESSIVE_REPEAT     = (1<<4);  /* ?+,*+,++ */
+    final int OP2_PLUS_POSSESSIVE_INTERVAL   = (1<<5);  /* {n,m}+   */
+    final int OP2_CCLASS_SET_OP              = (1<<6);  /* [...&&..[..]..] */
+    final int OP2_QMARK_LT_NAMED_GROUP       = (1<<7);  /* (?<name>...); */
+    final int OP2_ESC_K_NAMED_BACKREF        = (1<<8);  /* \k<name> */
+    final int OP2_ESC_G_SUBEXP_CALL          = (1<<9);  /* \g<name>, \g<n> */
+    final int OP2_ATMARK_CAPTURE_HISTORY     = (1<<10); /* (?@..);,(?@<x>..); */
+    final int OP2_ESC_CAPITAL_C_BAR_CONTROL  = (1<<11); /* \C-x */
+    final int OP2_ESC_CAPITAL_M_BAR_META     = (1<<12); /* \M-x */
+    final int OP2_ESC_V_VTAB                 = (1<<13); /* \v as VTAB */
+    final int OP2_ESC_U_HEX4                 = (1<<14); /* \\uHHHH */
+    final int OP2_ESC_GNU_BUF_ANCHOR         = (1<<15); /* \`, \' */
+    final int OP2_ESC_P_BRACE_CHAR_PROPERTY  = (1<<16); /* \p{...}, \P{...} */
+    final int OP2_ESC_P_BRACE_CIRCUMFLEX_NOT = (1<<17); /* \p{^..}, \P{^..} */
+    /* final int OP2_CHAR_PROPERTY_PREFIX_IS = (1<<18); */
+    final int OP2_ESC_H_XDIGIT               = (1<<19); /* \h, \H */
+    final int OP2_INEFFECTIVE_ESCAPE         = (1<<20); /* \ */
+
+    /* syntax (behavior); */
+    final int CONTEXT_INDEP_ANCHORS           = (1<<31); /* not implemented */
+    final int CONTEXT_INDEP_REPEAT_OPS        = (1<<0);  /* ?, *, +, {n,m} */
+    final int CONTEXT_INVALID_REPEAT_OPS      = (1<<1);  /* error or ignore */
+    final int ALLOW_UNMATCHED_CLOSE_SUBEXP    = (1<<2);  /* ...);... */
+    final int ALLOW_INVALID_INTERVAL          = (1<<3);  /* {??? */
+    final int ALLOW_INTERVAL_LOW_ABBREV       = (1<<4);  /* {,n} => {0,n} */
+    final int STRICT_CHECK_BACKREF            = (1<<5);  /* /(\1);/,/\1();/ ..*/
+    final int DIFFERENT_LEN_ALT_LOOK_BEHIND   = (1<<6);  /* (?<=a|bc); */
+    final int CAPTURE_ONLY_NAMED_GROUP        = (1<<7);  /* see doc/RE */
+    final int ALLOW_MULTIPLEX_DEFINITION_NAME = (1<<8);  /* (?<x>);(?<x>); */
+    final int FIXED_INTERVAL_IS_GREEDY_ONLY   = (1<<9);  /* a{n}?=(?:a{n});? */
+
+    /* syntax (behavior); in char class [...] */
+    final int NOT_NEWLINE_IN_NEGATIVE_CC      = (1<<20); /* [^...] */
+    final int BACKSLASH_ESCAPE_IN_CC          = (1<<21); /* [..\w..] etc.. */
+    final int ALLOW_EMPTY_RANGE_IN_CC         = (1<<22);
+    final int ALLOW_DOUBLE_RANGE_OP_IN_CC     = (1<<23); /* [0-9-a]=[0-9\-a] */
+    /* syntax (behavior); warning */
+    final int WARN_CC_OP_NOT_ESCAPED          = (1<<24); /* [,-,] */
+    final int WARN_REDUNDANT_NESTED_REPEAT    = (1<<25); /* (?:a*);+ */
+
+    final int POSIX_COMMON_OP =
+                            OP_DOT_ANYCHAR | OP_POSIX_BRACKET |
+                            OP_DECIMAL_BACKREF |
+                            OP_BRACKET_CC | OP_ASTERISK_ZERO_INF |
+                            OP_LINE_ANCHOR |
+                            OP_ESC_CONTROL_CHARS;
+
+    final int GNU_REGEX_OP =
+                            OP_DOT_ANYCHAR | OP_BRACKET_CC |
+                            OP_POSIX_BRACKET | OP_DECIMAL_BACKREF |
+                            OP_BRACE_INTERVAL | OP_LPAREN_SUBEXP |
+                            OP_VBAR_ALT |
+                            OP_ASTERISK_ZERO_INF | OP_PLUS_ONE_INF |
+                            OP_QMARK_ZERO_ONE |
+                            OP_ESC_AZ_BUF_ANCHOR | OP_ESC_CAPITAL_G_BEGIN_ANCHOR |
+                            OP_ESC_W_WORD |
+                            OP_ESC_B_WORD_BOUND | OP_ESC_LTGT_WORD_BEGIN_END |
+                            OP_ESC_S_WHITE_SPACE | OP_ESC_D_DIGIT |
+                            OP_LINE_ANCHOR;
+
+    final int GNU_REGEX_BV =
+                            CONTEXT_INDEP_ANCHORS | CONTEXT_INDEP_REPEAT_OPS |
+                            CONTEXT_INVALID_REPEAT_OPS | ALLOW_INVALID_INTERVAL |
+                            BACKSLASH_ESCAPE_IN_CC | ALLOW_DOUBLE_RANGE_OP_IN_CC;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TargetInfo.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TargetInfo.java
new file mode 100644
index 0000000..0c96559
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TargetInfo.java
@@ -0,0 +1,27 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface TargetInfo {
+    final int ISNOT_EMPTY   = 0;
+    final int IS_EMPTY      = 1;
+    final int IS_EMPTY_MEM  = 2;
+    final int IS_EMPTY_REC  = 3;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TokenType.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TokenType.java
new file mode 100644
index 0000000..342455f
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TokenType.java
@@ -0,0 +1,48 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public enum TokenType {
+      EOT,            /* end of token */
+      RAW_BYTE,
+      CHAR,
+      STRING,
+      CODE_POINT,
+      ANYCHAR,
+      CHAR_TYPE,
+      BACKREF,
+      CALL,
+      ANCHOR,
+      OP_REPEAT,
+      INTERVAL,
+      ANYCHAR_ANYTIME,  /* SQL '%' == .* */
+      ALT,
+      SUBEXP_OPEN,
+      SUBEXP_CLOSE,
+      CC_OPEN,
+      QUOTE_OPEN,
+      CHAR_PROPERTY,    /* \p{...}, \P{...} */
+      /* in cc */
+      CC_CLOSE,
+      CC_RANGE,
+      POSIX_BRACKET_OPEN,
+      CC_AND,             /* && */
+      CC_CC_OPEN          /* [ */
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Traverse.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Traverse.java
new file mode 100644
index 0000000..8cc3667
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Traverse.java
@@ -0,0 +1,26 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+public interface Traverse {
+    final int TRAVERSE_CALLBACK_AT_FIRST = 1;
+    final int TRAVERSE_CALLBACK_AT_LAST = 2;
+    final int TRAVERSE_CALLBACK_AT_BOTH = TRAVERSE_CALLBACK_AT_FIRST | TRAVERSE_CALLBACK_AT_LAST;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java
new file mode 100644
index 0000000..77eba2d
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java
@@ -0,0 +1,157 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.encoding;
+
+public class AsciiTables {
+
+    public static final short AsciiCtypeTable[] = {
+            0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+            0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+            0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+            0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+            0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+            0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+            0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+            0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+            0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+            0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+            0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+            0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+            0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+            0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+            0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+            0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+    };
+
+    public static final byte ToLowerCaseTable[] = {
+            (byte)'\000', (byte)'\001', (byte)'\002', (byte)'\003', (byte)'\004', (byte)'\005', (byte)'\006', (byte)'\007',
+            (byte)'\010', (byte)'\011', (byte)'\012', (byte)'\013', (byte)'\014', (byte)'\015', (byte)'\016', (byte)'\017',
+            (byte)'\020', (byte)'\021', (byte)'\022', (byte)'\023', (byte)'\024', (byte)'\025', (byte)'\026', (byte)'\027',
+            (byte)'\030', (byte)'\031', (byte)'\032', (byte)'\033', (byte)'\034', (byte)'\035', (byte)'\036', (byte)'\037',
+            (byte)'\040', (byte)'\041', (byte)'\042', (byte)'\043', (byte)'\044', (byte)'\045', (byte)'\046', (byte)'\047',
+            (byte)'\050', (byte)'\051', (byte)'\052', (byte)'\053', (byte)'\054', (byte)'\055', (byte)'\056', (byte)'\057',
+            (byte)'\060', (byte)'\061', (byte)'\062', (byte)'\063', (byte)'\064', (byte)'\065', (byte)'\066', (byte)'\067',
+            (byte)'\070', (byte)'\071', (byte)'\072', (byte)'\073', (byte)'\074', (byte)'\075', (byte)'\076', (byte)'\077',
+            (byte)'\100', (byte)'\141', (byte)'\142', (byte)'\143', (byte)'\144', (byte)'\145', (byte)'\146', (byte)'\147',
+            (byte)'\150', (byte)'\151', (byte)'\152', (byte)'\153', (byte)'\154', (byte)'\155', (byte)'\156', (byte)'\157',
+            (byte)'\160', (byte)'\161', (byte)'\162', (byte)'\163', (byte)'\164', (byte)'\165', (byte)'\166', (byte)'\167',
+            (byte)'\170', (byte)'\171', (byte)'\172', (byte)'\133', (byte)'\134', (byte)'\135', (byte)'\136', (byte)'\137',
+            (byte)'\140', (byte)'\141', (byte)'\142', (byte)'\143', (byte)'\144', (byte)'\145', (byte)'\146', (byte)'\147',
+            (byte)'\150', (byte)'\151', (byte)'\152', (byte)'\153', (byte)'\154', (byte)'\155', (byte)'\156', (byte)'\157',
+            (byte)'\160', (byte)'\161', (byte)'\162', (byte)'\163', (byte)'\164', (byte)'\165', (byte)'\166', (byte)'\167',
+            (byte)'\170', (byte)'\171', (byte)'\172', (byte)'\173', (byte)'\174', (byte)'\175', (byte)'\176', (byte)'\177',
+            (byte)'\200', (byte)'\201', (byte)'\202', (byte)'\203', (byte)'\204', (byte)'\205', (byte)'\206', (byte)'\207',
+            (byte)'\210', (byte)'\211', (byte)'\212', (byte)'\213', (byte)'\214', (byte)'\215', (byte)'\216', (byte)'\217',
+            (byte)'\220', (byte)'\221', (byte)'\222', (byte)'\223', (byte)'\224', (byte)'\225', (byte)'\226', (byte)'\227',
+            (byte)'\230', (byte)'\231', (byte)'\232', (byte)'\233', (byte)'\234', (byte)'\235', (byte)'\236', (byte)'\237',
+            (byte)'\240', (byte)'\241', (byte)'\242', (byte)'\243', (byte)'\244', (byte)'\245', (byte)'\246', (byte)'\247',
+            (byte)'\250', (byte)'\251', (byte)'\252', (byte)'\253', (byte)'\254', (byte)'\255', (byte)'\256', (byte)'\257',
+            (byte)'\260', (byte)'\261', (byte)'\262', (byte)'\263', (byte)'\264', (byte)'\265', (byte)'\266', (byte)'\267',
+            (byte)'\270', (byte)'\271', (byte)'\272', (byte)'\273', (byte)'\274', (byte)'\275', (byte)'\276', (byte)'\277',
+            (byte)'\300', (byte)'\301', (byte)'\302', (byte)'\303', (byte)'\304', (byte)'\305', (byte)'\306', (byte)'\307',
+            (byte)'\310', (byte)'\311', (byte)'\312', (byte)'\313', (byte)'\314', (byte)'\315', (byte)'\316', (byte)'\317',
+            (byte)'\320', (byte)'\321', (byte)'\322', (byte)'\323', (byte)'\324', (byte)'\325', (byte)'\326', (byte)'\327',
+            (byte)'\330', (byte)'\331', (byte)'\332', (byte)'\333', (byte)'\334', (byte)'\335', (byte)'\336', (byte)'\337',
+            (byte)'\340', (byte)'\341', (byte)'\342', (byte)'\343', (byte)'\344', (byte)'\345', (byte)'\346', (byte)'\347',
+            (byte)'\350', (byte)'\351', (byte)'\352', (byte)'\353', (byte)'\354', (byte)'\355', (byte)'\356', (byte)'\357',
+            (byte)'\360', (byte)'\361', (byte)'\362', (byte)'\363', (byte)'\364', (byte)'\365', (byte)'\366', (byte)'\367',
+            (byte)'\370', (byte)'\371', (byte)'\372', (byte)'\373', (byte)'\374', (byte)'\375', (byte)'\376', (byte)'\377',
+    };
+
+    public static final byte ToUpperCaseTable[] = {
+            (byte)'\000', (byte)'\001', (byte)'\002', (byte)'\003', (byte)'\004', (byte)'\005', (byte)'\006', (byte)'\007',
+            (byte)'\010', (byte)'\011', (byte)'\012', (byte)'\013', (byte)'\014', (byte)'\015', (byte)'\016', (byte)'\017',
+            (byte)'\020', (byte)'\021', (byte)'\022', (byte)'\023', (byte)'\024', (byte)'\025', (byte)'\026', (byte)'\027',
+            (byte)'\030', (byte)'\031', (byte)'\032', (byte)'\033', (byte)'\034', (byte)'\035', (byte)'\036', (byte)'\037',
+            (byte)'\040', (byte)'\041', (byte)'\042', (byte)'\043', (byte)'\044', (byte)'\045', (byte)'\046', (byte)'\047',
+            (byte)'\050', (byte)'\051', (byte)'\052', (byte)'\053', (byte)'\054', (byte)'\055', (byte)'\056', (byte)'\057',
+            (byte)'\060', (byte)'\061', (byte)'\062', (byte)'\063', (byte)'\064', (byte)'\065', (byte)'\066', (byte)'\067',
+            (byte)'\070', (byte)'\071', (byte)'\072', (byte)'\073', (byte)'\074', (byte)'\075', (byte)'\076', (byte)'\077',
+            (byte)'\100', (byte)'\101', (byte)'\102', (byte)'\103', (byte)'\104', (byte)'\105', (byte)'\106', (byte)'\107',
+            (byte)'\110', (byte)'\111', (byte)'\112', (byte)'\113', (byte)'\114', (byte)'\115', (byte)'\116', (byte)'\117',
+            (byte)'\120', (byte)'\121', (byte)'\122', (byte)'\123', (byte)'\124', (byte)'\125', (byte)'\126', (byte)'\127',
+            (byte)'\130', (byte)'\131', (byte)'\132', (byte)'\133', (byte)'\134', (byte)'\135', (byte)'\136', (byte)'\137',
+            (byte)'\140', (byte)'\101', (byte)'\102', (byte)'\103', (byte)'\104', (byte)'\105', (byte)'\106', (byte)'\107',
+            (byte)'\110', (byte)'\111', (byte)'\112', (byte)'\113', (byte)'\114', (byte)'\115', (byte)'\116', (byte)'\117',
+            (byte)'\120', (byte)'\121', (byte)'\122', (byte)'\123', (byte)'\124', (byte)'\125', (byte)'\126', (byte)'\127',
+            (byte)'\130', (byte)'\131', (byte)'\132', (byte)'\173', (byte)'\174', (byte)'\175', (byte)'\176', (byte)'\177',
+            (byte)'\200', (byte)'\201', (byte)'\202', (byte)'\203', (byte)'\204', (byte)'\205', (byte)'\206', (byte)'\207',
+            (byte)'\210', (byte)'\211', (byte)'\212', (byte)'\213', (byte)'\214', (byte)'\215', (byte)'\216', (byte)'\217',
+            (byte)'\220', (byte)'\221', (byte)'\222', (byte)'\223', (byte)'\224', (byte)'\225', (byte)'\226', (byte)'\227',
+            (byte)'\230', (byte)'\231', (byte)'\232', (byte)'\233', (byte)'\234', (byte)'\235', (byte)'\236', (byte)'\237',
+            (byte)'\240', (byte)'\241', (byte)'\242', (byte)'\243', (byte)'\244', (byte)'\245', (byte)'\246', (byte)'\247',
+            (byte)'\250', (byte)'\251', (byte)'\252', (byte)'\253', (byte)'\254', (byte)'\255', (byte)'\256', (byte)'\257',
+            (byte)'\260', (byte)'\261', (byte)'\262', (byte)'\263', (byte)'\264', (byte)'\265', (byte)'\266', (byte)'\267',
+            (byte)'\270', (byte)'\271', (byte)'\272', (byte)'\273', (byte)'\274', (byte)'\275', (byte)'\276', (byte)'\277',
+            (byte)'\300', (byte)'\301', (byte)'\302', (byte)'\303', (byte)'\304', (byte)'\305', (byte)'\306', (byte)'\307',
+            (byte)'\310', (byte)'\311', (byte)'\312', (byte)'\313', (byte)'\314', (byte)'\315', (byte)'\316', (byte)'\317',
+            (byte)'\320', (byte)'\321', (byte)'\322', (byte)'\323', (byte)'\324', (byte)'\325', (byte)'\326', (byte)'\327',
+            (byte)'\330', (byte)'\331', (byte)'\332', (byte)'\333', (byte)'\334', (byte)'\335', (byte)'\336', (byte)'\337',
+            (byte)'\340', (byte)'\341', (byte)'\342', (byte)'\343', (byte)'\344', (byte)'\345', (byte)'\346', (byte)'\347',
+            (byte)'\350', (byte)'\351', (byte)'\352', (byte)'\353', (byte)'\354', (byte)'\355', (byte)'\356', (byte)'\357',
+            (byte)'\360', (byte)'\361', (byte)'\362', (byte)'\363', (byte)'\364', (byte)'\365', (byte)'\366', (byte)'\367',
+            (byte)'\370', (byte)'\371', (byte)'\372', (byte)'\373', (byte)'\374', (byte)'\375', (byte)'\376', (byte)'\377',
+    };
+
+    public static final int LowerMap[][] = {
+            {0x41, 0x61},
+            {0x42, 0x62},
+            {0x43, 0x63},
+            {0x44, 0x64},
+            {0x45, 0x65},
+            {0x46, 0x66},
+            {0x47, 0x67},
+            {0x48, 0x68},
+            {0x49, 0x69},
+            {0x4a, 0x6a},
+            {0x4b, 0x6b},
+            {0x4c, 0x6c},
+            {0x4d, 0x6d},
+            {0x4e, 0x6e},
+            {0x4f, 0x6f},
+            {0x50, 0x70},
+            {0x51, 0x71},
+            {0x52, 0x72},
+            {0x53, 0x73},
+            {0x54, 0x74},
+            {0x55, 0x75},
+            {0x56, 0x76},
+            {0x57, 0x77},
+            {0x58, 0x78},
+            {0x59, 0x79},
+            {0x5a, 0x7a}
+    };
+}
\ No newline at end of file
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/CharacterType.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/CharacterType.java
new file mode 100644
index 0000000..79e1c01
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/CharacterType.java
@@ -0,0 +1,79 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.encoding;
+
+public interface CharacterType {
+
+    final int NEWLINE   = 0;
+    final int ALPHA     = 1;
+    final int BLANK     = 2;
+    final int CNTRL     = 3;
+    final int DIGIT     = 4;
+    final int GRAPH     = 5;
+    final int LOWER     = 6;
+    final int PRINT     = 7;
+    final int PUNCT     = 8;
+    final int SPACE     = 9;
+    final int UPPER     = 10;
+    final int XDIGIT    = 11;
+    final int WORD      = 12;
+    final int ALNUM     = 13;      /* alpha || digit */
+    final int ASCII     = 14;
+
+    final int SPECIAL_MASK = 256;
+    final int S = SPECIAL_MASK | SPACE;
+    final int D = SPECIAL_MASK | DIGIT;
+    final int W = SPECIAL_MASK | WORD;
+
+    final int LETTER_MASK = (1 << Character.UPPERCASE_LETTER)
+                          | (1 << Character.LOWERCASE_LETTER)
+                          | (1 << Character.TITLECASE_LETTER)
+                          | (1 << Character.MODIFIER_LETTER)
+                          | (1 << Character.OTHER_LETTER);
+    final int ALPHA_MASK = LETTER_MASK
+                          | (1 << Character.COMBINING_SPACING_MARK)
+                          | (1 << Character.NON_SPACING_MARK)
+                          | (1 << Character.ENCLOSING_MARK);
+    final int ALNUM_MASK = ALPHA_MASK
+                          | (1 << Character.DECIMAL_DIGIT_NUMBER);
+    final int WORD_MASK = ALNUM_MASK
+                          | (1 << Character.CONNECTOR_PUNCTUATION);
+    final int PUNCT_MASK =  (1 << Character.CONNECTOR_PUNCTUATION)
+                          | (1 << Character.DASH_PUNCTUATION)
+                          | (1 << Character.END_PUNCTUATION)
+                          | (1 << Character.FINAL_QUOTE_PUNCTUATION)
+                          | (1 << Character.INITIAL_QUOTE_PUNCTUATION)
+                          | (1 << Character.OTHER_PUNCTUATION)
+                          | (1 << Character.START_PUNCTUATION);
+    final int CNTRL_MASK =  (1 << Character.CONTROL)
+                          | (1 << Character.FORMAT)
+                          | (1 << Character.PRIVATE_USE)
+                          | (1 << Character.SURROGATE);
+    final int SPACE_MASK =  (1 << Character.SPACE_SEPARATOR)
+                          | (1 << Character.LINE_SEPARATOR)        // 0x2028
+                          | (1 << Character.PARAGRAPH_SEPARATOR);  // 0x2029
+    final int GRAPH_MASK = SPACE_MASK
+                          | (1 << Character.CONTROL)
+                          | (1 << Character.SURROGATE);
+    final int PRINT_MASK =  (1 << Character.CONTROL)
+                          | (1 << Character.SURROGATE);
+
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/IntHolder.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/IntHolder.java
new file mode 100644
index 0000000..248538b
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/IntHolder.java
@@ -0,0 +1,24 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.encoding;
+
+public class IntHolder {
+    public int value;
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/ObjPtr.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/ObjPtr.java
new file mode 100644
index 0000000..5238a03
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/ObjPtr.java
@@ -0,0 +1,35 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.encoding;
+
+public final class ObjPtr<T> {
+    public ObjPtr() {
+        this(null);
+    }
+
+    public ObjPtr(T p) {
+        this.p = p;
+    }
+
+    public T p;
+
+    static final ObjPtr<Void> NULL = new ObjPtr<Void>();
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/PosixBracket.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/PosixBracket.java
new file mode 100644
index 0000000..48978bf
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/PosixBracket.java
@@ -0,0 +1,77 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS".toCharArray(), WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.encoding;
+
+import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
+
+import java.util.HashMap;
+
+public class PosixBracket {
+
+    public static final char[][] PBSNamesLower = {
+            "alnum".toCharArray(),
+            "alpha".toCharArray(),
+            "blank".toCharArray(),
+            "cntrl".toCharArray(),
+            "digit".toCharArray(),
+            "graph".toCharArray(),
+            "lower".toCharArray(),
+            "print".toCharArray(),
+            "punct".toCharArray(),
+            "space".toCharArray(),
+            "upper".toCharArray(),
+            "xdigit".toCharArray(),
+            "ascii".toCharArray(),
+            "word".toCharArray()
+    };
+
+    public static final int PBSValues[] = {
+            CharacterType.ALNUM,
+            CharacterType.ALPHA,
+            CharacterType.BLANK,
+            CharacterType.CNTRL,
+            CharacterType.DIGIT,
+            CharacterType.GRAPH,
+            CharacterType.LOWER,
+            CharacterType.PRINT,
+            CharacterType.PUNCT,
+            CharacterType.SPACE,
+            CharacterType.UPPER,
+            CharacterType.XDIGIT,
+            CharacterType.ASCII,
+            CharacterType.WORD,
+    };
+
+    public static int propertyNameToCType(String name) {
+        name = name.toLowerCase();
+        if (!PBSTableUpper.containsKey(name)) {
+            throw new JOniException(ErrorMessages.ERR_INVALID_CHAR_PROPERTY_NAME.replaceAll("%n", name));
+        }
+        return PBSTableUpper.get(name);
+    }
+
+    private static final HashMap<String,Integer> PBSTableUpper = new HashMap<String,Integer>();
+
+    static {
+        for (int i=0; i<PBSValues.length; i++) PBSTableUpper.put(new String(PBSNamesLower[i]), PBSValues[i]);
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/Ptr.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/Ptr.java
new file mode 100644
index 0000000..57a28b9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/Ptr.java
@@ -0,0 +1,35 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.encoding;
+
+public final class Ptr {
+    public Ptr() {
+        this(0);
+    }
+
+    public Ptr(int p) {
+        this.p = p;
+    }
+
+    public int p;
+
+    public static final Ptr NULL = new Ptr(0);
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java
new file mode 100644
index 0000000..87e2a49
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java
@@ -0,0 +1,98 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
+import jdk.nashorn.internal.runtime.regexp.joni.Config;
+
+public interface ErrorMessages {
+    final String MISMATCH = "mismatch";
+    final String NO_SUPPORT_CONFIG = "no support in this configuration";
+
+    /* from jcodings */
+    final String ERR_INVALID_CHAR_PROPERTY_NAME = "invalid character property name <%n>";
+    final String ERR_INVALID_CODE_POINT_VALUE = "invalid code point value";
+    final String ERR_TOO_BIG_WIDE_CHAR_VALUE = "too big wide-char value";
+    final String ERR_TOO_LONG_WIDE_CHAR_VALUE = "too long wide-char value";
+
+    /* internal error */
+    final String ERR_MEMORY = "fail to memory allocation";
+    final String ERR_MATCH_STACK_LIMIT_OVER = "match-stack limit over";
+    final String ERR_TYPE_BUG = "undefined type (bug)";
+    final String ERR_PARSER_BUG = "internal parser error (bug)";
+    final String ERR_STACK_BUG = "stack error (bug)";
+    final String ERR_UNDEFINED_BYTECODE = "undefined bytecode (bug)";
+    final String ERR_UNEXPECTED_BYTECODE = "unexpected bytecode (bug)";
+    final String ERR_DEFAULT_ENCODING_IS_NOT_SETTED = "default multibyte-encoding is not setted";
+    final String ERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR = "can't convert to wide-char on specified multibyte-encoding";
+
+    /* general error */
+    final String ERR_INVALID_ARGUMENT = "invalid argument";
+
+    /* syntax error */
+    final String ERR_END_PATTERN_AT_LEFT_BRACE = "end pattern at left brace";
+    final String ERR_END_PATTERN_AT_LEFT_BRACKET = "end pattern at left bracket";
+    final String ERR_EMPTY_CHAR_CLASS = "empty char-class";
+    final String ERR_PREMATURE_END_OF_CHAR_CLASS = "premature end of char-class";
+    final String ERR_END_PATTERN_AT_ESCAPE = "end pattern at escape";
+    final String ERR_END_PATTERN_AT_META = "end pattern at meta";
+    final String ERR_END_PATTERN_AT_CONTROL = "end pattern at control";
+    final String ERR_META_CODE_SYNTAX = "invalid meta-code syntax";
+    final String ERR_CONTROL_CODE_SYNTAX = "invalid control-code syntax";
+    final String ERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE = "char-class value at end of range";
+    final String ERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE = "char-class value at start of range";
+    final String ERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS = "unmatched range specifier in char-class";
+    final String ERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED = "target of repeat operator is not specified";
+    final String ERR_TARGET_OF_REPEAT_OPERATOR_INVALID = "target of repeat operator is invalid";
+    final String ERR_NESTED_REPEAT_OPERATOR = "nested repeat operator";
+    final String ERR_UNMATCHED_CLOSE_PARENTHESIS = "unmatched close parenthesis";
+    final String ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS = "end pattern with unmatched parenthesis";
+    final String ERR_END_PATTERN_IN_GROUP = "end pattern in group";
+    final String ERR_UNDEFINED_GROUP_OPTION = "undefined group option";
+    final String ERR_INVALID_POSIX_BRACKET_TYPE = "invalid POSIX bracket type";
+    final String ERR_INVALID_LOOK_BEHIND_PATTERN = "invalid pattern in look-behind";
+    final String ERR_INVALID_REPEAT_RANGE_PATTERN = "invalid repeat range {lower,upper}";
+
+    /* values error (syntax error) */
+    final String ERR_TOO_BIG_NUMBER = "too big number";
+    final String ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE = "too big number for repeat range";
+    final String ERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE = "upper is smaller than lower in repeat range";
+    final String ERR_EMPTY_RANGE_IN_CHAR_CLASS = "empty range in char class";
+    final String ERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE = "mismatch multibyte code length in char-class range";
+    final String ERR_TOO_MANY_MULTI_BYTE_RANGES = "too many multibyte code ranges are specified";
+    final String ERR_TOO_SHORT_MULTI_BYTE_STRING = "too short multibyte code string";
+    final String ERR_TOO_BIG_BACKREF_NUMBER = "too big backref number";
+    final String ERR_INVALID_BACKREF = Config.USE_NAMED_GROUP ? "invalid backref number/name" : "invalid backref number";
+    final String ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED = "numbered backref/call is not allowed. (use name)";
+    final String ERR_INVALID_WIDE_CHAR_VALUE = "invalid wide-char value";
+    final String ERR_EMPTY_GROUP_NAME = "group name is empty";
+    final String ERR_INVALID_GROUP_NAME = "invalid group name <%n>";
+    final String ERR_INVALID_CHAR_IN_GROUP_NAME = Config.USE_NAMED_GROUP ? "invalid char in group name <%n>" : "invalid char in group number <%n>";
+    final String ERR_UNDEFINED_NAME_REFERENCE = "undefined name <%n> reference";
+    final String ERR_UNDEFINED_GROUP_REFERENCE = "undefined group <%n> reference";
+    final String ERR_MULTIPLEX_DEFINED_NAME = "multiplex defined name <%n>";
+    final String ERR_MULTIPLEX_DEFINITION_NAME_CALL = "multiplex definition name <%n> call";
+    final String ERR_NEVER_ENDING_RECURSION = "never ending recursion";
+    final String ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY = "group number is too big for capture history";
+    final String ERR_NOT_SUPPORTED_ENCODING_COMBINATION = "not supported encoding combination";
+    final String ERR_INVALID_COMBINATION_OF_OPTIONS = "invalid combination of options";
+    final String ERR_OVER_THREAD_PASS_LIMIT_COUNT = "over thread pass limit count";
+    final String ERR_TOO_BIG_SB_CHAR_VALUE = "too big singlebyte char value";
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/InternalException.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/InternalException.java
new file mode 100644
index 0000000..47028ae
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/InternalException.java
@@ -0,0 +1,28 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
+public class InternalException extends JOniException{
+    private static final long serialVersionUID = -3871816465397927992L;
+
+    public InternalException(String message) {
+        super(message);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/JOniException.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/JOniException.java
new file mode 100644
index 0000000..a5f237f
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/JOniException.java
@@ -0,0 +1,28 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
+public class JOniException extends RuntimeException{
+    private static final long serialVersionUID = -6027192180014164667L;
+
+    public JOniException(String message) {
+        super(message);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/SyntaxException.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/SyntaxException.java
new file mode 100644
index 0000000..e53fe36
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/SyntaxException.java
@@ -0,0 +1,28 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
+public class SyntaxException extends JOniException{
+    private static final long serialVersionUID = 7862720128961874288L;
+
+    public SyntaxException(String message) {
+        super(message);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java
new file mode 100644
index 0000000..d56a35a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java
@@ -0,0 +1,37 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
+public class ValueException extends SyntaxException{
+    private static final long serialVersionUID = -196013852479929134L;
+
+    public ValueException(String message) {
+        super(message);
+    }
+
+    public ValueException(String message, String str) {
+        super(message.replaceAll("%n", str));
+    }
+
+    public ValueException(String message, byte[]bytes, int p, int end) {
+        this(message, new String(bytes, p, end - p));
+    }
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
new file mode 100644
index 0000000..4547e44
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
@@ -0,0 +1,142 @@
+#
+# 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.
+#
+lexer.error.edit.string.missing.brace=Edit string expression missing closing brace
+lexer.error.here.missing.end.marker=Here string missing end marker "{0}"
+lexer.error.missing.close.quote=Missing close quote
+lexer.error.invalid.hex=Invalid hex digit
+lexer.error.invalid.octal=Invalid octal digit
+lexer.error.strict.no.octal=cannot use octal escapes in strict mode
+lexer.error.illegal.identifier.character=Illegal character in identifier
+
+parser.error.illegal.continue.stmt=Illegal continue statement
+parser.error.illegal.break.stmt=Illegal break statement
+parser.error.invalid.lvalue=Invalid left hand side for assignment
+parser.error.undefined.label=Undefined Label "{0}"
+parser.error.duplicate.label=Duplicate Label "{0}"
+parser.error.duplicate.default.in.switch=Switch already has default case
+parser.error.expected.literal=Expected a literal but found {0}
+parser.error.expected.operand=Expected an operand but found {0}
+parser.error.expected.stmt=Expected statement but found {0}
+parser.error.expected.comma=Expected comma but found {0}
+parser.error.expected=Expected {0} but found {1}
+parser.error.invalid.return=Invalid return statement
+parser.error.property.redefinition=Property "{0}" already defined
+parser.error.unexpected.token=Unexpected token: {0}
+parser.error.many.vars.in.for.in.loop=Only one variable allowed in for..in loop
+parser.error.not.lvalue.for.in.loop=Invalid left side value of for..in loop
+parser.error.missing.catch.or.finally=Missing catch or finally after try
+parser.error.regex.unsupported.flag=Unsupported RegExp flag: {0}
+parser.error.regex.repeated.flag=Repeated RegExp flag: {0}
+parser.error.regex.syntax={0}
+
+# strict mode error messages
+parser.error.strict.no.with="with" statement cannot be used in strict mode
+parser.error.strict.name="{0}" cannot be used as {1} in strict mode
+parser.error.strict.cant.delete.ident=cannot delete identifier "{0}" in strict mode
+parser.error.strict.param.redefinition=strict mode function cannot have duplicate parameter name "{0}"
+parser.error.strict.no.octal=cannot use octal value in strict mode
+parser.error.strict.no.func.here=In strict mode, functions can only be declared at top-level or immediately within a function
+type.error.strict.getter.setter.poison=In strict mode, "caller", "callee", and "arguments" properties can not be accessed on functions or the arguments object
+
+# not the expected type in a given context
+type.error.not.an.object={0} is not an Object
+type.error.not.a.boolean={0} is not a Boolean
+type.error.not.a.date={0} is not a Date
+type.error.not.a.number={0} is not a Number
+type.error.not.a.regexp={0} is not a RegExp
+type.error.not.a.string={0} is not a String
+type.error.not.a.function={0} is not a function
+type.error.not.a.constructor={0} is not a constructor function
+type.error.not.a.file={0} is not a File
+
+# operations not permitted on undefined
+type.error.cant.call.undefined=Cannot call undefined
+type.error.cant.read.property.of.undefined=Cannot read property "{0}" from undefined
+type.error.cant.set.property.of.undefined=Cannot set property "{0}" of undefined
+type.error.cant.delete.property.of.undefined=Cannot delete property "{0}" of undefined
+
+# other wrong usages of property
+type.error.property.has.no.setter=Cannot set property "{0}" of {1} that has only a getter
+type.error.cant.set.proto.to.non.object=Cannot set Object {0}'s __proto__ to be a non-object like {1}
+type.error.no.such.function={1} has no such function "{0}"
+type.error.cant.get.property=Cannot get property "{0}" of {1}
+type.error.cant.set.property=Cannot set property "{0}" of {1}
+type.error.cant.delete.property=Cannot delete property "{0}" of {1}
+type.error.cant.redefine.property=Cannot redefine property "{0}" of {1}
+type.error.property.not.writable="{0}" is not a writable property of {1}
+type.error.object.non.extensible=Cannot add new property "{0}" to non-extensible {1}
+
+# miscellaneous
+type.error.regex.cant.supply.flags=Cannot supply flags when constructing one RegExp from another
+type.error.inconsistent.property.descriptor=inconsistent property descriptor
+type.error.bad.default.value=bad default value: {0}
+type.error.function.apply.expects.array=Function.prototype.apply expects an Array for second argument
+type.error.instanceof.on.non.object=instanceof cannot be used on objects without [[HasInstance]]
+type.error.cannot.convert.to.interface=object {0} cannot be converted to {1} due to "{2}"
+type.error.array.reduce.invalid.init=invalid initialValue for Array.prototype.reduce
+type.error.array.reduceright.invalid.init=invalid initialValue for Array.prototype.reduceRight
+type.error.cannot.get.default.string=Cannot get default string value
+type.error.cannot.get.default.number=Cannot get default number value
+type.error.cant.apply.with.to.null=Cannot apply "with" to null
+type.error.cant.apply.with.to.undefined=Cannot apply "with" to undefined
+type.error.in.with.non.object=Right hand side of "in" cannot be non-Object, found {0}
+type.error.prototype.not.an.object="prototype" of {0} is not an Object, it is {1}
+type.error.cant.load.script=Cannot load script from {0}
+type.error.JSON.stringify.cyclic=JSON.stringify got a cyclic data structure
+type.error.cant.convert.string.to.char=Cannot convert string to character; its length must be exactly 1
+type.error.cant.convert.number.to.char=Cannot convert number to character; it's out of 0-65535 range
+type.error.cant.convert.to.java.string=Cannot convert object of type {0} to a Java argument of string type
+type.error.cant.convert.to.java.number=Cannot convert object of type {0} to a Java argument of number type
+type.error.cant.convert.to.javascript.array=Can only convert Java arrays and lists to JavaScript arrays. Can't convert object of type {0}.
+type.error.extend.expects.at.least.one.argument=Java.extend needs at least one argument.
+type.error.extend.expects.java.types=Java.extend needs Java types as its arguments.
+type.error.extend.ambiguous.defining.class=There is no class loader that can see all of {0} at once.
+type.error.extend.ERROR_FINAL_CLASS=Can not extend final class {0}.
+type.error.extend.ERROR_NON_PUBLIC_CLASS=Can not extend/implement non-public class/interface {0}.
+type.error.extend.ERROR_NO_ACCESSIBLE_CONSTRUCTOR=Can not extend class {0} as it has no public or protected constructors.
+type.error.extend.ERROR_MULTIPLE_SUPERCLASSES=Can not extend multiple classes {0}. At most one of the specified types can be a class, the rest must all be interfaces.
+type.error.extend.ERROR_NO_COMMON_LOADER=Can not find a common class loader for ScriptObject and {0}.
+type.error.no.constructor.matches.args=Can not construct {0} with the passed arguments; they do not match any of its constructor signatures.
+type.error.no.method.matches.args=Can not invoke method {0} with the passed arguments; they do not match any of its method signatures.
+type.error.method.not.constructor=Java method {0} can't be used as a constructor.
+type.error.env.not.object=$ENV must be an Object.
+range.error.inappropriate.array.length=inappropriate array length: {0}
+range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
+range.error.invalid.precision=precision argument toPrecision() must be in [1, 21]
+range.error.invalid.radix=radix argument must be in [2, 36]
+range.error.invalid.date=Invalid Date
+range.error.too.many.errors=Script contains too many errors: {0} errors
+
+reference.error.not.defined="{0}" is not defined
+reference.error.cant.be.used.as.lhs="{0}" can not be used as the left-hand side of assignment
+
+syntax.error.invalid.json=Invalid JSON: {0}
+syntax.error.strict.cant.delete=cannot delete "{0}" in strict mode
+
+io.error.cant.write=cannot write "{0}"
+config.error.no.dest=no destination directory supplied
+
+uri.error.bad.uri=Bad URI "{0}" near offset {1}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
new file mode 100644
index 0000000..534eb17
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
@@ -0,0 +1,309 @@
+#
+# 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.
+#
+option.error.invalid.option="{0}" is not a recognized option. Use "{1}" or "{2}" to see a list of all supported options.
+
+nashorn.options = Usage: jjs [option=value]* [filename.js]+ [-- options...]\n\
+                \n\
+                Valid options are:
+
+#
+# Localized meta descriptions
+#
+nashorn.options.param = param
+nashorn.options.default = default
+
+#
+# Which option is "help".
+#
+nashorn.options.help.key = nashorn.option.help
+
+#
+# Which option is "xhelp".
+#
+nashorn.options.xhelp.key = nashorn.option.xhelp
+
+#
+# Which option is "D".
+#
+nashorn.options.D.key = nashorn.option.D
+
+##
+## Grammar: at least short or long form. Arguments are optional, in that case they are given as
+##
+## params - a description of the parameters for command line usage
+## name - the name of the option, e.g. "--long-name"
+## short_name - the short name of the option, e.g. "-l"
+## type - the type of the option, currently allowed: boolean, integer, string, log, timezone. defaults to boolean if left out
+## is_undocumented - should this option never appear in the online help. defaults to no.
+## desc - description of what the option does
+## default - default value of the option. e.g. debug.lines is true by default. Not set means option not available by default
+## dependency - does this arg imply another arg, e.g. scripting -> anon-functions
+## confict - does this arg conflict with another arg e.g trace && instrument
+## value_next_arg - is the opton's value passed as next argument in command line?
+##
+## At least short_name or name needs to be in place for an argument descriptor to be valid.
+
+nashorn.option.help = {                       \
+    name="-help",                             \
+    short_name="-h",                          \
+    desc="Print help for command line flags." \
+}
+
+nashorn.option.xhelp = {                               \
+    name="-xhelp",                                     \
+    is_undocumented=true,                              \
+    desc="Print extended help for command line flags." \
+}
+
+nashorn.option.anon.functions = {                \
+    name="--anon-functions",                     \
+    short_name="-af",                            \
+    is_undocumented=true,                        \
+    desc="Always allow functions as statements." \
+}
+
+nashorn.option.class.cache.size ={                            \
+    name="--class-cache-size",                                \
+    short_name="--ccs",                                       \
+    desc="Size of the Class cache size per global scope.",    \
+    is_undocumented=true,                                     \
+    type=Integer                                              \
+}
+
+nashorn.option.classpath ={                                   \
+    name="-classpath",                                        \
+    short_name="-cp",                                         \
+    desc="-cp path. Specify where to find user class files.", \
+    value_next_arg=true,                                      \
+    type=String                                               \
+}
+
+nashorn.option.compile.only = {       \
+    name="--compile-only",			  \
+    short_name="-co",                 \
+    is_undocumented=true,             \
+    desc="Compile without running.",  \
+    type=Boolean                      \
+}
+
+nashorn.option.d = {                                             \
+    name="--dump-debug-dir",                                     \
+    short_name="-d",                                             \
+    is_undocumented=true,                                        \
+    params="<path>",                                             \
+    desc="specify a destination directory to dump class files.", \
+    type=String                                                  \
+}
+
+nashorn.option.doe                = {   \
+    name="-dump-on-error",              \
+    short_name="-doe",                  \
+    desc="Dump a stack trace on errors."\
+}
+
+nashorn.option.empty.statements = {          \
+    name="--empty-statements",               \
+    is_undocumented=true,                    \
+    desc="Preserve empty statements in AST." \
+}
+
+nashorn.option.early.lvalue.error = {                                      \
+    name="--early-lvalue-error",                                           \
+    is_undocumented=true,                                                  \
+    desc="invalid lvalue expressions should be reported as early errors.", \
+    type=Boolean,                                                          \
+    default=true                                                           \
+}
+
+nashorn.option.fullversion = {                 \
+    name="-fullversion",                       \
+    short_name="-fv",                          \
+    desc="Print full version info of Nashorn." \
+}
+
+nashorn.option.log = {                                                       \
+    name="--log",                                                            \
+    is_undocumented=true,                                                    \
+    params="<module:level>,*",                                               \
+    desc="Enable logging of a given level for a given number of sub systems. \
+        [for example: --log=fields:finest,codegen:info]",                    \
+    type=Log                                                                 \
+}
+
+nashorn.option.debug.lines = {                          \
+    name="--debug-lines",                               \
+    is_undocumented=true,                               \
+    desc="Generate line number table in .class files.", \
+    default=true                                        \
+}
+
+nashorn.option.debug.locals = {                           \
+    name="--debug-locals",                                \
+    is_undocumented=true,                                 \
+    desc="Generate local variable table in .class files." \
+}
+
+nashorn.option.loader.per.compile = {              \
+    name="--loader-per-compile",                   \
+    is_undocumented=true,                          \
+    desc="Create a new class loader per compile.", \
+    default=true                                   \
+}
+
+nashorn.option.no.syntax.extensions = {            \
+    name="--no-syntax-extensions",                 \
+    short_name="--nse",                            \
+    is_undocumented=true,                          \
+    desc="No non-standard syntax extensions",      \
+    default=-anon-functions=false                  \
+}
+
+nashorn.option.package = {                                     \
+    name="--package",                                          \
+    is_undocumented=true,                                      \
+    desc="Package to which generated .class files are added.", \
+    params="<package>",                                        \
+    type=String,                                               \
+    default=""                                                 \
+}
+
+nashorn.option.parse.only = {       \
+    name="--parse-only", 			\
+    is_undocumented=true,           \
+    desc="Parse without compiling." \
+}
+
+nashorn.option.profile.callsites = {   \
+    name="--profile-callsites",        \
+    short_name="-pcs",                 \
+    is_undocumented=true,              \
+    desc="Dump callsite profile data." \
+}
+
+nashorn.option.print.ast = {            \
+    name="--print-ast",                 \
+    is_undocumented=true,               \
+    desc="Print abstract syntax tree."  \
+}
+
+nashorn.option.print.lower.ast = {              \
+    name="--print-lower-ast",                   \
+    is_undocumented=true,                       \
+    desc="Print lowered abstract syntax tree."  \
+}
+
+nashorn.option.print.code = { \
+    name="--print-code",      \
+    is_undocumented=true,     \
+    desc="Print bytecode."    \
+}
+
+nashorn.option.print.no.newline = {                     \
+    name="--print-no-newline",                          \
+    is_undocumented=true,                               \
+    desc="Print function will not print new line char." \
+}
+
+nashorn.option.print.parse = {   \
+    name="--print-parse",        \
+    is_undocumented=true,        \
+    desc="Print the parse tree." \
+}
+
+nashorn.option.print.lower.parse = {            \
+    name="--print-lower-parse",                 \
+    is_undocumented=true,                       \
+    desc="Print the parse tree after lowering." \
+}
+
+nashorn.option.print.symbols = {   \
+    name="--print-symbols",        \
+    is_undocumented=true,          \
+    desc="Print the symbol table." \
+}
+
+nashorn.option.D = {                                                          \
+    name="-D",                                                                \
+    desc="-Dname=value. Set a system property. This option can be repeated.", \
+    type=String                                                               \
+}
+
+nashorn.option.strict = {              \
+    name="-strict",                    \
+    desc="Run scripts in strict mode." \
+}
+
+nashorn.option.scripting = {            \
+    name="-scripting",                  \
+    desc="Enable scripting features.",	\
+    dependency="--anon-functions=true"  \
+}
+
+nashorn.option.timezone = {                    \
+    name="-timezone",                          \
+    short_name="-t",                           \
+    params="<timezone>",                       \
+    desc="Set timezone for script execution.", \
+    type=TimeZone                              \
+}
+
+nashorn.option.stdout = {                                               \
+    name="--stdout",                                                    \
+    is_undocumented=true,                                               \
+    type=String,                                                        \
+    params="<output console>",                                          \
+    desc="Redirect stdout to a filename or to another tty, e.g. stderr" \
+}
+
+nashorn.option.stderr = {                                               \
+    name="--stderr",                                                    \
+    is_undocumented=true,                                               \
+    type=String,                                                        \
+    params="<output console>",                                          \
+    desc="Redirect stderr to a filename or to another tty, e.g. stdout" \
+}
+
+nashorn.option.trace.callsites = {                                              \
+    name="--trace-callsites",                                                   \
+    short_name="-tcs",                                                          \
+    is_undocumented=true,                                                       \
+    type=keyvalues,                                                             \
+    params="[=[option,]*]",                                                     \
+    desc="Enable callsite trace mode. Options are: miss [trace callsite misses] \
+    enterexit [trace callsite enter/exit], objects [print object properties]"   \
+}
+
+nashorn.option.verify.code = {              \
+    name="--verify-code",                   \
+    is_undocumented=true,                   \
+    desc="Verify byte code before running." \
+}
+
+nashorn.option.version = {                \
+    name="-version",                      \
+    short_name="-v",                      \
+    desc="Print version info of Nashorn." \
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js
new file mode 100644
index 0000000..15c67f9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js
@@ -0,0 +1,351 @@
+/*
+ * 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.
+ */
+
+/**
+ * This script contains non-standard, Mozilla compatibility functionality on
+ * the standard global objects. Please note that it is incomplete. Only the most
+ * often used functionality is supported.
+ */
+
+// JavaAdapter
+Object.defineProperty(this, "JavaAdapter", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        if (arguments.length < 2) {
+            throw new TypeError("JavaAdapter requires atleast two arguments");
+        }
+            
+        var types = Array.prototype.slice.call(arguments, 0, arguments.length - 1);
+        var NewType = Java.extend.apply(Java, types);
+        return new NewType(arguments[arguments.length - 1]);
+    }
+});
+
+// importPackage
+Object.defineProperty(this, "importPackage", {
+    configurable: true, enumerable: false, writable: true,
+    value: (function() {
+        var _packages = [];
+        var global = this;
+        var oldNoSuchProperty = global.__noSuchProperty__;
+        global.__noSuchProperty__ = function(name) {
+            for (var i in _packages) {
+                try {
+                    var type = Java.type(_packages[i] + "." + name);
+                    global[name] = type;
+                    return type;
+                } catch (e) {}
+            }
+            
+            return oldNoSuchProperty? oldNoSuchProperty(name) : undefined;
+        }
+        
+        var prefix = "[JavaPackage ";
+        return function() {
+            for (var i in arguments) {
+                var pkgName = arguments[i];
+                if ((typeof pkgName) != 'string') {
+                    pkgName = String(pkgName);
+                    // extract name from JavaPackage object
+                    if (pkgName.startsWith(prefix)) {
+                        pkgName = pkgName.substring(prefix.length, pkgName.length - 1);
+                    }
+                }
+                _packages.push(pkgName);
+            }
+        }
+    })()
+});
+
+// Object.prototype.__defineGetter__
+Object.defineProperty(Object.prototype, "__defineGetter__", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(name, func) {
+        Object.defineProperty(this, name, {
+            configurable: true, enumerable: true, get: func });
+    }
+});
+
+// Object.prototype.__defineSetter__
+Object.defineProperty(Object.prototype, "__defineSetter__", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(name, func) {
+        Object.defineProperty(this, name, {
+            configurable: true, enumerable: true, set: func });
+    }
+});
+
+// Object.prototype.__lookupGetter__
+Object.defineProperty(Object.prototype, "__lookupGetter__", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(name) {
+        var obj = this;
+        while (obj) {
+            var desc = Object.getOwnPropertyDescriptor(obj, name);
+            if (desc) return desc.get;
+            obj = Object.getPrototypeOf(obj);
+        }
+        return undefined;
+    }
+});
+
+// Object.prototype.__lookupSetter__
+Object.defineProperty(Object.prototype, "__lookupSetter__", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(name) {
+        var obj = this;
+        while (obj) {
+            var desc = Object.getOwnPropertyDescriptor(obj, name);
+            if (desc) return desc.set;
+            obj = Object.getPrototypeOf(obj);
+        }
+        return undefined;
+    }
+});
+
+// Object.prototype.__proto__ (read-only)
+Object.defineProperty(Object.prototype, "__proto__", {
+    configurable: true, enumerable: false,
+    get: function() {
+        return Object.getPrototypeOf(this);
+    },
+    set: function(x) {
+        throw new TypeError("__proto__ set not supported");
+    }
+});
+
+// Object.prototype.toSource
+Object.defineProperty(Object.prototype, "toSource", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(state) {
+        if (! state) {
+            state = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap());
+        }
+        if (state.contains(this)) {
+            return "{}";
+        }
+        state.add(this);
+        var str = new java.lang.StringBuffer('({');
+        for (i in this) {
+            str.append(i);
+            str.append(':');
+            if (this[i] instanceof Object && typeof(this[i].toSource) == 'function') {
+                str.append(this[i].toSource(state));
+            } else {
+                str.append(String(this[i]));
+            }
+            str.append(', ');
+        }
+        // delete last extra command and space
+        str = str.deleteCharAt(str.length() - 1);
+        str = str.deleteCharAt(str.length() - 1);
+        str.append('})');
+        return str.toString();
+    }
+});
+
+// Boolean.prototype.toSource
+Object.defineProperty(Boolean.prototype, "toSource", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '(new Boolean(' + this.toString() + '))';
+    }
+});
+
+// Date.prototype.toSource
+Object.defineProperty(Date.prototype, "toSource", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '(new Date(' + this.valueOf() + '))';
+    }
+});
+
+// Function.prototype.toSource -- already implemented in nashorn
+
+// Number.prototype.toSource
+Object.defineProperty(Number.prototype, "toSource", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '(new Number(' + this.toString() + '))';
+    }
+});
+
+// RegExp.prototype.toSource
+Object.defineProperty(RegExp.prototype, "toSource", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return this.toString();
+    }
+});
+
+// String.prototype.toSource
+Object.defineProperty(String.prototype, "toSource", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '(new String(' + this.quote() + '))';
+    }
+});
+
+// Error.prototype.toSource
+Object.defineProperty(Error.prototype, "toSource", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        var msg = this.message? String(this.message).quote() : "''";
+        return '(new ' + this.name + '(' + msg + '))';
+    }
+});
+
+// Function.prototype.arity
+Object.defineProperty(Function.prototype, "arity", {
+    configurable: true, enumerable: false,
+    get: function() { return this.length; },
+    set: function(x) {
+        throw new TypeError("Function arity can not be modified");
+    }
+});
+
+// String.prototype.quote
+Object.defineProperty(String.prototype, "quote", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return JSON.stringify(this);
+    }
+});
+
+// HTML generation methods of String.prototype
+
+// String.prototype.anchor
+Object.defineProperty(String.prototype, "anchor", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(name) {
+        return '<a name="' + name + '">' + this + '</a>';
+    }
+});
+
+// String.prototype.big
+Object.defineProperty(String.prototype, "big", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '<big>' + this + '</big>';
+    }
+});
+
+// String.prototype.blink
+Object.defineProperty(String.prototype, "blink", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '<blink>' + this + '</blink>';
+    }
+});
+
+// String.prototype.bold
+Object.defineProperty(String.prototype, "bold", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '<b>' + this + '</b>';
+    }
+});
+
+// String.prototype.fixed
+Object.defineProperty(String.prototype, "fixed", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '<tt>' + this + '</tt>';
+    }
+});
+
+// String.prototype.fontcolor
+Object.defineProperty(String.prototype, "fontcolor", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(clr) {
+        return '<font color="' + clr + '">' + this + '</font>';
+    }
+});
+
+// String.prototype.fontsize
+Object.defineProperty(String.prototype, "fontsize", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(size) {
+        return '<font size="' + size + '">' + this + '</font>';
+    }
+});
+
+// String.prototype.italics
+Object.defineProperty(String.prototype, "italics", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '<i>' + this + '</i>';
+    }
+});
+
+// String.prototype.link
+Object.defineProperty(String.prototype, "link", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(url) {
+        return '<a href="' + url + '">' + this + '</a>';
+    }
+});
+
+// String.prototype.small
+Object.defineProperty(String.prototype, "small", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '<small>' + this + '</small>';
+    }
+});
+
+// String.prototype.strike
+Object.defineProperty(String.prototype, "strike", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '<strike>' + this + '</strike>';
+    }
+});
+
+// String.prototype.sub
+Object.defineProperty(String.prototype, "sub", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '<sub>' + this + '</sub>';
+    }
+});
+
+// String.prototype.sup
+Object.defineProperty(String.prototype, "sup", {
+    configurable: true, enumerable: false, writable: true,
+    value: function() {
+        return '<sup>' + this + '</sup>';
+    }
+});
+
+// Rhino: global.importClass
+Object.defineProperty(this, "importClass", {
+    configurable: true, enumerable: false, writable: true,
+    value: function(clazz) {
+        if (Java.isType(clazz)) {
+            this[clazz.class.getSimpleName()] = clazz;
+        } else {
+            throw new TypeError(clazz + " is not a Java class");
+        }
+    }
+});
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/parser.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/parser.js
new file mode 100644
index 0000000..b89f7e1
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/parser.js
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/**
+ * Parse function returns a JSON object representing ECMAScript code passed.
+ * name is optional name for the code source and location param tells whether to
+ * include location information for AST nodes or not.
+ *
+ * Example:
+ *
+ *    load("nashorn:parser.js");
+ *    try {
+ *        var json = parse("print('hello')");
+ *        print(JSON.stringify(json));
+ *    } catch (e) {
+ *        print(e);
+ *    }
+ */
+function parse(/*code, [name], [location]*/) {
+    var code, name = "<unknown>", location = false;
+    switch (arguments.length) {
+        case 3:
+            location = arguments[2];
+        case 2:
+            name = arguments[1];
+        case 1:
+            code = arguments[0];
+    }
+
+    var jsonStr = Packages.jdk.nashorn.internal.runtime.ScriptRuntime.parse(code, name, location);
+    return JSON.parse(jsonStr,
+        function (prop, value) {
+            if (typeof(value) == 'string' && prop == "value") {
+                // handle regexps and strings - both are encoded as strings but strings
+                // do not start with '/'. If regexp, then eval it to make RegExp object
+                return value.startsWith('/')? eval(value) : value.substring(1);
+            } else {
+                // anythin else is returned "as is""
+                return value;
+            }
+        });
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/version.properties-template b/nashorn/src/jdk/nashorn/internal/runtime/resources/version.properties-template
new file mode 100644
index 0000000..e64f146
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/version.properties-template
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+
+full=$(FULL_VERSION)
+release=$(RELEASE)
diff --git a/nashorn/src/jdk/nashorn/internal/scripts/JO.java b/nashorn/src/jdk/nashorn/internal/scripts/JO.java
new file mode 100644
index 0000000..4441236
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/scripts/JO.java
@@ -0,0 +1,62 @@
+/*
+ * 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.scripts;
+
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Empty object class.
+ */
+public class JO extends ScriptObject {
+
+    /**
+     * Constructor
+     */
+    public JO() {
+        super();
+    }
+
+    /**
+     * Constructor given an initial property map
+     *
+     * @param map the property map
+     */
+    public JO(final PropertyMap map) {
+        super(map);
+    }
+
+    /**
+     * Used by FunctionObjectCreator. A method handle of this method is passed to the ScriptFunction constructor.
+     *
+     * @param map  the property map to use for allocatorMap
+     *
+     * @return newly allocated ScriptObject
+     */
+    public static ScriptObject allocate(final PropertyMap map) {
+        return new JO(map);
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/scripts/JS.java b/nashorn/src/jdk/nashorn/internal/scripts/JS.java
new file mode 100644
index 0000000..8711d64
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/scripts/JS.java
@@ -0,0 +1,33 @@
+/*
+ * 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.scripts;
+
+/**
+ * Root of script classes.
+ */
+public class JS {
+    // Empty
+}
diff --git a/nashorn/src/jdk/nashorn/tools/Shell.java b/nashorn/src/jdk/nashorn/tools/Shell.java
new file mode 100644
index 0000000..0c040a2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java
@@ -0,0 +1,405 @@
+/*
+ * 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.tools;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.codegen.Compiler;
+import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.parser.Parser;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Command line Shell for processing JavaScript files.
+ */
+public class Shell {
+
+    /**
+     * Resource name for properties file
+     */
+    private static final String MESSAGE_RESOURCE = "jdk.nashorn.tools.resources.Shell";
+    /**
+     * Shell message bundle.
+     */
+    private static ResourceBundle bundle;
+
+    static {
+        // Without do privileged, under security manager messages can not be
+        // loaded.
+        bundle = AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
+            @Override
+            public ResourceBundle run() {
+                return ResourceBundle.getBundle(MESSAGE_RESOURCE, Locale.getDefault());
+            }
+        });
+    }
+
+    /**
+     * Exit code for command line tool - successful
+     */
+    public static final int SUCCESS = 0;
+    /**
+     * Exit code for command line tool - error on command line
+     */
+    public static final int COMMANDLINE_ERROR = 100;
+    /**
+     * Exit code for command line tool - error compiling script
+     */
+    public static final int COMPILATION_ERROR = 101;
+    /**
+     * Exit code for command line tool - error during runtime
+     */
+    public static final int RUNTIME_ERROR = 102;
+    /**
+     * Exit code for command line tool - i/o error
+     */
+    public static final int IO_ERROR = 103;
+    /**
+     * Exit code for command line tool - internal error
+     */
+    public static final int INTERNAL_ERROR = 104;
+
+    /**
+     * Constructor
+     */
+    protected Shell() {
+    }
+
+    /**
+     * Main entry point with the default input, output and error streams.
+     *
+     * @param args The command line arguments
+     */
+    public static void main(final String[] args) {
+        try {
+            System.exit(main(System.in, System.out, System.err, args));
+        } catch (final IOException e) {
+            System.err.println(e); //bootstrapping, Context.err may not exist
+            System.exit(IO_ERROR);
+        }
+    }
+
+    /**
+     * Starting point for executing a {@code Shell}. Starts a shell with the
+     * given arguments and streams and lets it run until exit.
+     *
+     * @param in input stream for Shell
+     * @param out output stream for Shell
+     * @param err error stream for Shell
+     * @param args arguments to Shell
+     *
+     * @return exit code
+     *
+     * @throws IOException if there's a problem setting up the streams
+     */
+    public static int main(final InputStream in, final OutputStream out, final OutputStream err, final String[] args) throws IOException {
+        return new Shell().run(in, out, err, args);
+    }
+
+    /**
+     * Run method logic.
+     *
+     * @param in input stream for Shell
+     * @param out output stream for Shell
+     * @param err error stream for Shell
+     * @param args arguments to Shell
+     *
+     * @return exit code
+     *
+     * @throws IOException if there's a problem setting up the streams
+     */
+    protected final int run(final InputStream in, final OutputStream out, final OutputStream err, final String[] args) throws IOException {
+        final Context context = makeContext(in, out, err, args);
+        if (context == null) {
+            return COMMANDLINE_ERROR;
+        }
+
+        final ScriptObject global = context.createGlobal();
+        final ScriptEnvironment env = context.getEnv();
+        final List<String> files = env.getFiles();
+        if (files.isEmpty()) {
+            return readEvalPrint(context, global);
+        }
+
+        if (env._compile_only) {
+            return compileScripts(context, global, files);
+        }
+
+        return runScripts(context, global, files);
+    }
+
+    /**
+     * Make a new Nashorn Context to compile and/or run JavaScript files.
+     *
+     * @param in input stream for Shell
+     * @param out output stream for Shell
+     * @param err error stream for Shell
+     * @param args arguments to Shell
+     *
+     * @return null if there are problems with option parsing.
+     */
+    @SuppressWarnings("resource")
+    private static Context makeContext(final InputStream in, final OutputStream out, final OutputStream err, final String[] args) {
+        final PrintStream pout = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out);
+        final PrintStream perr = err instanceof PrintStream ? (PrintStream) err : new PrintStream(err);
+        final PrintWriter wout = new PrintWriter(pout, true);
+        final PrintWriter werr = new PrintWriter(perr, true);
+
+        // Set up error handler.
+        final ErrorManager errors = new ErrorManager(werr);
+        // Set up options.
+        final Options options = new Options("nashorn", werr);
+
+        // parse options
+        if (args != null) {
+            try {
+                options.process(args);
+            } catch (final IllegalArgumentException e) {
+                werr.println(bundle.getString("shell.usage"));
+                options.displayHelp(e);
+                return null;
+            }
+        }
+
+        // detect scripting mode by any source's first character being '#'
+        if (!options.getBoolean("scripting")) {
+            for (final String fileName : options.getFiles()) {
+                final File firstFile = new File(fileName);
+                if (firstFile.isFile()) {
+                    try (final FileReader fr = new FileReader(firstFile)) {
+                        final int firstChar = fr.read();
+                        // starts with '#
+                        if (firstChar == '#') {
+                            options.set("scripting", true);
+                            break;
+                        }
+                    } catch (final IOException e) {
+                        // ignore this. File IO errors will be reported later anyway
+                    }
+                }
+            }
+        }
+
+        return new Context(options, errors, wout, werr, Thread.currentThread().getContextClassLoader());
+    }
+
+    /**
+     * Compiles the given script files in the command line
+     *
+     * @param context the nashorn context
+     * @param global the global scope
+     * @param files the list of script files to compile
+     *
+     * @return error code
+     * @throws IOException when any script file read results in I/O error
+     */
+    private static int compileScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
+        final ScriptObject oldGlobal = Context.getGlobal();
+        final boolean globalChanged = (oldGlobal != global);
+        final ScriptEnvironment env = context.getEnv();
+        try {
+            if (globalChanged) {
+                Context.setGlobal(global);
+            }
+            final ErrorManager errors = context.getErrorManager();
+
+            // For each file on the command line.
+            for (final String fileName : files) {
+                final FunctionNode functionNode = new Parser(env, new Source(fileName, new File(fileName)), errors).parse();
+
+                if (errors.getNumberOfErrors() != 0) {
+                    return COMPILATION_ERROR;
+                }
+
+                //null - pass no code installer - this is compile only
+                new Compiler(env, functionNode).compile();
+            }
+        } finally {
+            env.getOut().flush();
+            env.getErr().flush();
+            if (globalChanged) {
+                Context.setGlobal(oldGlobal);
+            }
+        }
+
+        return SUCCESS;
+    }
+
+    /**
+     * Runs the given JavaScript files in the command line
+     *
+     * @param context the nashorn context
+     * @param global the global scope
+     * @param files the list of script files to run
+     *
+     * @return error code
+     * @throws IOException when any script file read results in I/O error
+     */
+    private int runScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
+        final ScriptObject oldGlobal = Context.getGlobal();
+        final boolean globalChanged = (oldGlobal != global);
+        try {
+            if (globalChanged) {
+                Context.setGlobal(global);
+            }
+            final ErrorManager errors = context.getErrorManager();
+
+            // For each file on the command line.
+            for (final String fileName : files) {
+                final File file = new File(fileName);
+                final ScriptFunction script = context.compileScript(new Source(fileName, file.toURI().toURL()), global);
+                if (script == null || errors.getNumberOfErrors() != 0) {
+                    return COMPILATION_ERROR;
+                }
+
+                try {
+                    apply(script, global);
+                } catch (final NashornException e) {
+                    errors.error(e.toString());
+                    if (context.getEnv()._dump_on_error) {
+                        e.printStackTrace(context.getErr());
+                    }
+
+                    return RUNTIME_ERROR;
+                }
+            }
+        } finally {
+            context.getOut().flush();
+            context.getErr().flush();
+            if (globalChanged) {
+                Context.setGlobal(oldGlobal);
+            }
+        }
+
+        return SUCCESS;
+    }
+
+    /**
+     * Hook to ScriptFunction "apply". A performance metering shell may
+     * introduce enter/exit timing here.
+     *
+     * @param target target function for apply
+     * @param self self reference for apply
+     *
+     * @return result of the function apply
+     */
+    protected Object apply(final ScriptFunction target, final Object self) {
+        return ScriptRuntime.apply(target, self);
+    }
+
+    /**
+     * read-eval-print loop for Nashorn shell.
+     *
+     * @param context the nashorn context
+     * @param global  global scope object to use
+     * @return return code
+     */
+    @SuppressWarnings("resource")
+    private static int readEvalPrint(final Context context, final ScriptObject global) {
+        final String prompt = bundle.getString("shell.prompt");
+        final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+        final PrintWriter err = context.getErr();
+        final ScriptObject oldGlobal = Context.getGlobal();
+        final boolean globalChanged = (oldGlobal != global);
+        final ScriptEnvironment env = context.getEnv();
+
+        try {
+            if (globalChanged) {
+                Context.setGlobal(global);
+            }
+
+            // initialize with "shell.js" script
+            try {
+                final Source source = new Source("<shell.js>", Shell.class.getResource("resources/shell.js"));
+                context.eval(global, source.getString(), global, "<shell.js>", false);
+            } catch (final Exception e) {
+                err.println(e);
+                if (env._dump_on_error) {
+                    e.printStackTrace(err);
+                }
+
+                return INTERNAL_ERROR;
+            }
+
+            while (true) {
+                err.print(prompt);
+                err.flush();
+
+                String source = "";
+                try {
+                    source = in.readLine();
+                } catch (final IOException ioe) {
+                    err.println(ioe.toString());
+                }
+
+                if (source == null) {
+                    break;
+                }
+
+                Object res;
+                try {
+                    res = context.eval(global, source, global, "<shell>", env._strict);
+                } catch (final Exception e) {
+                    err.println(e);
+                    if (env._dump_on_error) {
+                        e.printStackTrace(err);
+                    }
+                    continue;
+                }
+
+                if (res != null && res != ScriptRuntime.UNDEFINED) {
+                    err.println(ScriptRuntime.safeToString(res));
+                }
+            }
+        } finally {
+            if (globalChanged) {
+                Context.setGlobal(global);
+            }
+        }
+
+        return SUCCESS;
+    }
+}
diff --git a/nashorn/src/jdk/nashorn/tools/resources/Shell.properties b/nashorn/src/jdk/nashorn/tools/resources/Shell.properties
new file mode 100644
index 0000000..6f4c973
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/tools/resources/Shell.properties
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+# Error messages for Shell tool
+
+shell.usage=jjs [<options>] <files> [-- <arguments>]
+
+shell.prompt=jjs> 
+
+
diff --git a/nashorn/src/jdk/nashorn/tools/resources/shell.js b/nashorn/src/jdk/nashorn/tools/resources/shell.js
new file mode 100644
index 0000000..fdfde7a
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/tools/resources/shell.js
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+/*
+ * Initialization script for shell when running in interactive mode.
+ */
+
+/**
+ * Reads zero or more lines from standard input and returns concatenated string
+ *
+ * @param endMarker marker string that signals end of input
+ * @param prompt prompt printed for each line
+ */
+Object.defineProperty(this, "input", {
+    value: function input(endMarker, prompt) {
+        if (!endMarker) {
+            endMarker = "";
+        }
+
+        if (!prompt) {
+            prompt = " >> ";
+        }
+
+        var imports = new JavaImporter(java.io, java.lang);
+        var str = "";
+        with (imports) {
+            var reader = new BufferedReader(new InputStreamReader(System['in']));
+            var line;
+            while (true) {
+                System.out.print(prompt);
+                line = reader.readLine();
+                if (line == null || line == endMarker) {
+                    break;
+                }
+                str += line + "\n";
+            }
+        }
+
+        return str;
+    },
+    enumerable: false,
+    writable: true,
+    configurable: true
+});
+
+
+/**
+ * Reads zero or more lines from standard input and evaluates the concatenated
+ * string as code
+ *
+ * @param endMarker marker string that signals end of input
+ * @param prompt prompt printed for each line
+ */
+Object.defineProperty(this, "evalinput", {
+    value: function evalinput(endMarker, prompt) {
+        var code = input(endMarker, prompt);
+        // make sure everything is evaluated in global scope!
+        return this.eval(code);
+    },
+    enumerable: false,
+    writable: true,
+    configurable: true
+});
diff --git a/nashorn/src/netscape/javascript/JSObject.java b/nashorn/src/netscape/javascript/JSObject.java
new file mode 100644
index 0000000..23054c6
--- /dev/null
+++ b/nashorn/src/netscape/javascript/JSObject.java
@@ -0,0 +1,101 @@
+/*
+ * 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 netscape.javascript;
+
+import java.applet.Applet;
+
+/**
+ * Stub for JSObject to get compilation going.
+ */
+public abstract class JSObject {
+
+    /**
+     * Get the window for an {@link Applet}. Not supported
+     * by Nashorn
+     *
+     * @param a applet
+     * @return the window instance
+     */
+    public static JSObject getWindow(final Applet a) {
+        throw new UnsupportedOperationException("getWindow");
+    }
+
+    /**
+     * Call a JavaScript method
+     *
+     * @param methodName name of method
+     * @param args arguments to method
+     * @return result of call
+     */
+    public abstract Object call(String methodName, Object args[]);
+
+    /**
+     * Evaluate a JavaScript expression
+     *
+     * @param s JavaScript expression to evaluate
+     * @return evaluation result
+     */
+    public abstract Object eval(String s);
+
+    /**
+     * Retrieves a named member of a JavaScript object.
+     *
+     * @param name of member
+     * @return member
+     */
+    public abstract Object getMember(String name);
+
+    /**
+     * Retrieves an indexed member of a JavaScript object.
+     *
+     * @param index index of member slot
+     * @return member
+     */
+    public abstract Object getSlot(int index);
+
+    /**
+     * Remove a named member from a JavaScript object
+     *
+     * @param name name of member
+     */
+    public abstract void removeMember(String name);
+
+    /**
+     * Set a named member in a JavaScript object
+     *
+     * @param name  name of member
+     * @param value value of member
+     */
+    public abstract void setMember(String name, Object value);
+
+    /**
+     * Set an indexed member in a JavaScript object
+     *
+     * @param index index of member slot
+     * @param value value of member
+     */
+    public abstract void setSlot(int index, Object value);
+}
diff --git a/nashorn/src/overview.html b/nashorn/src/overview.html
new file mode 100644
index 0000000..5418854
--- /dev/null
+++ b/nashorn/src/overview.html
@@ -0,0 +1,113 @@
+<!-- 
+ 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.
+-->
+<body>
+<p>
+Nashorn is a runtime environment for programs written in ECMAScript 5.1.
+</p>
+<h1>Usage</h1>
+<p>
+The recommended way to use Nashorn is through the <a href="http://jcp.org/en/jsr/detail?id=223" target="_top">JSR-223
+"Scripting for the Java Platform"</a> APIs found in the {@link javax.script} package. Usually, you'll obtain a
+{@link javax.script.ScriptEngine} instance for Nashorn using:
+<pre>
+import javax.script.*;
+...
+ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("nashorn");
+</pre>
+and then use it just as you would any other JSR-223 script engine. See
+<a href="jdk/nashorn/api/scripting/package-summary.html">{@code jdk.nashorn.api.scripting}</a> package
+for details.
+<p>
+<h1>Compatibility</h1>
+Nashorn is 100% compliant with the <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm"
+target="_top">ECMA-262 Standard, Edition 5.1</a>. It requires a Java Virtual Machine that implements the
+<a href="http://jcp.org/en/jsr/detail?id=292" target="_top">JSR-292 "Supporting Dynamically Typed Languages on the Java
+Platform"</a> specification (often referred to as "invokedynamic"), as well as the already mentioned JSR-223.
+<h1>Interoperability with the Java platform</h1>
+<p>
+In addition to being a 100% ECMAScript 5.1 runtime, Nashorn provides features for interoperability of the ECMAScript
+programs with the Java platform. In general, any Java object put into the script engine's context will be visible from
+the script. In terms of the standard, such Java objects are not considered "native objects", but rather "host objects",
+as defined in section 4.3.8. This distinction allows certain semantical differences in handling them compared to native
+objects. For most purposes, Java objects behave just as native objects do: you can invoke their methods, get and set
+their properties. In most cases, though, you can't add arbitrary properties to them, nor can you remove existing
+properties.
+<p>
+<h2>Java collection handling</h2>
+<p>
+Native Java arrays and {@link java.util.List}s support indexed access to their elements through the property accessors,
+and {@link java.util.Map}s support both property and element access through both dot and square-bracket property
+accessors, with the difference being that dot operator gives precedence to object properties (its fields and properties
+defined as {@code getXxx} and {@code setXxx} methods) while the square bracket operator gives precedence to map
+elements. Native Java arrays expose the {@code length} property.
+<p>
+<h2>ECMAScript primitive types</h2>
+<p>
+ECMAScript primitive types for number, string, and boolean are represented with {@link java.lang.Number},
+{@link java.lang.CharSequence}, and {@link java.lang.Boolean} objects. While the most often used number type is
+{@link java.lang.Double} and the most often used string type is {@link java.lang.String}, don't rely on it as various
+internal optimizations cause other subclasses of {@code Number} and internal implementations of {@code CharSequence} to
+be used.
+<p>
+<h2>Type conversions</h2>
+<p>
+When a method on a Java object is invoked, the arguments are converted to the formal parameter types of the Java method
+using all allowed ECMAScript conversions. This can be surprising, as in general, conversions from string to number will
+succeed according to Standard's section 9.3 "ToNumber" and so on; string to boolean, number to boolean, Object to
+number, Object to string all work. Note that if the Java method's declared parameter type is {@code java.lang.Object},
+Nashorn objects are passed without any conversion whatsoever; specifically if the JavaScript value being passed is of
+primitive string type, you can only rely on it being a {@code java.lang.CharSequence}, and if the value is a number, you
+can only rely on it being a {@code java.lang.Number}. If the Java method declared parameter type is more specific (e.g.
+{@code java.lang.String} or {@code java.lang.Double}), then Nashorn will of course ensure the required type is passed.
+<p>
+<h2>SAM types</h2>
+<p>
+As a special extension when invoking Java methods, ECMAScript function objects can be passed in place of an argument
+whose Java type is so-called "single abstract method" or "SAM" type. While this name usually covers single-method
+interfaces, Nashorn is a bit more versatile, and it recognizes a type as a SAM type if all its abstract methods are
+overloads of the same name, and it is either an interface, or it is an abstract class with
+a no-arg constructor. The type itself must be public, while the constructor and the methods can be either public or
+protected. If there are multiple abstract overloads of the same name, the single function will serve as the shared
+implementation for all of them, <em>and additionally it will also override any non-abstract methods of the same name</em>.
+This is done to be consistent with the fact that ECMAScript does not have the concept of overloaded methods.
+<p>
+<h2>The {@code Java} object</h2>
+Nashorn exposes a non-standard global object named {@code Java} that is the primary API entry point into Java
+platform-specific functionality. You can use it to create instances of Java classes, convert from Java arrays to native
+arrays and back, and so on. The methods on the objects are directly implemented by public static methods on the class
+<a href="jdk/nashorn/internal/objects/NativeJava.html">{@code NativeJava}</a>, see that class for details on what
+functionality is available.
+<h2>Representations of Java types</h2>
+The method <a href="jdk/nashorn/internal/objects/NativeJava.html#type(java.lang.Object,%20java.lang.Object)">
+{@code Java.type(typeName)}</a> takes a name of a type, and returns an object representing a Java type. You can
+use that object to both create new instances of Java classes, as well as to access static fields and methods on them.
+The type object is distinct from the {@code java.lang.Class} object, which represents the reflective run-time type
+identity and doesn't carry i.e. static members. Again, see the link for {@code NativeJava} above for details.
+<h2>Other non-standard built-in objects</h2>
+In addition to {@code Java}, Nashorn also exposes some other non-standard built-in objects:
+<a href="jdk/nashorn/internal/objects/NativeJSAdapter.html">{@code JSAdapter}</a>,
+<a href="jdk/nashorn/internal/objects/NativeJavaImporter.html">{@code JavaImporter},
+<a href="jdk/nashorn/internal/runtime/NativeJavaPackage.html">{@code Packages}.</a>
+</body>
diff --git a/nashorn/test/README b/nashorn/test/README
new file mode 100644
index 0000000..ff41be2
--- /dev/null
+++ b/nashorn/test/README
@@ -0,0 +1,78 @@
+Nashorn tests are TestNG based. Running tests requires downloading the TestNG
+library and placing its jar file into the lib subdirectory:
+
+   # download and install TestNG
+   wget http://testng.org/testng-x.y.z.zip
+   unzip testng-x.y.z.zip
+   cp testng-x.y.z/testng-x.y.z.jar lib/testng.jar
+
+   # run tests
+   cd ..
+   ant test
+
+This will fail with a message like
+
+    taskdef class org.testng.TestNGAntTask cannot be found
+
+if the TestNG jar file is not installed properly or if the wrong
+version is present. (Check build.xml to find the version of TestNG
+that is required.)  Only the jar file is necessary. The unzipped
+hierarchy can be removed.
+
+We have tested using TestNG 6.7 as well ad TestNG 6.8. TestNG 6.7's jar file
+is also available as part of jtreg 4.1 b05 which can be downloaded at
+http://download.java.net/openjdk/jtreg/
+
+ECMAScript script test framework:
+
+* Test tags for test framework:
+
+The test runner crawls these directories for .js files and looks for JTReg-style
+@foo comments to identify tests.
+
+    * @test - A test is tagged with @test.
+
+    * @test/fail - Tests that are supposed to fail (compiling, see @run/fail
+      for runtime) are tagged with @test/fail.
+
+    * @test/compile-error - Test expects compilation to fail, compares
+      output.
+
+    * @test/warning - Test expects compiler warnings, compares output.
+
+    * @test/nocompare - Test expects to compile [and/or run?]
+      successfully(may be warnings), does not compare output.
+
+    * @subtest - denotes necessary file for a main test file; itself is not
+      a test.
+
+    * @run - A test that should be run is also tagged with @run (otherwise
+      the test runner only compiles the test).
+
+    * @runif - A test that should be run only if a specific System property
+      is defined (Example: @runif external.v8)
+
+    * @run/fail - A test that should compile but fail with a runtime error.
+
+    * @run/param - specify runtime arguments to script.
+
+    * @run/ignore-std-error - script may produce output on stderr, ignore
+      this output.
+
+    * @compilearg \ - pass arg to compiler, sample.
+
+/**
+ * @compilearg --dump-ir-graph
+ * @test/warning
+ */
+
+    * @compilefirst foo.js - foo.js being a necessary file for a test; it
+      may or may not itself be a test. These are compiled separately before
+      main test file.
+
+    * @compile/fail foo.js - foo.js being a necessary file for a test; it
+      may or may not itself be a test, compile should fail. These are compile
+      with main file.
+
+    * @compile bar.js - bar.js being a necessary file for a test; it may or
+      may not itself be a test. These are compiled with main file.
diff --git a/nashorn/test/TEST.ROOT b/nashorn/test/TEST.ROOT
new file mode 100644
index 0000000..6512c34
--- /dev/null
+++ b/nashorn/test/TEST.ROOT
@@ -0,0 +1,6 @@
+# This file identifies the root of the test-suite hierarchy.
+# It also contains test-suite configuration information.
+# DO NOT EDIT without first contacting jdk-regtest@sun.com.
+
+# The list of keywords supported in the entire test suite
+keys=2d dnd i18n
diff --git a/nashorn/test/examples/dual-fields-micro.js b/nashorn/test/examples/dual-fields-micro.js
new file mode 100644
index 0000000..aafc888
--- /dev/null
+++ b/nashorn/test/examples/dual-fields-micro.js
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function b(x,y) {
+    return x * y; //this one always returns a double
+}
+
+var sum = 1;
+function bench() {    
+    var d = new Date;
+
+    for (var iter = 0; iter <4*50e6; iter++) {
+	sum *= 20 * b(21,22);
+    }
+
+    print("time = " +(new Date-d));
+    print(sum);    
+}
+
+bench();
diff --git a/nashorn/test/examples/innerbench.js b/nashorn/test/examples/innerbench.js
new file mode 100644
index 0000000..b7be741
--- /dev/null
+++ b/nashorn/test/examples/innerbench.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function bench() {
+   var N = 10000000;
+
+   function empty() {}
+
+   function outer1() {
+       function inner() {}
+   }
+
+   function outer2() {
+       function inner() {}
+       inner();
+   }
+
+   for (var i = 0, d = Date.now(); i < N; i++) {
+      empty();
+   }
+   print("empty :", Date.now() - d);
+   for (var i = 0, d = Date.now(); i < N; i++) {
+      outer1();
+   }
+   print("outer1:", Date.now() - d);
+   for (var i = 0, d = Date.now(); i < N; i++) {
+      outer2();
+   }
+   print("outer2:", Date.now() - d);
+}
+bench();
+
diff --git a/nashorn/test/examples/string-micro.js b/nashorn/test/examples/string-micro.js
new file mode 100644
index 0000000..56ed0dd
--- /dev/null
+++ b/nashorn/test/examples/string-micro.js
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+var str = "The quick gray nashorn jumps over the lazy zebra.";
+
+function bench(name, func) {
+    var start = Date.now();
+    for (var iter = 0; iter < 5000000; iter++) {
+        func();
+    }
+    print((Date.now() - start) + "\t" + name);
+}
+
+bench("[]", function() {
+    str[0];
+    str[1];
+    str[2];
+});
+
+bench("fromCharCode", function() {
+    String.fromCharCode(97);
+    String.fromCharCode(98);
+    String.fromCharCode(99);
+});
+
+bench("charAt 1", function() {
+    str.charAt(0);
+    str.charAt(1);
+    str.charAt(2);
+});
+
+bench("charAt 2", function() {
+    str.charAt(100);
+    str.charAt(-1);
+});
+
+bench("charCodeAt 1", function() {
+    str.charCodeAt(0);
+    str.charCodeAt(1);
+    str.charCodeAt(2);
+});
+
+bench("charCodeAt 2", function() {
+    str.charCodeAt(100);
+    str.charCodeAt(-1);
+});
+
+bench("indexOf 1", function() {
+    str.indexOf("T");
+    str.indexOf("h");
+    str.indexOf("e");
+});
+
+bench("indexOf 2", function() {
+    str.indexOf("T", 0);
+    str.indexOf("h", 1);
+    str.indexOf("e", 2);
+});
+
+bench("lastIndexOf", function() {
+    str.indexOf("a");
+    str.indexOf("r");
+    str.indexOf("b");
+});
+
+bench("slice", function() {
+    str.slice(5);
+    str.slice(5);
+    str.slice(5);
+});
+
+bench("split 1", function() {
+    str.split();
+});
+
+bench("split 2", function() {
+    str.split("foo");
+});
+
+bench("split 3", function() {
+    str.split(/foo/);
+});
+
+bench("substring 1", function() {
+    str.substring(0);
+    str.substring(0);
+    str.substring(0);
+});
+
+bench("substring 2", function() {
+    str.substring(0, 5);
+    str.substring(0, 5);
+    str.substring(0, 5);
+});
+
+bench("substr", function() {
+    str.substr(0);
+    str.substr(0);
+    str.substr(0);
+});
+
+bench("slice", function() {
+    str.slice(0);
+    str.slice(0);
+    str.slice(0);
+});
+
+bench("concat", function() {
+    str.concat(str);
+    str.concat(str);
+    str.concat(str);
+});
+
+bench("trim", function() {
+    str.trim();
+    str.trim();
+    str.trim();
+});
+
+bench("toUpperCase", function() {
+    str.toUpperCase();
+});
+
+bench("toLowerCase", function() {
+    str.toLowerCase();
+});
+
+bench("valueOf", function() {
+    str.valueOf();
+    str.valueOf();
+    str.valueOf();
+});
+
+bench("toString", function() {
+    str.toString();
+    str.toString();
+    str.toString();
+});
+
+bench("String", function() {
+    String(str);
+    String(str);
+    String(str);
+});
+
+bench("new String", function() {
+    new String(str);
+    new String(str);
+    new String(str);
+});
diff --git a/nashorn/test/examples/typechain.js b/nashorn/test/examples/typechain.js
new file mode 100644
index 0000000..8b13ad9
--- /dev/null
+++ b/nashorn/test/examples/typechain.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+print("Starting type chain test, x is undefined");
+var x;
+//loop once to ensure that the callsites have been rewritten and retargeted
+for (var i = 0; i < 5; i++) {
+    print("LAP " + i);
+    print(x);
+    x = 17;
+    print(x);
+    x = 17.4711;
+    print(x);
+    x += "string ";
+    print(x);
+}
+
+
diff --git a/nashorn/test/lib/benchmark.js b/nashorn/test/lib/benchmark.js
new file mode 100644
index 0000000..e759cf1
--- /dev/null
+++ b/nashorn/test/lib/benchmark.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * A simple benchmark module that can be loaded
+ * in order to time how many times a method executes
+ * in a fixed number of seconds
+ */
+
+var benchmark = function(method, timeInMillis, args) {
+    var hz,
+    period,
+    startTime = new Date,
+    runs = 0;
+    do {
+	method.apply(args);
+	runs++;
+	totalTime = new Date - startTime;
+    } while (totalTime < timeInMillis);
+    
+    // convert ms to seconds
+    totalTime /= 1000;
+    
+    // period → how long per operation
+    period = totalTime / runs;
+
+    // hz → the number of operations per second
+    hz = 1 / period;
+
+    return hz;
+};
+
diff --git a/nashorn/test/opt/add.js b/nashorn/test/opt/add.js
new file mode 100644
index 0000000..6e43ae0
--- /dev/null
+++ b/nashorn/test/opt/add.js
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/**
+ * Example of an add function that gets specialized to doubles
+ * if run with --optimize flag set 
+ */
+
+function add(a,b) {
+    return a + b;
+}
+
+
+function bench() {
+    var sum = 1;
+    for (var x = 0 ; x < 10e8/2 ; x ++) {
+	sum *= add(x,x + 1);
+    }
+    return sum;
+}
+
+print("doing first run");
+var d = new Date;
+print(bench());
+d = new Date - d;
+print("first run took " + d + " ms");
+
+// invalidate add, replace it with something else
+add = function(a,b) {
+    return b + a;
+}
+
+print("doing second run");
+var d = new Date;
+print(bench());
+d = new Date - d;
+print("second run took " + d + " ms");
+
diff --git a/nashorn/test/opt/add_constant.js b/nashorn/test/opt/add_constant.js
new file mode 100644
index 0000000..0f2ae8b
--- /dev/null
+++ b/nashorn/test/opt/add_constant.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * Example of an add function that gets specialized to doubles
+ * if run with --optimize flag set 
+ */
+
+function add(a,b) {
+    return a + b;
+}
+
+
+function bench() {
+    var sum = 1;
+    for (var x = 0 ; x < 5e7 ; x++) {
+	sum *= add(x, 17);
+    }
+    return sum;
+}
+
+var d = new Date;
+print(bench());
+d = new Date - d;
+print("took " + d + " ms");
diff --git a/nashorn/test/opt/add_reuse_callsite.js b/nashorn/test/opt/add_reuse_callsite.js
new file mode 100644
index 0000000..3539823
--- /dev/null
+++ b/nashorn/test/opt/add_reuse_callsite.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * Example of an add function that gets specialized to doubles
+ * if run with --optimize flag set 
+ */
+
+function add(a,b) {
+    return a + b;
+}
+
+
+function bench() {
+    var sum = 1;
+    for (var x = 0 ; x < 5e7 ; x++) {
+	sum *= add(x,x + 1);
+    }
+    for (var x = 0; x < 5e7 ; x++) {
+	sum *= add(x + 2, x + 3);
+    }
+    return sum;
+}
+
+var d = new Date;
+print(bench());
+d = new Date - d;
+print("took " + d + " ms");
diff --git a/nashorn/test/opt/add_revert2.js b/nashorn/test/opt/add_revert2.js
new file mode 100644
index 0000000..6ea36c5
--- /dev/null
+++ b/nashorn/test/opt/add_revert2.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * Example of an add function that gets specialized to doubles
+ * if run with --optimize flag set 
+ */
+
+function add(a,b) {
+    return a + b;
+}
+
+
+function bench() {
+    var sum = 1;
+    for (var x = 0 ; x < 5e7 ; x++) {
+	sum *= add(x, 17);
+	sum *= add(x, x); //can use same revert as 17?
+    }
+    return sum;
+}
+
+var d = new Date;
+print(bench());
+d = new Date - d;
+print("took " + d + " ms");
diff --git a/nashorn/test/opt/cascade_specialize.js b/nashorn/test/opt/cascade_specialize.js
new file mode 100644
index 0000000..7b5d66c
--- /dev/null
+++ b/nashorn/test/opt/cascade_specialize.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+function add3(a,b,c) {
+    return add2(a, b) + c;
+}
+
+function add2(a,b) {
+    return a + b;
+}
+
+function test() {
+    var x = 17;
+    var y = 18;
+    var z = 19;
+    add3(x,y,z);
+}
+
+test();
+ 
diff --git a/nashorn/test/script/README b/nashorn/test/script/README
new file mode 100644
index 0000000..3cca31e
--- /dev/null
+++ b/nashorn/test/script/README
@@ -0,0 +1,26 @@
+basic:
+
+"basic" language and library tests. These need run only with File read 
+permission to read files under "test/script" or subdirs and property read
+permission to read properties named "nashorn.test.*"
+
+error:
+
+scripts that should result in compile-time error. The expected files check
+for the error message format etc.
+
+currently-failing: 
+
+Tests that fail currently - but should pass eventually.
+These are excluded for now.
+
+sandbox:
+
+Tests to check that sandbox scripts cannot access security sensitive resources.
+Scripts under this directory run with no special permissions other than
+what is given to all "sandbox" scripts.
+
+trusted:
+
+These tests run under AllPermission. Put only those scripts that really need
+AllPermission - say for eg. creating class loader, full reflective access.
diff --git a/nashorn/test/script/assert.js b/nashorn/test/script/assert.js
new file mode 100644
index 0000000..25bc259
--- /dev/null
+++ b/nashorn/test/script/assert.js
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/**
+ * This is not a test - but a framework to run other tests.
+ *
+ * @subtest
+ */
+
+// Assert is TestNG's Assert class
+Object.defineProperty(this, "Assert", { 
+    configuable: true,
+    enumerable: false,
+    writable: true,
+    value: Packages.org.testng.Assert
+});
+
+// fail function to call TestNG Assert.fail
+Object.defineProperty(this, "fail", {
+    configuable: true,
+    enumerable: false,
+    writable: true,
+    // 'error' is optional. if present it has to be 
+    // an ECMAScript Error object or java Throwable object
+    value: function (message, error) {
+        var throwable = null;
+        if (typeof error != 'undefined') {
+            if (error instanceof java.lang.Throwable) {
+                throwable = error;
+            } else if (error.nashornException instanceof java.lang.Throwable) {
+                throwable = error.nashornException;
+            }
+        }
+
+        if (throwable != null) {
+            // call the fail version that accepts Throwable argument
+            Assert.fail(message, throwable);
+        } else {
+            // call the fail version that accepts just message
+            Assert.fail(message);
+        }
+    }
+});
diff --git a/nashorn/test/script/basic/JDK-8005958.js b/nashorn/test/script/basic/JDK-8005958.js
new file mode 100644
index 0000000..e72ba09
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8005958.js
@@ -0,0 +1,32 @@
+/*
+ * 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-8005958 : invoking a function through INVOKESTATIC with more 
+ * arguments than it declares resulted in malformed bytecode being
+ * generated.
+ *
+ * @test
+ * @run
+ */
+(function() {})(2)
diff --git a/nashorn/test/script/basic/JDK-8006304.js b/nashorn/test/script/basic/JDK-8006304.js
new file mode 100644
index 0000000..f2d2c01
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006304.js
@@ -0,0 +1,41 @@
+/*
+ * 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-8006304 : Remove pre-population of maps for constructor produced maps.
+ *
+ * @test
+ * @run
+ */
+
+function Factory() {
+    this.w = 10;
+    this.x = 20;
+    if (false) {
+        this.y = 30;
+    }
+    this.z = 40;
+}
+
+var a = new Factory();
+for (var i in a) print(i, a[i]);
diff --git a/nashorn/test/script/basic/JDK-8006304.js.EXPECTED b/nashorn/test/script/basic/JDK-8006304.js.EXPECTED
new file mode 100644
index 0000000..df803d7
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006304.js.EXPECTED
@@ -0,0 +1,3 @@
+w 10
+x 20
+z 40
diff --git a/nashorn/test/script/basic/JDK-8006337.js b/nashorn/test/script/basic/JDK-8006337.js
new file mode 100644
index 0000000..21c469a
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006337.js
@@ -0,0 +1,31 @@
+/*
+ * 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-8006337 : Discarded arguments for INVOKESTATIC must still be 
+ * evaluated for side effects.
+ *
+ * @test
+ * @run
+ */
+(function() {})(print("hello"))
diff --git a/nashorn/test/script/basic/JDK-8006337.js.EXPECTED b/nashorn/test/script/basic/JDK-8006337.js.EXPECTED
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006337.js.EXPECTED
@@ -0,0 +1 @@
+hello
diff --git a/nashorn/test/script/basic/JDK-8006529-b.js b/nashorn/test/script/basic/JDK-8006529-b.js
new file mode 100644
index 0000000..a7a6e3f
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006529-b.js
@@ -0,0 +1,65 @@
+/*
+ * 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 : Constructor functions that don't need callees must not get
+ * linked with a MethodHandle boud to a specific function instance.
+ * @test
+ * @run
+ */
+
+Object.defineProperty(Object.prototype, "extends", {
+  value: function (superConstructor) {
+    function ProtoBridge() { }
+    ProtoBridge.prototype = superConstructor.prototype;
+    this.prototype = new ProtoBridge();
+    this.superConstructor = superConstructor;
+  }
+});
+
+function A() {
+}
+A.prototype.f = function () {
+  this.g();
+}
+
+function B() {
+  B.superConstructor.call(this);
+  this.f();
+}
+B.extends(A);
+
+B.prototype.g = function () {
+  print("It worked!")
+}
+
+function C() {
+  C.superConstructor.call(this);
+}
+C.extends(B);
+
+var x = [B, C]
+for(var i in x) {
+  print("Doing " + i)
+  new x[i]()
+}
\ No newline at end of file
diff --git a/nashorn/test/script/basic/JDK-8006529-b.js.EXPECTED b/nashorn/test/script/basic/JDK-8006529-b.js.EXPECTED
new file mode 100644
index 0000000..e7891c7
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006529-b.js.EXPECTED
@@ -0,0 +1,4 @@
+Doing 0
+It worked!
+Doing 1
+It worked!
diff --git a/nashorn/test/script/basic/JDK-8006570.js b/nashorn/test/script/basic/JDK-8006570.js
new file mode 100644
index 0000000..29dc7ab
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006570.js
@@ -0,0 +1,60 @@
+/*
+ * 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-8006570 : this-value for non-strict functions should be converted to object
+ *
+ * @test
+ * @run
+ */
+
+var strict, nonstrict;
+
+nonstrict = Object.prototype.nonstrict = function nonstrict() {
+    print(typeof this, this instanceof Object);
+};
+
+(function() {
+    "use strict";
+    strict = Object.prototype.strict = function strict() {
+        print(typeof this, this instanceof Object);
+    };
+})();
+
+"foo".nonstrict();
+(1).nonstrict();
+true.nonstrict();
+nonstrict();
+nonstrict.call(null);
+nonstrict.call("foo");
+nonstrict.call(1);
+nonstrict.call(true);
+
+"foo".strict();
+(1).strict();
+true.strict();
+strict();
+strict.call(null);
+strict.call("foo");
+strict.call(1);
+strict.call(true);
\ No newline at end of file
diff --git a/nashorn/test/script/basic/JDK-8006570.js.EXPECTED b/nashorn/test/script/basic/JDK-8006570.js.EXPECTED
new file mode 100644
index 0000000..4d78063
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006570.js.EXPECTED
@@ -0,0 +1,16 @@
+object true
+object true
+object true
+object true
+object true
+object true
+object true
+object true
+string false
+number false
+boolean false
+undefined false
+object false
+string false
+number false
+boolean false
diff --git a/nashorn/test/script/basic/JDK-8006575.js b/nashorn/test/script/basic/JDK-8006575.js
new file mode 100644
index 0000000..4d005da
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006575.js
@@ -0,0 +1,32 @@
+/*
+ * 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-8006575 : Error in codegen for element access on primitive value
+ *
+ * @test
+ * @run
+ */
+
+// The following expression used to result in AssertionError from codegen
+(1)[0]
diff --git a/nashorn/test/script/basic/JDK-8006755.js b/nashorn/test/script/basic/JDK-8006755.js
new file mode 100644
index 0000000..3012a4b
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006755.js
@@ -0,0 +1,41 @@
+/*
+ * 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-8006755: Functions inside with statements dont get correct scope
+ *
+ * @test
+ * @run
+ */
+
+var scope = { x: "hello" };
+
+with (scope) {
+    function main() {
+        if (x != "hello") {
+            fail("x != 'hello'");
+        }
+    }
+}
+
+main()
diff --git a/nashorn/test/script/basic/JDK-8006852a.js b/nashorn/test/script/basic/JDK-8006852a.js
new file mode 100644
index 0000000..7e706bd
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006852a.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8006852 : Move tests from JIRA for prepopulated map failures
+ *
+ * @test
+ * @run
+ */
+ 
+function Field(val){                                                                                                                                                                                                                                          
+    this.value = val;                                                                                                                                                                                                                                         
+}                                                                                                                                                                                                                                                             
+var times = 0;                                                                                                                                                                                                                                                
+                                                                                                                                                                                                                                                              
+Field.prototype = {                                                                                                                                                                                                                                           
+    get value(){                                                                                                                                                                                                                                              
+        print("GETTER!");                                                                                                                                                                                                                                     
+        return this._value;                                                                                                                                                                                                                                   
+    },                                                                                                                                                                                                                                                        
+    set value(val){                                                                                                                                                                                                                                           
+        print("SETTER!");                                                                                                                                                                                                                                     
+        this._value = val + (++times);                                                                                                                                                                                                                        
+    }                                                                                                                                                                                                                                                         
+};                                                                                                                                                                                                                                                            
+                                                                                                                                                                                                                                                              
+var f = new Field("test");                                                                                                                                                                                                                                    
+print(f.value);                                                                                                                                                                                                                                               
+f.value = "test2";                                                                                                                                                                                                                                            
+print(f.value);
diff --git a/nashorn/test/script/basic/JDK-8006852a.js.EXPECTED b/nashorn/test/script/basic/JDK-8006852a.js.EXPECTED
new file mode 100644
index 0000000..1e4a83a
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006852a.js.EXPECTED
@@ -0,0 +1,6 @@
+SETTER!
+GETTER!
+test1
+SETTER!
+GETTER!
+test22
diff --git a/nashorn/test/script/basic/JDK-8006852b.js b/nashorn/test/script/basic/JDK-8006852b.js
new file mode 100644
index 0000000..2d0c4b6
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006852b.js
@@ -0,0 +1,48 @@
+/*
+ * 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-8006852 : Move tests from JIRA for prepopulated map failures
+ *
+ * @test
+ * @run
+ */
+ 
+function MyCons(arg) {
+    if (arg == 2) {
+       this.foo = 3;
+    }
+    this.bar = 44;
+    // print(Debug.map(this));
+}
+
+MyCons.prototype.foo = "proto--foo";
+
+var myObj = new MyCons();
+if (myObj.hasOwnProperty("foo")) {
+    print("FAILED: myObj should not have 'foo'");
+}
+
+if (myObj.foo !== 'proto--foo') {
+    print("FAILED: myObj.foo is wrong");
+}
diff --git a/nashorn/test/script/basic/JDK-8006857.js b/nashorn/test/script/basic/JDK-8006857.js
new file mode 100644
index 0000000..c651464
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006857.js
@@ -0,0 +1,48 @@
+/*
+ * 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-8006857: ClassCastException when interface implementing function uses arguments object
+ *
+ * @test
+ * @run
+ */
+
+
+function run() {
+    print(arguments);
+    print("in run");
+}
+
+var t = new java.lang.Thread(run);
+t.start();
+t.join();
+
+var r = new java.lang.Runnable() {
+        run: function() {
+            print(arguments);
+            print("in run");
+        }
+    };
+
+r.run();
diff --git a/nashorn/test/script/basic/JDK-8006857.js.EXPECTED b/nashorn/test/script/basic/JDK-8006857.js.EXPECTED
new file mode 100644
index 0000000..cfe8346
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006857.js.EXPECTED
@@ -0,0 +1,4 @@
+[object Arguments]
+in run
+[object Arguments]
+in run
diff --git a/nashorn/test/script/basic/JDK-8006983.js b/nashorn/test/script/basic/JDK-8006983.js
new file mode 100644
index 0000000..2c126c4
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006983.js
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+/**
+ * 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
+ *
+ * @test
+ * @option -scripting
+ * @option --no-syntax-extensions
+ * @run
+ */
+
+try {
+    eval("var r = new java.lang.Runnable() { run: function(){} }");
+    fail("should have thrown error for anon-class-style new");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected, got " + e);
+    }
+}
+
+try {
+    eval("var sqr = function(x) x*x ");
+    fail("should have thrown error for expression closures");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected, got " + e);
+    }
+}
+
+try {
+    eval("function() {};");
+    fail("should have thrown error for anonymous function statement");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected, got " + e);
+    }
+}
+
+try {
+    eval("for each (i in [22, 33, 33]) { print(i) }");
+    fail("should have thrown error for-each statement");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected, got " + e);
+    }
+}
+
+try {
+    eval("# shell style comment");
+    fail("should have thrown error for shell style comment");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected, got " + e);
+    }
+}
+
+try {
+    eval("print(<<EOF);\nhello\nworld\nEOF\n");
+    fail("should have thrown error heredoc");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected, got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/JDK-8006984.js b/nashorn/test/script/basic/JDK-8006984.js
new file mode 100644
index 0000000..60702e3
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006984.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * findProperty on WithObject was not considering its object argument
+ * 
+ * @test
+ * @run
+ */
+
+var guiPkgs = { JFrame: function() { print("created"); } }; 
+
+with (guiPkgs) { 
+     var main = function() { 
+        var frame; // <---- this local variable caused scope to be not set properly prior to fix
+
+        function createFrame() { 
+            frame = new JFrame(); 
+        } 
+
+        createFrame(); 
+    } 
+} 
+main();
diff --git a/nashorn/test/script/basic/JDK-8006984.js.EXPECTED b/nashorn/test/script/basic/JDK-8006984.js.EXPECTED
new file mode 100644
index 0000000..3151666
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8006984.js.EXPECTED
@@ -0,0 +1 @@
+created
diff --git a/nashorn/test/script/basic/JDK-8007060.js b/nashorn/test/script/basic/JDK-8007060.js
new file mode 100644
index 0000000..699cecb
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007060.js
@@ -0,0 +1,94 @@
+/*
+ * 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-8007060 : Primitive wrap filter throws ClassCastException in test262parallel
+ *
+ * @test
+ * @run
+ */
+
+Object.prototype.T = function() {
+    print(this, typeof this);
+};
+
+function F() {
+    print(this, typeof this);
+}
+
+
+function test(obj) {
+   obj.T();
+}
+
+// Ordinary callsite - call often so we go to megamorphic
+test(1);
+test({});
+test("hello");
+test(1);
+test({});
+test("hello");
+test(1);
+test({});
+test("hello");
+test(1);
+test({});
+test("hello");
+test(1);
+test({});
+test("hello");
+test(1);
+test({});
+test("hello");
+test(1);
+test({});
+test("hello");
+test(1);
+test({});
+test("hello");
+
+// Dynamic invoker callsite used by NativeArray
+[1, 2, 3].filter(F, 1);
+[1, 2, 3].filter(F, {});
+[1, 2, 3].filter(F, "hello");
+[1, 2, 3].filter(F, 1);
+[1, 2, 3].filter(F, {});
+[1, 2, 3].filter(F, "hello");
+[1, 2, 3].filter(F, 1);
+[1, 2, 3].filter(F, {});
+[1, 2, 3].filter(F, "hello");
+[1, 2, 3].filter(F, 1);
+[1, 2, 3].filter(F, {});
+[1, 2, 3].filter(F, "hello");
+[1, 2, 3].filter(F, 1);
+[1, 2, 3].filter(F, {});
+[1, 2, 3].filter(F, "hello");
+[1, 2, 3].filter(F, 1);
+[1, 2, 3].filter(F, {});
+[1, 2, 3].filter(F, "hello");
+[1, 2, 3].filter(F, 1);
+[1, 2, 3].filter(F, {});
+[1, 2, 3].filter(F, "hello");
+[1, 2, 3].filter(F, 1);
+[1, 2, 3].filter(F, {});
+[1, 2, 3].filter(F, "hello");
\ No newline at end of file
diff --git a/nashorn/test/script/basic/JDK-8007060.js.EXPECTED b/nashorn/test/script/basic/JDK-8007060.js.EXPECTED
new file mode 100644
index 0000000..4c504bf
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007060.js.EXPECTED
@@ -0,0 +1,96 @@
+1 object
+[object Object] object
+hello object
+1 object
+[object Object] object
+hello object
+1 object
+[object Object] object
+hello object
+1 object
+[object Object] object
+hello object
+1 object
+[object Object] object
+hello object
+1 object
+[object Object] object
+hello object
+1 object
+[object Object] object
+hello object
+1 object
+[object Object] object
+hello object
+1 object
+1 object
+1 object
+[object Object] object
+[object Object] object
+[object Object] object
+hello object
+hello object
+hello object
+1 object
+1 object
+1 object
+[object Object] object
+[object Object] object
+[object Object] object
+hello object
+hello object
+hello object
+1 object
+1 object
+1 object
+[object Object] object
+[object Object] object
+[object Object] object
+hello object
+hello object
+hello object
+1 object
+1 object
+1 object
+[object Object] object
+[object Object] object
+[object Object] object
+hello object
+hello object
+hello object
+1 object
+1 object
+1 object
+[object Object] object
+[object Object] object
+[object Object] object
+hello object
+hello object
+hello object
+1 object
+1 object
+1 object
+[object Object] object
+[object Object] object
+[object Object] object
+hello object
+hello object
+hello object
+1 object
+1 object
+1 object
+[object Object] object
+[object Object] object
+[object Object] object
+hello object
+hello object
+hello object
+1 object
+1 object
+1 object
+[object Object] object
+[object Object] object
+[object Object] object
+hello object
+hello object
+hello object
diff --git a/nashorn/test/script/basic/JDK-8007132.js b/nashorn/test/script/basic/JDK-8007132.js
new file mode 100644
index 0000000..363b108
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007132.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/**
+ * JDK-8007232: Java objects returned from constructor functions are lost
+ *
+ * @test
+ * @run
+ */
+
+function Func() {
+    return new java.util.HashMap();
+}
+
+var f = new Func();
+if (! (f instanceof java.util.Map)) {
+    fail("instance of java.util.Map expected")
+}
+
+function check(obj) {
+    if (typeof obj != 'object') {
+        fail("expected 'object' but got " + (typeof obj));
+    }
+}
+
+// check primitive returning constructors
+check(new (function() { return 22; }));
+check(new (function() { return false }));
+check(new (function() { return "hello" }));
+
+// check null and undefined returning constructors
+check(new (function() { return null; }));
+check(new (function() { return undefined; }));
diff --git a/nashorn/test/script/basic/JDK-8007140.js b/nashorn/test/script/basic/JDK-8007140.js
new file mode 100644
index 0000000..28b4191
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007140.js
@@ -0,0 +1,115 @@
+/*
+ * 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-8007140: Java.extend crashes when attempting to extend java.lang.Object
+ *
+ * @test
+ * @run
+ */
+
+
+// try various Java.extend cases
+
+// Single interface
+var runReached = false;
+var r = new (Java.extend(java.lang.Runnable)) {
+    run: function() {
+        runReached = true;
+    }
+};
+
+r.run();
+if (! runReached) {
+    fail("run was not called");
+}
+
+if (! (r instanceof java.lang.Runnable)) {
+    fail("r is not a Runnable");
+}
+
+// Multiple intefaces
+var runReached = false;
+var actionPerformedReached = false;
+
+var obj = new (Java.extend(java.awt.event.ActionListener, java.lang.Runnable)) {
+    actionPerformed : function(e) {
+        actionPerformedReached = true;
+    },
+
+    run: function() {
+        runReached = true;
+    }
+};
+
+obj.actionPerformed(null);
+if (! actionPerformedReached) {
+    fail("actionPerformed was not called");
+}
+
+obj.run();
+if (! runReached) {
+    fail("run was not called");
+}
+
+if (! (obj instanceof java.lang.Runnable)) {
+    fail("obj is not a Runnable");
+}
+
+if (! (obj instanceof java.awt.event.ActionListener)) {
+    fail("obj is not an ActionListener");
+}
+
+// Single class
+var obj = new (Java.extend(java.lang.Object)) {
+    toString: function() { return "I am an Object"; }
+};
+
+if (! (obj instanceof java.lang.Object)) {
+    fail("obj is not an instance of java.lang.Object");
+}
+
+if (obj.toString() != "I am an Object") {
+    fail("Object.toString did not get called");
+}
+
+// Single class and single interface
+var runReached = false;
+var obj = new (Java.extend(java.lang.Object, java.lang.Runnable)) {
+    run: function() {
+        runReached = true;
+    },
+
+    hashCode: function() {
+        return 12;
+    }
+};
+
+obj.run();
+if (! runReached) {
+    fail("run was not called");
+}
+
+if (obj.hashCode() != 12) {
+    fail("hashCode does not return 12");
+}
diff --git a/nashorn/test/script/basic/JDK-8007215.js b/nashorn/test/script/basic/JDK-8007215.js
new file mode 100644
index 0000000..0dbd718
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007215.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * Varargs based on too many parameters broke. Regression test.
+ * 
+ * @test
+ * @run
+ */
+
+function f() {
+    var sum = 0;
+    for (var i = 0; i < arguments.length; i++) {
+	var a = arguments[i];
+	sum += a;
+    }
+    return sum;
+} 
+
+var res;
+
+res = f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249);
+
+print(res);
+
+res = f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250);
+
+print(res);
+
+res = f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251);
+
+print(res);
diff --git a/nashorn/test/script/basic/JDK-8007215.js.EXPECTED b/nashorn/test/script/basic/JDK-8007215.js.EXPECTED
new file mode 100644
index 0000000..5cf89c2
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007215.js.EXPECTED
@@ -0,0 +1,3 @@
+31125
+31375
+31626
diff --git a/nashorn/test/script/basic/JDK-8007460.js b/nashorn/test/script/basic/JDK-8007460.js
new file mode 100644
index 0000000..7dc4c31
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007460.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8007460: code generation error for variable-argument function that has a var-assignment to one of its parameters
+ *
+ * @test
+ * @run
+ */
+
+function f(y) {
+  print(y)
+  print(arguments[0])
+
+  var y = 1
+
+  print(y)
+  print(arguments[0])
+}
+f(2)
\ No newline at end of file
diff --git a/nashorn/test/script/basic/JDK-8007460.js.EXPECTED b/nashorn/test/script/basic/JDK-8007460.js.EXPECTED
new file mode 100644
index 0000000..74cd8c6
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007460.js.EXPECTED
@@ -0,0 +1,4 @@
+2
+2
+1
+1
diff --git a/nashorn/test/script/basic/JDK-8007522.js b/nashorn/test/script/basic/JDK-8007522.js
new file mode 100644
index 0000000..855d7d1
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007522.js
@@ -0,0 +1,36 @@
+/*
+ * 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-8007522: IllegalStateException thrown from String.prototype.search function
+ *
+ * @test
+ * @run
+ */
+
+var str = "hello";
+// search used to result in IllegalStateException
+if (str.search(/foo/g) != -1) {
+    fail("String.prototype.search failed");
+}
+
diff --git a/nashorn/test/script/basic/JDK-8007523.js b/nashorn/test/script/basic/JDK-8007523.js
new file mode 100644
index 0000000..2a97ce2
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007523.js
@@ -0,0 +1,36 @@
+/*
+ * 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-8007523: VerifyError on script that uses regular expression literals with ternary operator 
+ *
+ * @test
+ * @run
+ */
+
+var flag = true;
+
+// used to throw VerifyError because of the following ternary operator
+if (String(flag? /bar1/ : /bar2/) != '/bar1/') {
+    fail("ternary operator failed to pass right value");
+}
diff --git a/nashorn/test/script/basic/JDK-8007619.js b/nashorn/test/script/basic/JDK-8007619.js
new file mode 100644
index 0000000..2c91f9c
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007619.js
@@ -0,0 +1,49 @@
+/*
+ * 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-8007619: Add support for deprecated properties of RegExp constructor
+ *
+ * @test
+ * @run
+ */
+
+
+var emailPattern = /(\w+)@(\w+)\.(\w+)/g;
+var input= "Please send mail to foo@acme.com and bar@gov.in ASAP!";
+
+var match = emailPattern.exec(input);
+
+while (match != null) {
+    print("Match = " + match);
+    print("RegExp.lastMatch = " + RegExp.lastMatch);
+   
+    print("RegExp.$1 = " + RegExp.$1);
+    print("RegExp.$2 = " + RegExp.$2);
+    print("RegExp.$3 = " + RegExp.$3);
+ 
+    print("RegExp.lastParen = " + RegExp.lastParen)
+    print("RegExp.input = " + RegExp.input);
+
+    match = emailPattern.exec(input);
+}
diff --git a/nashorn/test/script/basic/JDK-8007619.js.EXPECTED b/nashorn/test/script/basic/JDK-8007619.js.EXPECTED
new file mode 100644
index 0000000..a440f1d
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007619.js.EXPECTED
@@ -0,0 +1,14 @@
+Match = foo@acme.com,foo,acme,com
+RegExp.lastMatch = foo@acme.com
+RegExp.$1 = foo
+RegExp.$2 = acme
+RegExp.$3 = com
+RegExp.lastParen = com
+RegExp.input = Please send mail to foo@acme.com and bar@gov.in ASAP!
+Match = bar@gov.in,bar,gov,in
+RegExp.lastMatch = bar@gov.in
+RegExp.$1 = bar
+RegExp.$2 = gov
+RegExp.$3 = in
+RegExp.lastParen = in
+RegExp.input = Please send mail to foo@acme.com and bar@gov.in ASAP!
diff --git a/nashorn/test/script/basic/JDK-8007718.js b/nashorn/test/script/basic/JDK-8007718.js
new file mode 100644
index 0000000..fce5d8c
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007718.js
@@ -0,0 +1,55 @@
+/*
+ * 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-8007718: Make static RegExp properties fully compatible to other engines
+ *
+ * @test
+ * @run
+ */
+
+function dumpRegExpProperties() {
+    for (var p in RegExp) {
+        print(p, RegExp[p], typeof RegExp[p]);
+    }
+}
+
+dumpRegExpProperties();
+
+/abc/.exec("xyz");
+dumpRegExpProperties();
+
+/(b)(a)(r)/gmi.exec("FOOBARfoo");
+dumpRegExpProperties();
+
+"abcdefghijklmnopq".match(/(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)/);
+dumpRegExpProperties();
+
+"abcabcabcABCabcABC".split(/(b)/i);
+dumpRegExpProperties();
+
+"foobarfoo".search(/bar/);
+dumpRegExpProperties();
+
+/abc/.exec("xyz");
+dumpRegExpProperties();
diff --git a/nashorn/test/script/basic/JDK-8007718.js.EXPECTED b/nashorn/test/script/basic/JDK-8007718.js.EXPECTED
new file mode 100644
index 0000000..9ffbd3c
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007718.js.EXPECTED
@@ -0,0 +1,105 @@
+input  string
+multiline false boolean
+lastMatch  string
+lastParen  string
+leftContext  string
+rightContext  string
+$1  string
+$2  string
+$3  string
+$4  string
+$5  string
+$6  string
+$7  string
+$8  string
+$9  string
+input  string
+multiline false boolean
+lastMatch  string
+lastParen  string
+leftContext  string
+rightContext  string
+$1  string
+$2  string
+$3  string
+$4  string
+$5  string
+$6  string
+$7  string
+$8  string
+$9  string
+input FOOBARfoo string
+multiline false boolean
+lastMatch BAR string
+lastParen R string
+leftContext FOO string
+rightContext foo string
+$1 B string
+$2 A string
+$3 R string
+$4  string
+$5  string
+$6  string
+$7  string
+$8  string
+$9  string
+input abcdefghijklmnopq string
+multiline false boolean
+lastMatch abcdefghijk string
+lastParen k string
+leftContext  string
+rightContext lmnopq string
+$1 a string
+$2 b string
+$3 c string
+$4 d string
+$5 e string
+$6 f string
+$7 g string
+$8 h string
+$9 i string
+input abcabcabcABCabcABC string
+multiline false boolean
+lastMatch B string
+lastParen B string
+leftContext abcabcabcABCabcA string
+rightContext C string
+$1 B string
+$2  string
+$3  string
+$4  string
+$5  string
+$6  string
+$7  string
+$8  string
+$9  string
+input foobarfoo string
+multiline false boolean
+lastMatch bar string
+lastParen  string
+leftContext foo string
+rightContext foo string
+$1  string
+$2  string
+$3  string
+$4  string
+$5  string
+$6  string
+$7  string
+$8  string
+$9  string
+input foobarfoo string
+multiline false boolean
+lastMatch bar string
+lastParen  string
+leftContext foo string
+rightContext foo string
+$1  string
+$2  string
+$3  string
+$4  string
+$5  string
+$6  string
+$7  string
+$8  string
+$9  string
diff --git a/nashorn/test/script/basic/JDK-8007990.js b/nashorn/test/script/basic/JDK-8007990.js
new file mode 100644
index 0000000..7f4f739
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007990.js
@@ -0,0 +1,36 @@
+/*
+ * 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-8007990: Access methods declared on public interfaces implemented by 
+ * non-public classes
+ *
+ * @test
+ * @run
+ */
+
+var p = new Packages.java.io.File("test/script/basic/JDK-8007990.js"); 
+var path = p.toPath(); 
+var basicView = Packages.java.nio.file.Files.getFileAttributeView(path, Packages.java.nio.file.attribute.BasicFileAttributeView.class); 
+// We just want to confirm we can access the readAttributes() function
+print(basicView.readAttributes().directory);
diff --git a/nashorn/test/script/basic/JDK-8007990.js.EXPECTED b/nashorn/test/script/basic/JDK-8007990.js.EXPECTED
new file mode 100644
index 0000000..c508d53
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8007990.js.EXPECTED
@@ -0,0 +1 @@
+false
diff --git a/nashorn/test/script/basic/JDK-8008197.js b/nashorn/test/script/basic/JDK-8008197.js
new file mode 100644
index 0000000..e77a13a
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008197.js
@@ -0,0 +1,69 @@
+/*
+ * 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-8008197: Cross script engine function calls do not work as expected
+ *
+ * @test
+ * @run
+ */
+
+
+var m = new javax.script.ScriptEngineManager();
+var e = m.getEngineByName("nashorn");
+
+var obj = {
+    func: function(str) { 
+        return /hello/.exec(str);
+    }
+};
+
+// set our object as object to the engine created
+e.put("obj", obj);
+
+// try to invoke method from the other engine
+if (e.eval("obj.func('hello')") == null) {
+    fail("FAILED: #1 obj.func('hello') returns null");
+}
+
+// define an object in the engine
+ e.eval("var foo = { callMe: function(callback) { return callback() } }");
+
+// try to invoke a script method from here but callback is from this engine
+var res = e.invokeMethod(e.get("foo"), "callMe", function() {
+    return /nashorn/;
+});
+
+if (! res.exec("nashorn")) {
+    fail("FAILED: #2 /nashorn/ does not match 'nashorn'");
+}
+
+// invoke a script method from here with callback from this engine.
+// This uses JSObject.call interface
+res = e.get("foo").callMe(function() {
+    return /ecmascript/;
+});
+
+if (! res.exec("ecmascript")) {
+    fail("FAILED: #3 /ecmascript/ does not match 'ecmascript'");
+}
diff --git a/nashorn/test/script/basic/JDK-8008198.js b/nashorn/test/script/basic/JDK-8008198.js
new file mode 100644
index 0000000..745cea7
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008198.js
@@ -0,0 +1,55 @@
+/*
+ * 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-8008198 : java.lang.AssertionError: Invalid break target class jdk.nashorn.internal.ir.TryNode
+ *
+ * @test
+ * @run
+ */
+
+a: try {
+    print("try");
+    break a;
+    print("wrong");
+} catch (e) {
+    print("error");
+} finally {
+    print("finally");
+}
+print("done");
+
+a: b: if (true) {
+   c: d: with({}) {
+      print("with");
+      break c;
+      print("wrong");
+   }
+   print("if");
+   break a;
+   print("wrong");
+}
+print("done");
+
+
+
diff --git a/nashorn/test/script/basic/JDK-8008198.js.EXPECTED b/nashorn/test/script/basic/JDK-8008198.js.EXPECTED
new file mode 100644
index 0000000..a7350d7
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008198.js.EXPECTED
@@ -0,0 +1,6 @@
+try
+finally
+done
+with
+if
+done
diff --git a/nashorn/test/script/basic/JDK-8008206.js b/nashorn/test/script/basic/JDK-8008206.js
new file mode 100644
index 0000000..be84f51
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008206.js
@@ -0,0 +1,36 @@
+/*
+ * 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-8008026 : allInteger case in Switch nodes requiers integer literals only
+ *
+ * @test
+ * @run
+ */
+
+var x = 1; 
+
+switch (x) { 
+  case foo = false, 1: 
+     print("ok"); 
+} 
diff --git a/nashorn/test/script/basic/JDK-8008206.js.EXPECTED b/nashorn/test/script/basic/JDK-8008206.js.EXPECTED
new file mode 100644
index 0000000..9766475
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008206.js.EXPECTED
@@ -0,0 +1 @@
+ok
diff --git a/nashorn/test/script/basic/JDK-8008215.js b/nashorn/test/script/basic/JDK-8008215.js
new file mode 100644
index 0000000..691b9a4
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008215.js
@@ -0,0 +1,41 @@
+/*
+ * 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-8008215 : break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
+ *
+ * @test
+ * @run
+ */
+
+a: try {
+    print("try");
+    throw new Error();
+} catch (e) {
+    print("catch");
+    break a;
+    print("error");
+} finally {
+    print("finally");
+}
+print("done");
diff --git a/nashorn/test/script/basic/JDK-8008215.js.EXPECTED b/nashorn/test/script/basic/JDK-8008215.js.EXPECTED
new file mode 100644
index 0000000..a708873
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008215.js.EXPECTED
@@ -0,0 +1,4 @@
+try
+catch
+finally
+done
diff --git a/nashorn/test/script/basic/JDK-8008298.js b/nashorn/test/script/basic/JDK-8008298.js
new file mode 100644
index 0000000..4f1fd1a
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008298.js
@@ -0,0 +1,111 @@
+/*
+ * 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-8008298: Add tests to cover specialized versions of Math functions.
+ * Excerise all specialized Math functions with various literal values.
+ *
+ * @test
+ * @run
+ */
+
+if (Math.abs(-88) != 88) {
+    fail("Math.abs for int value");
+}
+
+if (Math.abs(-2147483648) != 2147483648) {
+    fail("Math.abs failed for long value");
+}
+
+if (Math.acos(1.0) != 0) {
+    fail("Math.acos failed on double value");
+}
+
+if (Math.asin(0.0) != 0) {
+    fail("Math.asin failed on double value");
+}
+
+if (Math.atan(0.0) != 0) {
+    fail("Math.atan failed on double value");
+}
+
+if (Math.ceil(1) != 1) {
+    fail("Math.ceil failed on int value");
+}
+
+if (Math.ceil(2147483648) != 2147483648) {
+    fail("Math.ceil failed on long value");
+}
+
+if (Math.ceil(-0.3) != 0) {
+    fail("Math.ceil failed on double value");
+}
+
+if (Math.floor(1) != 1) {
+    fail("Math.floor failed on int value");
+}
+
+if (Math.floor(2147483648) != 2147483648) {
+    fail("Math.floor failed on long value");
+}
+
+if (Math.floor(0.3) != 0) {
+    fail("Math.floor failed on double value");
+}
+
+if (Math.log(1.0) != 0) {
+    fail("Math.log failed on double value");
+}
+
+if (Math.max(2, 28) != 28) {
+    fail("Math.max failed for int values");
+}
+
+if (Math.max(2147483649, 2147483648) != 2147483649) {
+    fail("Math.max failed for long values");
+}
+
+if (Math.max(0.0, -2.5) != 0.0) {
+    fail("Math.max failed for double values");
+}
+
+if (Math.min(2, 28) != 2) {
+    fail("Math.min failed for int values");
+}
+
+if (Math.min(2147483649, 2147483648) != 2147483648) {
+    fail("Math.min failed for long values");
+}
+
+if (Math.min(0.0, 2.5) != 0.0) {
+    fail("Math.min failed for double values");
+}
+
+if (Math.sqrt(4) != 2) {
+    fail("Math.sqrt failed for int value");
+}
+
+if (Math.tan(0.0) != 0.0) {
+    fail("Math.tan failed for double value");
+}
diff --git a/nashorn/test/script/basic/JDK-8008370.js b/nashorn/test/script/basic/JDK-8008370.js
new file mode 100644
index 0000000..5e05bec
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008370.js
@@ -0,0 +1,44 @@
+/*
+ * 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-8008370: coffee script compiler doesn't work with Nashorn
+ *
+ * @test
+ * @run
+ */
+
+print(/\sx/.exec(" x"));
+print(/[a\s]x/.exec(" x"));
+print(/[a\s]x/.exec("ax"));
+print(/[^a\s]x/.exec("bx"));
+print(/[^a\s]x/.exec("ax"));
+print(/[^a\s]x/.exec(" x"));
+
+print(/\Sx/.exec("ax"));
+print(/[a\S]x/.exec("ax"));
+print(/[a\S]x/.exec("xx"));
+print(/[^a\S]x/.exec("ax"));
+print(/[^a\S]x/.exec("bx"));
+print(/[^\n\S]x/.exec(" x"));
+print(/[^ \S]x/.exec(" x"));
diff --git a/nashorn/test/script/basic/JDK-8008370.js.EXPECTED b/nashorn/test/script/basic/JDK-8008370.js.EXPECTED
new file mode 100644
index 0000000..42269b4
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008370.js.EXPECTED
@@ -0,0 +1,13 @@
+ x
+ x
+ax
+bx
+null
+null
+ax
+ax
+xx
+null
+null
+ x
+null
diff --git a/nashorn/test/script/basic/JDK-8008448.js b/nashorn/test/script/basic/JDK-8008448.js
new file mode 100644
index 0000000..d5ffbd4
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008448.js
@@ -0,0 +1,48 @@
+/*
+ * 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-8008448: Add coverage test for jdk.nashorn.internal.ir.debug.JSONWriter
+ * Ensure that all parseable files can be parsed using parser API.
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+var File = Java.type("java.io.File");
+var FilenameFilter = Java.type("java.io.FilenameFilter");
+var Source = Java.type("jdk.nashorn.internal.runtime.Source")
+
+// Filter out non .js files
+var files = new File(__DIR__).listFiles(new FilenameFilter() {
+    accept: function(f, n) { return n.endsWith(".js") }
+});
+
+// load parser API
+load("nashorn:parser.js");
+
+// parse each file to make sure it does not result in exception
+for each (var f in files) {
+    parse(new Source(f.toString(), f).getString());
+}
diff --git a/nashorn/test/script/basic/JDK-8008554.js b/nashorn/test/script/basic/JDK-8008554.js
new file mode 100644
index 0000000..0cbe8b8
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8008554.js
@@ -0,0 +1,36 @@
+/*
+ * 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-8008554: Try loading another output free test in this dir both as file and as url
+ *
+ * @test
+ * @run
+ */
+
+var dir = __DIR__;
+var file = __FILE__.replace("JDK-8008554", "NASHORN-99");
+load(file);
+file = "file://" + __DIR__ + "NASHORN-99.js";
+load(file);
diff --git a/nashorn/test/script/basic/JDK-8009553.js b/nashorn/test/script/basic/JDK-8009553.js
new file mode 100644
index 0000000..3617f16
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8009553.js
@@ -0,0 +1,56 @@
+/*
+ * 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-8009553: Object.create(Array.prototype) doesn't respect reset length
+ *
+ * @test
+ * @run
+ */
+
+var desc = Object.getOwnPropertyDescriptor(Array.prototype, "length");
+if (! desc.writable) {
+    fail("Array.prototype.length is not writable");
+}
+
+if (desc.value != 0) {
+    fail("Array.prototype.length != 0");
+}
+
+var array = Object.create(Array.prototype);
+if (array.hasOwnProperty("length")) {
+    fail("array has 'length'");
+}
+
+if (array.length != 0) {
+    fail("array.length != 0");
+}
+
+array.length = 4;
+if (! array.hasOwnProperty("length")) {
+    fail("array does not have 'length'");
+}
+
+if (array.length != 4) {
+    fail("array.length != 4");
+}
diff --git a/nashorn/test/script/basic/JDK_8005848.js b/nashorn/test/script/basic/JDK_8005848.js
new file mode 100644
index 0000000..d2d07ea
--- /dev/null
+++ b/nashorn/test/script/basic/JDK_8005848.js
@@ -0,0 +1,39 @@
+/*
+ * 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-8005848 : assigning to global toString variable affects Object.prototype.toString 
+ *
+ * @test
+ * @run
+ */
+
+toString = function() {
+    print("global's toString called!!");
+}
+
+var obj = {};
+var str = obj.toString();
+if (str != "[object Object]") {
+    print("FAILED: toString does not return expected value");
+}
diff --git a/nashorn/test/script/basic/NASHORN-100.js b/nashorn/test/script/basic/NASHORN-100.js
new file mode 100644
index 0000000..fdea1cf
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-100.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-100 :  return statement that is not within a FunctionBody should result in syntax error.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval("return;");
+    fail("#1 expected SyntaxError got here!");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#2 expected SyntaxError got " + e);
+    }
+    print(e.toString().replace(/\\/g, '/'));
+}
diff --git a/nashorn/test/script/basic/NASHORN-100.js.EXPECTED b/nashorn/test/script/basic/NASHORN-100.js.EXPECTED
new file mode 100644
index 0000000..d183bb3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-100.js.EXPECTED
@@ -0,0 +1,3 @@
+SyntaxError: test/script/basic/NASHORN-100.js#32<eval>:1:0 Invalid return statement
+return;
+^
diff --git a/nashorn/test/script/basic/NASHORN-101.js b/nashorn/test/script/basic/NASHORN-101.js
new file mode 100644
index 0000000..4e83a99
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-101.js
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-101:  switch statement should use === rather than == to compare case values against switch expression.
+ *
+ * @test
+ * @run
+ */
+
+function func(x) {
+    switch(x) {
+        case 0:
+            print("x === 0"); break;
+        case 1:
+            print("x === 1"); break;
+        case true:
+            print("x === true"); break;
+        case false:
+            print("x === false"); break;
+        case null:
+            print("x === null"); break;
+        case undefined:
+            print("x === undefined"); break;
+        default:
+            print("default case x " + x); break;
+    }
+}
+
+func(0);
+func(1);
+func(2);
+func("hello");
+func(null);
+func(undefined);
+func(true);
+func(false);
+func({});
diff --git a/nashorn/test/script/basic/NASHORN-101.js.EXPECTED b/nashorn/test/script/basic/NASHORN-101.js.EXPECTED
new file mode 100644
index 0000000..7692a07
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-101.js.EXPECTED
@@ -0,0 +1,9 @@
+x === 0
+x === 1
+default case x 2
+default case x hello
+x === null
+x === undefined
+x === true
+x === false
+default case x [object Object]
diff --git a/nashorn/test/script/basic/NASHORN-102.js b/nashorn/test/script/basic/NASHORN-102.js
new file mode 100644
index 0000000..cc388dd
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-102.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-102 :  if "prototype" property is not an Object, [[HasInstance]] should throw TypeError.
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+}
+func.prototype ="hello";
+
+try {
+    print({} instanceof func);
+    fail("#1 should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#2 TypeError expected got " + e);
+    }
+    print(e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-102.js.EXPECTED b/nashorn/test/script/basic/NASHORN-102.js.EXPECTED
new file mode 100644
index 0000000..96a7709
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-102.js.EXPECTED
@@ -0,0 +1,2 @@
+TypeError: "prototype" of function func() {
+} is not an Object, it is hello
diff --git a/nashorn/test/script/basic/NASHORN-103.js b/nashorn/test/script/basic/NASHORN-103.js
new file mode 100644
index 0000000..ddce596
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-103.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-103 :  "Object" called as function with 'undefined' or 'null' argument should work like new Object().
+ *
+ * @test
+ * @run
+ */
+
+function check(obj) {
+    if (obj === null || obj === undefined) {
+        throw new Error("new Object() should have been called");
+    }
+}
+
+check(Object(null));
+check(Object(undefined));
+check(Object());
diff --git a/nashorn/test/script/basic/NASHORN-104.js b/nashorn/test/script/basic/NASHORN-104.js
new file mode 100644
index 0000000..c97b6bc
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-104.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-104 :  number type inferred for a global var for a local assignment
+ *
+ * @test
+ * @run
+ */
+
+var p = { toString: function() { p = 1; return "hello" } };
+print("typeof(p) = " + typeof p);
+print(p.toString());
+print("typeof(p) = " + typeof p);
+print("p = " + p);
diff --git a/nashorn/test/script/basic/NASHORN-104.js.EXPECTED b/nashorn/test/script/basic/NASHORN-104.js.EXPECTED
new file mode 100644
index 0000000..da42592
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-104.js.EXPECTED
@@ -0,0 +1,4 @@
+typeof(p) = object
+hello
+typeof(p) = number
+p = 1
diff --git a/nashorn/test/script/basic/NASHORN-105.js b/nashorn/test/script/basic/NASHORN-105.js
new file mode 100644
index 0000000..f26710d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-105.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-105 :  parseFloat function is not spec. compliant.
+ * 
+ * @test
+ * @run
+ */
+
+print(parseFloat("3.14xyz"));
+print(parseFloat("2.18 43.4543"));
+print(parseFloat("2.9e8E-45"));
+print(parseFloat("55654.6756.4546"));
+print(parseFloat("343e"));
+print(parseFloat("343e+"));
+print(parseFloat("343e-"));
+print(parseFloat("343e+35"));
+print(parseFloat("Infinity1"));
+print(parseFloat("-Infinity1"));
+print(parseFloat("1ex"));
+print(parseFloat("2343+"));
+print(parseFloat("2ex"));
+
+// invalid stuff
+print(parseFloat(""));
+print(parseFloat("+"));
+print(parseFloat("-"));
+print(parseFloat("e"));
+print(parseFloat("sjdfhdsj"));
diff --git a/nashorn/test/script/basic/NASHORN-105.js.EXPECTED b/nashorn/test/script/basic/NASHORN-105.js.EXPECTED
new file mode 100644
index 0000000..19ef4a8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-105.js.EXPECTED
@@ -0,0 +1,18 @@
+3.14
+2.18
+290000000
+55654.6756
+343
+343
+343
+3.43e+37
+Infinity
+-Infinity
+1
+2343
+2
+NaN
+NaN
+NaN
+NaN
+NaN
diff --git a/nashorn/test/script/basic/NASHORN-106.js b/nashorn/test/script/basic/NASHORN-106.js
new file mode 100644
index 0000000..e5a9c61
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-106.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-106 :  parseInt function is not spec. compliant
+ *
+ * @test
+ * @run
+ */
+
+print(parseInt("23432"));
+print(parseInt("234jdhfdjs"));
+print(parseInt("0xFEEE"));
+print(parseInt("0xFFgarbage"));
+print(parseInt("\u0009-1"));
+print(parseInt("2343.34534.34534"));
+print(parseInt("23", Number.POSITIVE_INFINITY));
+print(parseInt("23", 8));
+print(parseInt("11111", 2));
diff --git a/nashorn/test/script/basic/NASHORN-106.js.EXPECTED b/nashorn/test/script/basic/NASHORN-106.js.EXPECTED
new file mode 100644
index 0000000..2b05b0a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-106.js.EXPECTED
@@ -0,0 +1,9 @@
+23432
+234
+65262
+255
+-1
+2343
+23
+19
+31
diff --git a/nashorn/test/script/basic/NASHORN-107.js b/nashorn/test/script/basic/NASHORN-107.js
new file mode 100644
index 0000000..2aeb5dc
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-107.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-107 :  toJSON of undefined should be "undefined"
+ *
+ * @test
+ * @run
+ */
+
+if (JSON.stringify(undefined) !== undefined) {
+    fail("JSON.stringify(undefined) is not undefined");
+}
diff --git a/nashorn/test/script/basic/NASHORN-108.js b/nashorn/test/script/basic/NASHORN-108.js
new file mode 100644
index 0000000..e12096b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-108.js
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-109 :  line number in stack trace is incorrect in exceptions from scripts loaded via load()
+ *
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "NASHORN-109.js");
diff --git a/nashorn/test/script/basic/NASHORN-108.js.EXPECTED b/nashorn/test/script/basic/NASHORN-108.js.EXPECTED
new file mode 100644
index 0000000..59e90f6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-108.js.EXPECTED
@@ -0,0 +1,3 @@
+runScript 33
+runScript 32
+done
diff --git a/nashorn/test/script/basic/NASHORN-109.js b/nashorn/test/script/basic/NASHORN-109.js
new file mode 100644
index 0000000..b05e0f1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-109.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-109 :  line number in stack trace is incorrect in exceptions from scripts loaded via load()
+ *
+ * @test
+ * @run
+ */
+
+try {
+    if (typeof foo == 'undefined') {
+        throw new Error("error");
+    }
+} catch (e) {
+    for (i in e.stack) { 
+        print(e.stack[i].methodName + ' ' + e.stack[i].lineNumber);
+    }
+}
+
+// just some code at the end.. original test involved
+// line numer of the last line always. Just to check the same..
+print("done");
diff --git a/nashorn/test/script/basic/NASHORN-109.js.EXPECTED b/nashorn/test/script/basic/NASHORN-109.js.EXPECTED
new file mode 100644
index 0000000..fca137e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-109.js.EXPECTED
@@ -0,0 +1,2 @@
+runScript 33
+done
diff --git a/nashorn/test/script/basic/NASHORN-11.js b/nashorn/test/script/basic/NASHORN-11.js
new file mode 100644
index 0000000..ca8565f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-11.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-11 :  undefined == null |- false
+ *
+ * @test
+ * @run
+ */
+
+var data;
+print("data = " + data);
+if (data == null)  {
+    print("data == null");
+} else {
+    print("FAIL: data != null !");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-11.js.EXPECTED b/nashorn/test/script/basic/NASHORN-11.js.EXPECTED
new file mode 100644
index 0000000..5d47de5
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-11.js.EXPECTED
@@ -0,0 +1,2 @@
+data = undefined
+data == null
diff --git a/nashorn/test/script/basic/NASHORN-111.js b/nashorn/test/script/basic/NASHORN-111.js
new file mode 100644
index 0000000..4b8347c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-111.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-111 :  ClassCastException from JSON.stringify
+ *
+ * @test
+ * @run
+ */
+
+try {
+    throw new TypeError("type error");
+} catch (e) {
+    // This used to throw ClassCastException 
+    // ThrowException cannot be cast to ScriptObject
+    print(JSON.stringify(e));
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-111.js.EXPECTED b/nashorn/test/script/basic/NASHORN-111.js.EXPECTED
new file mode 100644
index 0000000..287f255
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-111.js.EXPECTED
@@ -0,0 +1 @@
+{"message":"type error"}
diff --git a/nashorn/test/script/basic/NASHORN-113.js b/nashorn/test/script/basic/NASHORN-113.js
new file mode 100644
index 0000000..d90d1fb
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-113.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-113: variable declaration with initialization should set type to non void
+ *
+ * @test
+ * @run
+ */
+
+var value = "hello";
+print(value);
+value = 12;
+print(value);
diff --git a/nashorn/test/script/basic/NASHORN-113.js.EXPECTED b/nashorn/test/script/basic/NASHORN-113.js.EXPECTED
new file mode 100644
index 0000000..eeeb008
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-113.js.EXPECTED
@@ -0,0 +1,2 @@
+hello
+12
diff --git a/nashorn/test/script/basic/NASHORN-114.js b/nashorn/test/script/basic/NASHORN-114.js
new file mode 100644
index 0000000..0326921
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-114.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-114 :  String.fromCharCode should use ToUInt16 as per the spec.
+ *
+ * @test
+ * @run
+ */
+
+if (String.fromCharCode(4294967294).charCodeAt(0) !== 65534) {
+    fail("String.fromCharCode(4294967294).charCodeAt(0) !== 65534");
+}
+
+if (String.fromCharCode(Number.POSITIVE_INFINITY).charCodeAt(0) !== 0) {
+    fail("String.fromCharCode(Number.POSITIVE_INFINITY).charCodeAt(0) !== 0");
+}
+
+if (String.fromCharCode(0x0000).charCodeAt(0) !== 0) {
+    fail("String.fromCharCode(0x0000).charCodeAt(0) !== 0");
+}
+
+if (String.fromCharCode(65, 66, 67, 68) !== "ABCD") {
+    fail("String.fromCharCode(65, 66, 67, 68) !== 'ABCD'");
+}
diff --git a/nashorn/test/script/basic/NASHORN-115.js b/nashorn/test/script/basic/NASHORN-115.js
new file mode 100644
index 0000000..924a9a2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-115.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-115 :  "this" in eval'-ed code refers to wrong object
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+   eval("print(this)");
+}
+
+func();
+
+var obj = {};
+obj.func = func;
+obj.func();
+
+var f = new Function("print(this)");
+f();
+
+obj.f = f;
+obj.f();
+
+// eval of nothing
+print(eval());
diff --git a/nashorn/test/script/basic/NASHORN-115.js.EXPECTED b/nashorn/test/script/basic/NASHORN-115.js.EXPECTED
new file mode 100644
index 0000000..f99e8b6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-115.js.EXPECTED
@@ -0,0 +1,5 @@
+[object global]
+[object Object]
+[object global]
+[object Object]
+undefined
diff --git a/nashorn/test/script/basic/NASHORN-117.js b/nashorn/test/script/basic/NASHORN-117.js
new file mode 100644
index 0000000..9436150
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-117.js
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-117 :  StackOverflowError because of recursive class loading involving LayoutGenerator
+ *
+ * @test
+ * @run
+ */
+
+// The following code results in StackOverflowError 
+
+var i0 = "";
+var o0 = "";
+var i1 = "";
+var o1 = "";
+var i2 = "";
+var o2 = "";
+var i3 = "";
+var o3 = "";
+var i4 = "";
+var o4 = "";
+var i5 = "";
+var o5 = "";
+var i6 = "";
+var o6 = "";
+var i7 = "";
+var o7 = "";
+var i8 = "";
+var o8 = "";
+var i9 = "";
+var o9 = "";
+var i10 = "";
+var o10 = "";
+var i11 = "";
+var o11 = "";
+var i12 = "";
+var o12 = "";
+var i13 = "";
+var o13 = "";
+var i14 = "";
+var o14 = "";
+var i15 = "";
+var o15 = "";
+var i16 = "";
+var o16 = "";
+var i17 = "";
+var o17 = "";
+var i18 = "";
+var o18 = "";
+var i19 = "";
+var o19 = "";
+var i20 = "";
+var o20 = "";
+var i21 = "";
+var o21 = "";
+var i22 = "";
+var o22 = "";
+var i23 = "";
+var o23 = "";
+var i24 = "";
+var o24 = "";
+var i25 = "";
+var o25 = "";
+var i26 = "";
+var o26 = "";
+var i27 = "";
+var o27 = "";
+var i28 = "";
+var o28 = "";
+var i29 = "";
+var o29 = "";
+var i30 = "";
+var o30 = "";
+var i31 = "";
+var o31 = "";
+var i32 = "";
+var o32 = "";
+var i33 = "";
+var o33 = "";
+var i34 = "";
+var o34 = "";
+var i35 = "";
+var o35 = "";
+var i36 = "";
+var o36 = "";
+var i37 = "";
+var o37 = "";
+var i38 = "";
+var o38 = "";
+var i39 = "";
+var o39 = "";
+var i40 = "";
+var o40 = "";
+var i41 = "";
+var o41 = "";
+var i42 = "";
+var o42 = "";
+var i43 = "";
+var o43 = "";
+var i44 = "";
+var o44 = "";
+var i45 = "";
+var o45 = "";
+var i46 = "";
+var o46 = "";
+var i47 = "";
+var o47 = "";
+var i48 = "";
+var o48 = "";
+var i49 = "";
+var o49 = "";
+var i50 = "";
+var o50 = "";
+var i51 = "";
+var o51 = "";
+var i52 = "";
+var o52 = "";
+var i53 = "";
+var o53 = "";
+var i54 = "";
+var o54 = "";
+var i55 = "";
+var o55 = "";
+var i56 = "";
+var o56 = "";
+var i57 = "";
+var o57 = "";
+var i58 = "";
+var o58 = "";
+var i59 = "";
+var o59 = "";
+var i60 = "";
+var o60 = "";
+var i61 = "";
+var o61 = "";
+var i62 = "";
+var o62 = "";
+var i63 = "";
+var o63 = "";
diff --git a/nashorn/test/script/basic/NASHORN-118.js b/nashorn/test/script/basic/NASHORN-118.js
new file mode 100644
index 0000000..d12d861
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-118.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-118 :  Function.prototype.apply should accept "arguments" object 
+ * of another function as second argument.
+ *
+ * @test
+ * @run
+ */
+
+function func(x, y, z) {
+    print("x " + x);
+    print("y " + y);
+    print("z " + z);
+}
+
+
+(function (){
+    func.apply(this,arguments);
+})("hello", "world", "great!");
+
+
diff --git a/nashorn/test/script/basic/NASHORN-118.js.EXPECTED b/nashorn/test/script/basic/NASHORN-118.js.EXPECTED
new file mode 100644
index 0000000..fd53376
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-118.js.EXPECTED
@@ -0,0 +1,3 @@
+x hello
+y world
+z great!
diff --git a/nashorn/test/script/basic/NASHORN-119.js b/nashorn/test/script/basic/NASHORN-119.js
new file mode 100644
index 0000000..c957cdf
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-119.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-119 :  Function.prototype.apply should accept any array-like object as second argument
+ *
+ * @test
+ * @run
+ */
+
+function func(x, y, z) {
+    print(x);
+    print(y);
+    print(z);
+}
+
+func.apply(this, { length: 3, 0: "thus", 1: "spoke", 2: "zarathustra" });
diff --git a/nashorn/test/script/basic/NASHORN-119.js.EXPECTED b/nashorn/test/script/basic/NASHORN-119.js.EXPECTED
new file mode 100644
index 0000000..8ff1946
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-119.js.EXPECTED
@@ -0,0 +1,3 @@
+thus
+spoke
+zarathustra
diff --git a/nashorn/test/script/basic/NASHORN-12.js b/nashorn/test/script/basic/NASHORN-12.js
new file mode 100644
index 0000000..ed04d62
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-12.js
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-12 :  Number does not have methods toFixed, toPrecision, and toExponential.
+ *
+ * @test
+ * @run
+ */
+
+// checks for Number.prototype.toFixed
+
+if (NaN.toFixed() !== "NaN") {
+    fail("#1 NaN.toFixed() is not NaN");
+}
+
+if (new Number(1e21).toFixed(12) !== String(1e21)) {
+    fail("#2 new Number(1e21).toFixed(12) is not String(1e21)");
+}
+
+if (new Number(1.2).toFixed(3) !== "1.200") {
+    fail("#3 new Number(1.2).toFixed(3) is not '1.200'");
+}
+
+if (new Number(1.2542).toFixed(3) !== "1.254") {
+    fail("#4 Number(1.2542).toFixed(3) is not '1.254'");
+}
+
+try {
+    453.334.toFixed(31);
+    fail("#5 toFixed(31) should have thrown RangeError");
+} catch (e) {
+    if (! (e instanceof RangeError)) {
+        fail("#6 toFixed(31) should throw RangeError, got " + e);
+    }
+}
+
+try {
+    3.14.toFixed(-1);
+    fail("#7 toFixed(-1) should have thrown RangeError");
+} catch (e) {
+    if (! (e instanceof RangeError)) {
+        fail("#8 toFixed(-1) should throw RangeError, got " + e);
+    }
+}
+
+
+// checks for Number.prototype.toPrecision
+
+var num = new Number(0.0);
+
+try {
+    num.toPrecision(0);
+    fail("#9: num.toPrecision(0) should have been thrown RangeError");
+} catch (e) {
+    if (! (e instanceof RangeError)) {
+        fail("#10: RangeError expected, got " + e);
+    }
+}
+
+try {
+    num.toPrecision(22);
+    fail("#11: num.toPrecision(22) should have been thrown RangeError");
+} catch (e) {
+    if (! (e instanceof RangeError)) {
+        fail("#12: RangeError expected, got " + e);
+    }
+}
+
+num = new Number(23.4718);
+
+if (num.toPrecision(1) != "2e+1") {
+    fail("#13: toPrecision(1) gives " + num.toPrecision(1));
+}
+
+if (num.toPrecision(2) != "23") {
+    fail("#14: toPrecision(2) gives " + num.toPrecision(2));
+}
+
+if (num.toPrecision(3) != "23.5") {
+    fail("#15: toPrecision(3) gives " + num.toPrecision(3));
+}
+
+if (num.toPrecision(11) != "23.471800000") {
+    fail("#16: toPrecision(11) gives " + num.toPrecision(11));
+}
+
+if (Infinity.toPrecision(1) != "Infinity") {
+    fail("#17: Infinity.toPrecision(1) gives " + Infinity.toPrecision(1));
+}
+
+if (-Infinity.toPrecision(1) != "-Infinity") {
+    fail("#18: -Infinity.toPrecision(1) gives " + -Infinity.toPrecision(1));
+}
+
+// checks for Number.prototype.toExponential
+
+if (num.toExponential(1) != "2.3e+1") {
+    fail("#20: toExponential(1) gives " + num.toExponential(1));
+}
+
+if (num.toExponential(2) != "2.35e+1") {
+    fail("#21: toExponential(2) gives " + num.toExponential(2));
+}
+
+if (num.toExponential(3) != "2.347e+1") {
+    fail("#22: toExponential(3) gives " + num.toExponential(3));
+}
+
+if (num.toExponential(11) != "2.34718000000e+1") {
+    fail("#23: toExponential(11) gives " + num.toExponential(11));
+}
+
+if (Infinity.toExponential(1) != "Infinity") {
+    fail("#24: Infinity.toExponential(1) gives " + Infinity.toExponential(1));
+}
+
+if (-Infinity.toExponential(1) != "-Infinity") {
+    fail("#25: -Infinity.toExponential(1) gives " + -Infinity.toExponential(1));
+}
+
+if (NaN.toExponential(1) != "NaN") {
+    fail("#26: NaN.toExponential(1) gives " + NaN.toExponential(1));
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-120.js b/nashorn/test/script/basic/NASHORN-120.js
new file mode 100644
index 0000000..b424f3e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-120.js
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-120 :  String.prototype.split does not convert the input arguments in the order specified
+ *
+ * @test
+ * @run
+ */
+
+var obj1 = {
+    toString: function() {
+        throw "inside obj1.toString";
+    }
+};
+
+var obj2 = {
+    valueOf: function() {
+        throw "inside obj2.valueOf";
+    }
+};
+
+try {
+    "hello".split(obj1, obj2);
+    fail('#1: split not throwing exception on input conversion');
+} catch (e) {
+    if (e !== "inside obj2.valueOf") {
+        fail('#2: Exception === "obj2.valueOf" got: '+e);
+    }
+}
+
+try {
+    "hello".split(obj1, 10);
+    fail('#3: split not throwing exception on input conversion');
+} catch (e) {
+    if (e !== "inside obj1.toString") {
+        fail('#4: Exception === "obj1.toString" got: '+e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-122.js b/nashorn/test/script/basic/NASHORN-122.js
new file mode 100644
index 0000000..a8863a9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-122.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-122 :  Hex string to number conversion does not work as expected
+ *
+ * @test
+ * @run
+ */
+
+function num(str) { print("Number('" + str + "') = " + Number(str)); }
+
+num("0x00007");
+num("0xCAFEBABE");
+num("0xFE");
+num("0xEF");
diff --git a/nashorn/test/script/basic/NASHORN-122.js.EXPECTED b/nashorn/test/script/basic/NASHORN-122.js.EXPECTED
new file mode 100644
index 0000000..0d573a0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-122.js.EXPECTED
@@ -0,0 +1,4 @@
+Number('0x00007') = 7
+Number('0xCAFEBABE') = 3405691582
+Number('0xFE') = 254
+Number('0xEF') = 239
diff --git a/nashorn/test/script/basic/NASHORN-126.js b/nashorn/test/script/basic/NASHORN-126.js
new file mode 100644
index 0000000..dc3f3b3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-126.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-126 - number to ascii conversion
+ *
+ * @test
+ * @run
+ */ 
+
+print(String(1000000000000000000000) === "1e+21");
+print(String(0.000000000100000000000) === "1e-10");
+
+    
diff --git a/nashorn/test/script/basic/NASHORN-126.js.EXPECTED b/nashorn/test/script/basic/NASHORN-126.js.EXPECTED
new file mode 100644
index 0000000..bb101b6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-126.js.EXPECTED
@@ -0,0 +1,2 @@
+true
+true
diff --git a/nashorn/test/script/basic/NASHORN-127.js b/nashorn/test/script/basic/NASHORN-127.js
new file mode 100644
index 0000000..3cd64d2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-127.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-127 :  Exceptions erroneously inherit messages from the last exception thrown.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    try { 
+        throw ReferenceError(17);
+    } catch (e) { 
+        print(e); 
+        throw TypeError(4711); 
+    }
+} catch (e) { print(e); 
+}
diff --git a/nashorn/test/script/basic/NASHORN-127.js.EXPECTED b/nashorn/test/script/basic/NASHORN-127.js.EXPECTED
new file mode 100644
index 0000000..aa70362
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-127.js.EXPECTED
@@ -0,0 +1,2 @@
+ReferenceError: 17
+TypeError: 4711
diff --git a/nashorn/test/script/basic/NASHORN-130.js b/nashorn/test/script/basic/NASHORN-130.js
new file mode 100644
index 0000000..64f275c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-130.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-130 :  prototype comparison throws java class cast exception
+ *
+ * @test
+ * @run
+ */
+
+function Func() {
+}
+
+Func.prototype = Object;
+var f = new Func();
+if (f.prototype !== Object.prototype) {
+    fail("f.prototype should be Object.prototype");
+}
diff --git a/nashorn/test/script/basic/NASHORN-132.js b/nashorn/test/script/basic/NASHORN-132.js
new file mode 100644
index 0000000..f8ad281
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-132.js
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-132 : Implementation of __FILE__ and __LINE__ in lower is incorrect.
+ *
+ * @test
+ * @run
+ */
+
+function printFile() {
+    var idx = __FILE__.lastIndexOf(java.io.File.separator);
+    if (idx < 0) {
+        // separator is "/" when running under ant on windows
+        idx = __FILE__.lastIndexOf("/");
+    }
+    var file = (idx != -1)? __FILE__.substring(idx + 1) : __FILE__;
+    print("file: " + file);
+}
+
+// assignment to global read-only __FILE__ ignored
+__FILE__ = 454;
+printFile();
+
+// assignment to global read-only __LINE__ ignored
+__LINE__ = "hello";
+print("line: " + __LINE__);
+
+var obj = { __FILE__: "obj.__FILE__", __LINE__: "obj.__LINE__" };
+
+// obj.__FILE__ is different from global __FILE__
+print(obj.__FILE__);
+printFile();
+
+// obj.__LINE__ is different from global __LINE__
+print(obj.__LINE__);
+print("line: " + __LINE__);
+
+function func() {
+   // can have local variable of that name
+   var __FILE__ = "local __FILE__ value";
+   print(__FILE__);
+
+   var __LINE__ = "local __LINE__ value";
+   print(__LINE__);
+}
+
+func();
+printFile();
+print("line: " + __LINE__);
diff --git a/nashorn/test/script/basic/NASHORN-132.js.EXPECTED b/nashorn/test/script/basic/NASHORN-132.js.EXPECTED
new file mode 100644
index 0000000..78f7e48
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-132.js.EXPECTED
@@ -0,0 +1,10 @@
+file: NASHORN-132.js
+line: 47
+obj.__FILE__
+file: NASHORN-132.js
+obj.__LINE__
+line: 57
+local __FILE__ value
+local __LINE__ value
+file: NASHORN-132.js
+line: 70
diff --git a/nashorn/test/script/basic/NASHORN-133.js b/nashorn/test/script/basic/NASHORN-133.js
new file mode 100644
index 0000000..f4ddbe6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-133.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-133 :  esacpe and unescape global functions are not implemented
+ *
+ * @test
+ * @run
+ */
+
+
+print("escape is " + (typeof escape) + " with arity " + escape.length);
+print("unescape is " + (typeof unescape) + " with arity " + unescape.length);
+
+// escape tests
+
+print(escape("This is great!"));
+print(escape("What is going on here??"));
+print(escape("\uFFFF\uFFFE\u1FFF"));
+
+// unescape tests
+print(unescape("This%20is%20great%21"));
+print(unescape("What%20is%20going%20on%20here%3F%3F"));
+if (unescape("%uFFFF%uFFFE%u1FFF") != "\uFFFF\uFFFE\u1FFF") {
+    fail("unescape('%uFFFF%uFFFE%u1FFF') does not work");
+}
diff --git a/nashorn/test/script/basic/NASHORN-133.js.EXPECTED b/nashorn/test/script/basic/NASHORN-133.js.EXPECTED
new file mode 100644
index 0000000..5ba986f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-133.js.EXPECTED
@@ -0,0 +1,7 @@
+escape is function with arity 1
+unescape is function with arity 1
+This%20is%20great%21
+What%20is%20going%20on%20here%3F%3F
+%uFFFF%uFFFE%u1FFF
+This is great!
+What is going on here??
diff --git a/nashorn/test/script/basic/NASHORN-135.js b/nashorn/test/script/basic/NASHORN-135.js
new file mode 100644
index 0000000..6ffff06
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-135.js
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-135 : With statements are forbidden in strict mode
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval("'use strict'; with ({}) {}");
+    fail("should have thrown SyntaxError for 'with'");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("expected SyntaxError but got " + e);
+    }
+}
+
+
+try {
+    var f = new Function("func", "'use strict'; with ({}) {}");
+    fail("should have thrown SyntaxError for 'with'");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("expected SyntaxError but got " + e);
+    }
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-136.js b/nashorn/test/script/basic/NASHORN-136.js
new file mode 100644
index 0000000..473a3e1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-136.js
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-136 :  binary addition operator does not work as per the spec.
+ *
+ * @test
+ * @run
+ */
+
+var obj1 = {
+    valueOf: function() {
+        print("obj1.valueOf");
+        return 1;
+    }, 
+
+    toString: function() {
+        print("obj1.toString");
+        return 0;
+    }
+};
+
+print("obj1 is " + obj1);
+print(obj1 + 10);
+
+var obj2 = {
+    valueOf: function() {
+        print("obj2.valueOf");
+        return 2;
+    },
+
+    toString: function() {
+        print("obj2.toString");
+        return "hello";
+    }
+};
+
+print("obj2 is " + obj2);
+print(obj2 + 22);
+
+// valueOf on each object and then add
+print(obj1 + obj2);
+
+var obj3 = {
+    toString: function() {
+        print("obj3.toString");
+        return "world";
+    }
+};
+
+print(obj3 + 12);
+print("hello " + obj3);
+
+print(obj1 + obj3);
+print(obj2 + obj3);
+print(obj3 + obj3);
+
diff --git a/nashorn/test/script/basic/NASHORN-136.js.EXPECTED b/nashorn/test/script/basic/NASHORN-136.js.EXPECTED
new file mode 100644
index 0000000..f09beae
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-136.js.EXPECTED
@@ -0,0 +1,24 @@
+obj1.valueOf
+obj1 is 1
+obj1.valueOf
+11
+obj2.valueOf
+obj2 is 2
+obj2.valueOf
+24
+obj1.valueOf
+obj2.valueOf
+3
+obj3.toString
+world12
+obj3.toString
+hello world
+obj1.valueOf
+obj3.toString
+1world
+obj2.valueOf
+obj3.toString
+2world
+obj3.toString
+obj3.toString
+worldworld
diff --git a/nashorn/test/script/basic/NASHORN-14.js b/nashorn/test/script/basic/NASHORN-14.js
new file mode 100644
index 0000000..83a0a07
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-14.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * NASHORN-14 :  Function.apply and call do not work with varargs in callee.
+ *
+ * @test
+ * @run
+ */
+
+
+function callback() { 
+    print('callback with args ' + Array.prototype.join.apply(arguments))
+}
+
+var cb = callback;
+cb.call(this, 's', 10, 13.1, true, false, null, {}, [], [1,2,{}]);
+cb.apply(this, ['s', 10, 13.1, true, false, null, {}, [], [1,2,{}]]);
diff --git a/nashorn/test/script/basic/NASHORN-14.js.EXPECTED b/nashorn/test/script/basic/NASHORN-14.js.EXPECTED
new file mode 100644
index 0000000..e7f5de3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-14.js.EXPECTED
@@ -0,0 +1,2 @@
+callback with args s,10,13.1,true,false,,[object Object],,1,2,[object Object]
+callback with args s,10,13.1,true,false,,[object Object],,1,2,[object Object]
diff --git a/nashorn/test/script/basic/NASHORN-148.js b/nashorn/test/script/basic/NASHORN-148.js
new file mode 100644
index 0000000..398b09d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-148.js
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-148 :  arguments element deletion/resurrection does not work as expected
+ * 
+ * @test
+ * @run
+ */
+
+
+function func(x) { 
+    print("func.x = " + x);
+    print("func.arguments[0] = " + arguments[0]);
+
+    arguments[0] = "world";
+
+    print("func.x = " + x);
+    print("func.arguments[0] = " + arguments[0]);
+
+    x = "changed x";
+    print("func.x = " + x);
+    print("func.arguments[0] = " + arguments[0]);
+
+    // delete arguments[0]
+    delete arguments[0]; 
+    print("func.x = " + x);
+    print("func.arguments[0] = " + arguments[0]);
+
+    // resurrect arguments[0]
+    arguments[0] = 42;
+    print("func.x = " + x);
+    print("func.arguments[0] = " + arguments[0]);
+
+    x = 33;
+    print("func.x = " + x);
+    print("func.arguments[0] = " + arguments[0]);
+}
+
+func(3.14);
+
+
+// deletion and resurrection of different argument
+function func2(x, y) {
+   delete arguments[0];
+   arguments[0] = 3434;
+   print("func2.x = " + x);
+   print("func2.arguments[0] = " + arguments[0]);
+
+   print("func2.y = " + y);
+   print("func2.arguments[1] = " + arguments[1]);
+
+   y = 54;
+   print("func2.y = " + y);
+   print("func2.arguments[1] = " + arguments[1]);
+
+   arguments[1] = 67;
+   print("func2.y = " + y);
+   print("func2.arguments[1] = " + arguments[1]);
+}
+
+func2(1, 3);
+
diff --git a/nashorn/test/script/basic/NASHORN-148.js.EXPECTED b/nashorn/test/script/basic/NASHORN-148.js.EXPECTED
new file mode 100644
index 0000000..d2f81f9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-148.js.EXPECTED
@@ -0,0 +1,20 @@
+func.x = 3.14
+func.arguments[0] = 3.14
+func.x = world
+func.arguments[0] = world
+func.x = changed x
+func.arguments[0] = changed x
+func.x = changed x
+func.arguments[0] = undefined
+func.x = changed x
+func.arguments[0] = 42
+func.x = 33
+func.arguments[0] = 42
+func2.x = 1
+func2.arguments[0] = 3434
+func2.y = 3
+func2.arguments[1] = 3
+func2.y = 54
+func2.arguments[1] = 54
+func2.y = 67
+func2.arguments[1] = 67
diff --git a/nashorn/test/script/basic/NASHORN-15.js b/nashorn/test/script/basic/NASHORN-15.js
new file mode 100644
index 0000000..895fac6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-15.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-15 :  JSAdapter __call__ does not accept more than 7 args
+ *
+ * @test
+ * @run
+ */
+
+var x = new JSAdapter() {
+    __call__: function(a, b, c, d, e, f, g , h, i, j) {
+        print(a);
+        print(b);
+        print(c);
+        print(d);
+        print(e);
+        print(f);
+        print(g);
+        print(h);
+        print(i);
+        print(j);
+   }
+}
+
+x.foo(11, 12, 13, 14, 15, 16, 17, 18, 19);
diff --git a/nashorn/test/script/basic/NASHORN-15.js.EXPECTED b/nashorn/test/script/basic/NASHORN-15.js.EXPECTED
new file mode 100644
index 0000000..781dba2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-15.js.EXPECTED
@@ -0,0 +1,10 @@
+foo
+11
+12
+13
+14
+15
+16
+17
+18
+19
diff --git a/nashorn/test/script/basic/NASHORN-153.js b/nashorn/test/script/basic/NASHORN-153.js
new file mode 100644
index 0000000..e38c3e1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-153.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-153 : When using property name with a '.' we get ClassFormatError
+ *
+ * @test
+ * @run
+ */
+
+var obj = { "foo.bar" : 344 };
+if (obj["foo.bar"] !== 344) {
+    fail("foo.bar !== 344");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-156.js b/nashorn/test/script/basic/NASHORN-156.js
new file mode 100644
index 0000000..6a111e9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-156.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-156 :  object literal getter function fails only with -scripting mode.
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+var obj = { 
+    get foo() { return 3; } 
+};
+
+if (obj.foo != 3) {
+    throw new Error("obj.foo should be 3 got " + obj.foo);
+}
diff --git a/nashorn/test/script/basic/NASHORN-157.js b/nashorn/test/script/basic/NASHORN-157.js
new file mode 100644
index 0000000..1908d38
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-157.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-157 :  undefined ident as lhs of comma expression should result in ReferenceError
+ *
+ * @test
+ * @run
+ */
+
+try { 
+    print((x, 1));
+    fail("#1 ReferenceError should have been thrown");
+} catch (e) {
+    if (! (e instanceof ReferenceError)) {
+        fail("#2 ReferenceError expected");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-163.js b/nashorn/test/script/basic/NASHORN-163.js
new file mode 100644
index 0000000..d431a3d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-163.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-163 :  Object.keys(o) should only enumerate o's own properties
+ * 
+ * @test
+ * @run
+ */
+
+print(Object.keys({0:'a'}));
+print(Object.keys({0:'a',26:'z'}));
+
+print(Object.keys(['a']));
+print(Object.keys(['a','b',,,'z']));
+
+print(Object.getOwnPropertyNames({0:'a'}));
+print(Object.getOwnPropertyNames({0:'a',26:'z'}));
+
+print(Object.getOwnPropertyNames(['a']));
+print(Object.getOwnPropertyNames(['a','b',,,'z']));
diff --git a/nashorn/test/script/basic/NASHORN-163.js.EXPECTED b/nashorn/test/script/basic/NASHORN-163.js.EXPECTED
new file mode 100644
index 0000000..4708cc6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-163.js.EXPECTED
@@ -0,0 +1,8 @@
+0
+0,26
+0
+0,1,4
+0
+0,26
+0,length
+0,1,4,length
\ No newline at end of file
diff --git a/nashorn/test/script/basic/NASHORN-164.js b/nashorn/test/script/basic/NASHORN-164.js
new file mode 100644
index 0000000..f1b42eb
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-164.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-164 :  JSON.stringify should serialize only own properties of an object (like Object.keys)
+ *
+ * @test
+ * @run
+ */
+
+var obj2 = { bar: 'hello' };
+var obj = Object.create(obj2);
+obj.foo = 22; 
+
+if (JSON.stringify(obj) != '{"foo":22}') {
+    throw Error("expected '{\"foo\":22}' got " + JSON.stringify(obj));
+}
diff --git a/nashorn/test/script/basic/NASHORN-165.js b/nashorn/test/script/basic/NASHORN-165.js
new file mode 100644
index 0000000..fc1008e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-165.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-165 :  Date.prototype.getTimezoneOffset does not return correct value.
+ *
+ * @test
+ * @option -timezone=Asia/Calcutta
+ * @run
+ */
+
+var d = new Date(0);
+if (d.getTimezoneOffset() != -330) {
+    fail("getTimezoneOffset for Asia/Calcutta should be -330");
+}
diff --git a/nashorn/test/script/basic/NASHORN-166.js b/nashorn/test/script/basic/NASHORN-166.js
new file mode 100644
index 0000000..465f159
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-166.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-166 : Parameter of nested catch should not be shared with enclosing catch.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    throw "ex1";
+} catch(ex){
+    try {
+        throw "ex2";
+    } catch(ex) {
+    }
+
+    if (ex !== "ex1") {
+        fail('#1 expected that (ex === "ex1")');
+    }
+
+    if (ex === "ex2") {
+        fail('#2 expected that (ex !== "ex2")');
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-168.js b/nashorn/test/script/basic/NASHORN-168.js
new file mode 100644
index 0000000..138c352
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-168.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-168 :  Object.prototype.toString does not work as per the spec.
+ *
+ * @test
+ * @run
+ */
+
+function printToString(obj) {
+    print(Object.prototype.toString.call(obj));
+}
+
+printToString(null);
+printToString(undefined);
+(function () {
+    printToString(arguments);
+})();
+printToString([]);
+printToString(new Boolean(false));
+printToString(new Date(0));
+printToString(Object);
+printToString(JSON);
+printToString(Math);
+printToString(new Number(0));
+printToString({});
+printToString(/js/);
+printToString(new String(''));
+
+// check the primitives too
+printToString(false);
+printToString(3.14);
+printToString('js');
diff --git a/nashorn/test/script/basic/NASHORN-168.js.EXPECTED b/nashorn/test/script/basic/NASHORN-168.js.EXPECTED
new file mode 100644
index 0000000..2b564af
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-168.js.EXPECTED
@@ -0,0 +1,16 @@
+[object Null]
+[object Undefined]
+[object Arguments]
+[object Array]
+[object Boolean]
+[object Date]
+[object Function]
+[object JSON]
+[object Math]
+[object Number]
+[object Object]
+[object RegExp]
+[object String]
+[object Boolean]
+[object Number]
+[object String]
diff --git a/nashorn/test/script/basic/NASHORN-169.js b/nashorn/test/script/basic/NASHORN-169.js
new file mode 100644
index 0000000..4da5276
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-169.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-169 :  Array.prototype has 'length' property with the initial value of 0.
+ *
+ * @test
+ * @run
+ */
+
+if (Array.prototype.length != 0.0) {
+    fail("Array.prototype.length should be 0.0");
+}
diff --git a/nashorn/test/script/basic/NASHORN-172.js b/nashorn/test/script/basic/NASHORN-172.js
new file mode 100644
index 0000000..607642f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-172.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-172 :  delete of undeclared global variable returns false.
+ *
+ * @test
+ * @run
+ */
+
+if (delete x !== true) { 
+    fail('#1: delete x === true');
+}
+
+if (delete this.x !== true) { 
+    fail('#2: delete this.x === true'); 
+}
+
+var y = 23;
+if (delete y != false) {
+    fail('#3: can delete declared var y');
+}
+
+if (delete this.y != false) {
+    fail('#4: can delete declared var using this.y');
+}
+
+foo = 'hello';
+if (delete foo != true) {
+    fail('#5: can not delete "foo"');
+}
+
+if (typeof foo != 'undefined') {
+    fail('#6: huh? "foo" is not undefined');
+}
diff --git a/nashorn/test/script/basic/NASHORN-173.js b/nashorn/test/script/basic/NASHORN-173.js
new file mode 100644
index 0000000..1ee89f3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-173.js
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-173 : radix is ignored in Number.toString(radix).
+ * @test
+ * @run
+ */
+
+function printNumber(n) {
+    print(n);
+    print(n.toString(10));
+    print(n.toString(undefined));
+    print(n.toString(2));
+    print(n.toString(5));
+    print(n.toString(8));
+    print(n.toString(12));
+    print(n.toString(16));
+    print(n.toString(21));
+    print(n.toString(32));
+    print(n.toString(36));
+    try {
+      n.toString(0);
+    } catch (e) {
+      print(e.name);
+    }
+    try {
+      n.toString(37);
+    } catch (e) {
+      print(e.name);
+    }
+}
+
+printNumber(0);
+printNumber(1);
+printNumber(-10);
+printNumber(255);
+printNumber(255.5);
+printNumber(255.55);
+printNumber(4988883874234);
+printNumber(342234.2);
+printNumber(-32423423.2342);
+printNumber(837423.234765892);
+printNumber(2342344660903453345345);
+printNumber(-0.138789879520123);
+printNumber(10.5);
+printNumber(-10.22);
+printNumber(-32.44);
+printNumber(0.435235);
+printNumber(0.5);
+printNumber(5);
+printNumber(7.5);
diff --git a/nashorn/test/script/basic/NASHORN-173.js.EXPECTED b/nashorn/test/script/basic/NASHORN-173.js.EXPECTED
new file mode 100644
index 0000000..a0781a8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-173.js.EXPECTED
@@ -0,0 +1,247 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+RangeError
+RangeError
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+RangeError
+RangeError
+-10
+-10
+-10
+-1010
+-20
+-12
+-a
+-a
+-a
+-a
+-a
+RangeError
+RangeError
+255
+255
+255
+11111111
+2010
+377
+193
+ff
+c3
+7v
+73
+RangeError
+RangeError
+255.5
+255.5
+255.5
+11111111.1
+2010.2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
+377.4
+193.6
+ff.8
+c3.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+7v.g
+73.i
+RangeError
+RangeError
+255.55
+255.55
+255.55
+11111111.10001100110011001100110011001100110011001101
+2010.2333333333333333333440411420102434041342101041104034013001143430224314314301310104420320003202133421100122004104230444342000330231241324044130122233321334130023440110312044001444303340044410444304021211144032141232022022424112320434100322341303404213222221310110402124214431112112332411023434014304103002212144411141131133023143003244042433323031241103240111400401413411302040044220204120404110040211000132132102021403143342312114213423444210402143320040002200103321132001414102222414121043324141144413423040212044222332333423242104332221204211320030001321441100421000433432414133023323030331302132442444300104222413131313121314202311001010442334040222122442423112344101244234204140224132411112141040321031221043334030133440131340114433001243241124424310333144231341430314413143110444143410334204034402342412420420342010044240033122330340102033421133123130423130122232323041240404343420224342114300141020244220214230001124424040140440142221414221020131130222240101204022212444110341333232431442243120203222021143041341344044221304120304224323221133101041202404211234401203104412231404322342013233241
+377.431463146314632
+193.672497249724a996835599
+ff.8cccccccccd
+c3.bbbbbbbbbbfb3eddce5086cf31jb62fjfe8c02h53ia5d3he85e29f8j5e9j81ag47hjfa84kk6d2khic3a05kg4ii75dgf3kgfbka9439dki0870efe2502ig30h04ah3eb51edcc5f7j17akh7d9hkfcd77487hgi906j20ffcfebf21f37ea658kb3930e70kdga97889ee41f7fe17h5b23j95ikd6gjc0ad32832bdf4590d31b2ahjf31g5032d9gabjkeggka51e31fc4b1275fe2074ii990814g86gkj533j3i3i6hhei22a68e7b9c6af6e5j25dk6c4jbi33hh78198ai82ffc8ga05id48be71hakg3bf8a19a7jj450h5eh1f45dche56a5k6g540j4cgch49740b8ei98hidd8b0f89c1h4idjc3d9gbd9kb60jceg5b6908d5kigd035ahekgbgh7ga52ggbf0cdg160k49i9ij4049gf5hi9ej1ig8hca822a3925gckica5cacd3hac5425j7kg8h17j7j6c7g32fd6047hjdh499ik4ibbdcd77bccff10i0dghggdgc62aea53cigkj9fj624fbhk9ab282g600j5bkd5825086j9j28d874fh1g3bf57aedjh597e7i95ib02dih1j14k76ik149hg33h14i5gec4cb582dfeac2jaeh21k16cc80dbj54iih1ja6k14g011ge6gk1db89k4f7de690fhaac9gbi07fj2835ec1d9e9h04igfd4dcd6b9dg70844a6c8eff0ci412gg0e9ddd863e8fk2dc396bhhik3jb1724i4c172b94309c8efabadj905eahj08ae68ia2e31f3id3gbfk1cc16h10ei09abi5825j7i9jcb96he0ajcjg7de877kig9jh409448kikdb0b20hc678ck8fgkcjjkc2429fgcjd5060g4f6h7744g136g3a346c47ge6b83geiea3j31fija70b81a12f3dj48dfk92268jhc08k94g46df775cciab
+7v.hj6cpj6cq
+73.jssssssstyd5yiwdkxd2t9
+RangeError
+RangeError
+4988883874234
+4988883874234
+4988883874234
+1001000100110010000101001101011000110111010
+1123214213232433414
+110462051530672
+686a6714744a
+48990a6b1ba
+65ij9h9371
+4h68adcdq
+1rnv0ndtm
+RangeError
+RangeError
+342234.2
+342234.2
+342234.2
+1010011100011011010.0011001100110011001100110011001101
+41422414.1000000000000001342010241433444114200132142432402041303144343124404314033411124402321233000412232441103142322421312040313431310141214320111032300332321314244142011033124332134441101413234130443424400441233124103312033344003342031231234004244402400103432441142213041201433143121103302113122214430000232033101142143232322031310211204324000203442332222442230234414230330201023210241014324233433022223341341403404434420441302002000143300411213113341344303444314220004113043133331123013122213114031022233034004243233324442402122203341303321120020131122443421211431014141344142303334034113430420232300030243332131321000213131132210242121302243000244143430144034410410310333414334401133412022003214041043220244020113243011340032342024231112340001321111000042220022343003001310103422110424001033133244313142444321401142214440241100304431011230002202334033340442023132032232310123314123211012140312421213202230400041202243240400441102411231034014420431143303230342223041232043023020403022240123231123103132103110311113310141431301310423222431201020424232441144221403314130421420031301430231330013043003341141
+1234332.146314631464
+146076.249724972562bb6b3
+538da.333333334
+1fk0i.44444444d97k67a746f6926cg2eckb5iibk9bbkh4be8h77i5c82e2he8ei4cg575kg9bfef8d1hjg1k4b5j0jbi6c9hf9ec274k9kb1f771d78k513i32f2453a9a3ab0g3fg52d9agcd4hkbecgd29g2k1ba6e2kdd0j45be0c4i95ak52kc33dg37aii60ck54970hfcjd3198f1hj8gc9d90bid3eid86e32h974c546dg6b0hc4f5fdc89h358gd3f7gbcecg08ech6jgdek48e4376geibcgfeji2aj0fj947h9aehd019ed69af93jd95a3jf83fe51akca0b24e5219cd76ca1d5b795e182j4e2c99hg9b329kgk1c16ff2446k1738f40ki99kk6543d3fek25fbe6acdac8d580ef1g16j7g6817fcbd64e1b98fak99116ah0jh6i685c1kffjec9b0ckb6ad85h8243ggjckfeg5gb7gee06h59ki7hejk59062c92k87d8ekchfjfgjb14775h0c7df336i3g63h9dh5i135kcbi60hiec2b8k52ki5dfd7hfi510aji48f78759d44h3g92h4dfb3k29668j8b72e2f8d608d63f73ga51c45i7g2169agi53e0jbcbeek35ah5e3gc88076657c612j29c2ih1a3c10h35ie59724gjh707h1761gigcac1d3j88909g31h46aja99jh14814h4f422cbcg174bi6f4c05h09eadek08997a7eca2ed5123ghha50i9kj87736hi82e598gc1bc0392g0338132j21hakc7d3a5ah7715651fa175e76dj72k08a4ai428fihc404h7h609b6efa90jk34c378aag183g4d85gg4g7cf0fcai83b19k2714ihhk5i8617d6jd6ddacg29haig74bbgi169i5751g3b04f4ba07e3d5i01326ia025i166j6318i07j1g176efd7e7k9jc92b251fjcaf30ki7fi9735i2hbdje4a9ba4721249d
+ae6q.6cpj6cq
+7c2i.777777841ihi1kyb9
+RangeError
+RangeError
+-32423423.2342
+-32423423.2342
+-32423423.2342
+-1111011101011110111111111.001110111111010010001
+-31300022143.1041141414142400343343342124342141443422002404311420331343043121034332120113013302202303114112140133023421311010433313022224321030130044112330044314031130144100343321412100113001124330301133342444202100010421122434042210202201004132433113333204244311104103024240321140342210022041421300324030121344242131411312002021441104031133014220123042031340323133032133342334301423334442030003033330332320110142244341301214132244301044311134413421332313401240412011031141341202123031121301021400334412010003232122440242231222213422313422210243202140233421113312332102110440331304201134233140133124441114314111014201232432324212032023003112040410430124142043300121010234010221214113223144223014004031000300432441141430132413010441301422443024430410042303330243040042104322220132441423104024103242231142241112003210134030200223101230414042240213314443023023244410124112204242433421231210234304111240434113222222333104100322402030404003404044414111332412134233114041131443204134200013002121041041022000344022230044211240203322412313332003340204304404204121024204042234203121404441301233120042444213423104320001033
+-173536777.1677221
+-aa3767b.29884555646
+-1eebdff.3bf488
+-7jf1ab.4j5j99ce458e7383fdkgh8k20fh07278fd3bgc2d0ii3ce6ece41ega2cbk0afdiee94jj8a1d9993fi8b5iii5bhkf6fhkb221jja956a3ahdef35558e68h02j1966ji2ef64jf907h234hh2354ce9d3g9ad64kba76gb7a007b28a4hc8a37ghhjj0k8k976gc213d299jc51a9bi9k9he38916f35b4113a3i7e36bfcck1e40kc2230be3g9222fkh84fe8e0j1c72gd7j02e3eb0ghk110ec1ge5a500fa8cf4gk52fia8k8c7h80fhj584j1d6b4i1fhkegkjkf24igb712165073ie9ccb83cgb16j39h40263dfd42dhi73dcd2i148kef9e5fe56413bjcbe4hea57adc521ed4aa3fifc60e1ak7ihb7hfi1f9h6j6chg63g4bg33j89377kd9gbe0kh6b2i3addi4fcc1ika38a6dgfh98g6bia1ec3ke42j03k5764a00hb94e9g90g6b10k367h55idai56ji3969hedgb9h715jb46i46jh1h2f6c0hjba4849211ace3a1jbgeii0ibe9h64a08d2fcddba0ig11j0527e7k29eadgh3d9687j237019d69hbe9i0gdd3ba5edi9b2ci4eifa9h6f4j892cgh0ei42jkc8a13170e2k82jfd3b8gb6dje8be451d70cka59if47258h7k4jki5d5dj413hi4jb64bf097ikihj1c26b08kagfbd02k6g7jag78ked4jfj8a4cg2i496aj6hb1c95e45di87da43e9j169cgb4e0944hckf4eh7bi2d35jgeea8ghdha09ddbc5d5i7e1h888227d00afkjeh4946j83i194afag8e6g4ghkddicik9g528k9cid7dfc6c3be82e84i07j80290027gg8b30173fe86kijh2i829ggae87b88kbd3e35k2fed4021782e5d6j55dfg1k3jeag0ja10992k3i3chdgi8cf6dj3dde85493d9c705
+-utffv.7fq8g
+-jay2n.8fiu2gr2j4i
+RangeError
+RangeError
+837423.234765892
+837423.234765892
+837423.234765892
+11001100011100101111.001111000001100110011110000101001
+203244143.1041331020313011020141012144343424004432324444123214111330012003020411412444130434430234014141001014030004013421431340423043243430334044344010114312304212344313122223100333121042212214144443012140012404202123102304232203144231420223022143412411110220404413330002012023342142200012143401143221103143123303203424423424402344232320322114033210421113011043103034420133011321302403444201021402240331414301404102000141340430140441203242110340313202403241214140042301311201231330432444123302124020343203214342403201201120231444423411123002433333023143423323214443143443014020333210044011442400104304044231203234101200333401233121222133144041133201333432132210142001323311322114432101141144434100300003420103423441110412224340004340431344232402000211133412443112210242413321341013234234044230020223121342231401343444343341040102343414102042211122032004420304401204024230432224422021334140402404400210142431320221023221032234212401203221312043133313002102414041014114332140004000433431341240242141010214333444444333114224331041340033441220314132301110103040040022220121420204304402313414402301142334134300341
+3143457.17014636051
+344753.29981324504a97046
+cc72f.3c199e148
+468j6.4jb3acik2k824ca6dbfaec22565g2k80733f9f806k45kee4kcia6bd9ggh968h5c94e419f2e74gg2gjc66ifa847hee53hi76a86h6f8ei123bg4j25g79bkkb6462hhci123f2hf58j2ebf31c4jig1929k02k5hc8j5a217di6812ckd4c0c97jfh14b994e13hh3c29d6731ij6i38212fj3khe6ab4g4fce6044h92hjkia5hcgje4g2hb711be5g7facc9f2hcbg3724keh09kg3g21e239h64jka8ejf5j73jf9fb3dcc1idjke9ihg4hffj997jdd732390hhjeb4040c08h7be09214a054ej7j61f01h031ck511i3i2fkje4d5926bg7fj852aejkdh560hia2a6gceij35d002g5g7g23d1iffkdbgeagdh43jfb93b35f88a11db1301cfc0je79e7ghdb65h58ki47bad490kf5bg26h87cdfk2d54fji5476d8hb133dfhhk1dbb3ce8h04kdi61h7b0093b47b715fi1dejefj95i704ad6365ebhe1a2g7iibea89d35bc1a6fg9gb05kkcgb49k15gjc6a79g04g4e12gb9c9jkdcg6kebf1ecc4507je0dh9734hk1ja69e9k95iif197igdgfch59kk2gchfiec442d7kei8dgaahg872fi0ac2i7ggk5h8b1a69fc6hdake6cjjd3bj9j03ehjic65k7hhk85ce423h1g9df3ii075907d2123kgggjb2f44ib2hgf76djke64gj979h5fh99hddc7a1fd3444dekkfj3j59fh2ji5ahagf31h7a24ddc0kd28j19kb19hb7kdhi2e07229bj4ecakb39h98df2c687kfb8i0ce92i3ided7e95i0je25275addb63cb9j3bf7f86i23fakd7d34gg5fhiceh9b1513f9c19a2037k3h9jffikg2dbh1bk2jddeij1jh3jb77343k1cc3e9hf622fj32ba0if3ie113e832hj82a59gg9
+phpf.7gcps54
+hy5r.8g98jqvgcr700ms4i
+RangeError
+RangeError
+2.3423446609034533e+21
+2.3423446609034533e+21
+2.3423446609034533e+21
+11111101111101010001111111010101101000101011011001001000000000000000000
+2224143002343343220233144213324
+375752177255053311000000
+73b92b9962990aa44400
+7efa8fead15b240000
+1d81ai80e3cf15796
+1vfl3vaq5di8000
+dqc1bgb40jcw40
+RangeError
+RangeError
+-0.138789879520123
+-0.138789879520123
+-0.138789879520123
+-0.001000111000011110111011110010011000111000000001011
+-0.0321332434424311014042334422402031444214321023400022213242301114144143134413344420443303400242303240024043410344014342403423220334422212130303123300411101233141233101431031024121444404404324321222020102433310040201042101103203021431223030313320312241214202321210202203333441321311241222243324003403310114234014423331001203123014342232004042244033303001213114434344301030121322443344321244440220243342223333300332300301023431402123244140123031203432034404131124430140121324243442201304201233444122134303114122201243020323203212023203331433204433042242442432222121012414332221304304001231410103032232034031410142301433442200443112321443311022320143141103434434312241423332110331412002024221433133133012044224211302103311444200331224131341130012303041003122412222404110330034302114441000413204120411014222440440232102230124112331130102040223242420401220143031233040404312211244411033301103012310130344024132220423204401443011330402340200030210033034134234130012204341313102300211334341231400221031023403422142232404240234033424134201412233424314433320224443122340040002230140320200132121343133402342111
+-0.10703673623070013
+-0.17b9b44394a2921a2643aa1946
+-0.2387bbc98e016
+-0.2j46kicch4ae28bi7i4a3hekb78b060iaekkbe1gafgdfe8799hg7062475f91c010eb5gghj8jab9bjjg3ch6aa36e43k5ci442c9bchcf4dej8bkeicghi7igfe7bc455jei2683g2i069254aa3ha0h7i9j14j8g24g5fi4di7961ii4f48bi11gh02a1668cg631kak99i2gi96eceea0gjc76d04jb6c0d1bjj97bjk0h1kci9gh1d6hje7kc81kd1khdg5e5217hi571206c0ah3g66c310c8402jb45gc62210d5700991kch3ffgiaj392ga98j5a5ad1ehifb3de79bgj7j6d05575d4h226ajijg052fgd616062d82cbj912545jkbekb0f596i78hd37deb4aige6ah581beg72kd7jf6a48kegk7422a55ad58kci3i08khf1hgd5c6bg9854g62d2k03i2034214h1fj1ddahk04h130a5j9dgib2d7k421g1ab0223bbage89cj9k15g6je32cj81i4c4h90gdj1cfgk09egbcd22kg7g0e2k8387553hh93b972abebhf7kd760fech0jd8bgkf2f40e9b803gk7j7i0d54dekf6e1e0d9e1644idk3ch7ih17h01abja798e194cj119160ab4b9h77c86j5ef9k7418jjija5c97kd312064c6b86d93c6ggb4h5i4e2ef118cek0bjcjdd55k1d18b45fc2ai7eb7g9f189i2267g52gc3eh8fcbd33g79ah2j6c4d268ghg6941fh8bg2d3k2gf6g5ddhc881a78hkjkick9760dc2471g0103fci341gaji196egkj2hbi34hcjhkhk1c16c5553ihef87ai164510b9h8480k5agfici9a0kf1e0fikfkihj0bige0j9jeh960hk79a09heg605e1j65hi613eh0b7gjg948k7hdfed880efhbkfcbafi4cedcgacdg05bdheje09dk9hb0chf88g8gcj0j82f9181a1kg5ije4493d1f
+-0.4e3rnice05g
+-0.4zvdpa5kudb144bi51yl6dpldi
+RangeError
+RangeError
+10.5
+10.5
+10.5
+1010.1
+20.2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
+12.4
+a.6
+a.8
+a.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+a.g
+a.i
+RangeError
+RangeError
+-10.22
+-10.22
+-10.22
+-1010.0011100001010001111010111000010100011110101110001
+-20.1022222222222222222224003020122323033300441442220203301203144402343140242430210221111202304121331330403042243413420432141114301142321112234231230243243403034304420413041103023243301222242320410310203042422131344321000021412200213432012023330343142214331443441422020304334441242130124344031300310203021033122344414122434323234322113443422202440342102304430413104122434244432402024014012432011410002030410320143312441041304222324442210411300433042140030032330434203141212110341042404224034202123402003000013423013022223420022223301424141002413330420211223241221322243303141331100021444200213023432403144122314024134134241121031130022231213411000013302031044443224142134012040001334312210142032023331411403214324241410221101420413344123022122343020212031002144044412014234100120044343004013201212013323401121041023212443302403430014402124314212043424113420040213031230243231414102302042433031132143104204133340001111313232212030443444311440404212031424012100423413404003104400131234421420430331431213102441041312020324322313422223402123424403011331430423143114202040240231012022003422233243022320404011
+-12.16050753412172704
+-a.2781b05915343aa9902400346
+-a.3851eb851eb88
+-a.4d08h4d08h4hf45d3bg4kakgi4f0cjfh4d50h019kaki7b8i4k6a7ff23765kje1kejb7gbk6d37427b8kkgg70504h52g23jhe8b62fj40f799c818k20k3200ef465ah24g979g8bfadgja0c92kid34g5fb6ih95f740ggcj1jcaggaadf020759j4i0i4eh5b9140kig25601hee42igd58hea5hfbgee2b75j2ch560ig96e7j13hhhjc7ke85f7b6e5ik7hb63aegdd9djh9g1aik942gcaede776314272c7j1i9jb6c1ee0fi0b3fj53gfk45961jckh70c0j0a9ie54716b9bba9g356g2668k74abkejfgead0116i3i6b5f9204hhk06fic33a1aj8i88i8efh29fh0ce5j7536e52h1d1eeh445hi9h01e50jk7c2bh108kh4h9i7d9eb5hf1c7fe9cba8ehj5k6fa0e657dh3aca2774i6kk7j6i0377b8ij3dk4gbc5c485jfeeabd10kkg1f7i47cikij29eec9a3c8014g4ebc6404egbga840f950fjaa903febjg25hca14a3afh65gag2bbda62g44aif3ebcg65ad578k9b7djcbf142ee1i0k6f9i5e0ha9kgfeb21d4j03e996f3gjajghb7j3jec178k9c6jdhcj8gb27akkchgk96790g71c079kgie65k3773976ii3kb65ik40fjf993k49i1486jdhd627j55ak77gkj386e341dd3kj6d141d29kihc8447jj3739kiikb5e2493dae4279c26j2h435dkfcb927cii9d4c50hgeb9565faag9275934j8g4298jf6j0k95k5gdkfb7i2hfbh28j5c9bg429f8c5ijd3c5g619b22h64d40gd3aa56bfdkfg6k5e09f033k878fk8jek1fj3g4e52b28cbci61f77ib56e23djgai8c4578jdhhie2gadcb1h39ke2h2hk811ffcbb5afega0545hjic9ihciaf5ja79h6fie18
+-a.718un18un2
+-a.7x4bipx4bl239d7o5wh5s714i
+RangeError
+RangeError
+-32.44
+-32.44
+-32.44
+-100000.01110000101000111101011100001010001111010111
+-112.2044444444444444444434242141323034424144123224222424432033213440310401401403202322341301333013114441223321132422410233344133300310204200423420321110001144420330434322302123433133402444323342233402431212213430114210131131040422101234423301044202442412011111202322243120411340222122100042230434431402423033112113342214220220031014033003424040001030204223004322143243141442203124323411312421242422324312233320120123131143013444102121411440433412243114001324333113323001220133141423111041421224000414213341441024312123411100044441004122400111212412201330333201134223241233234440041420031001030300203120034033403322411042020202021201413102233232234044424311121034041022043423203404412414310420042222114224301230211223444430314434320144321340033204004220340402300013410144140301342014022233413442244412424343044042041241244132323404330021100244323124441220021020241020321110101024204242343441310344121403314231303411311410333220340424314234314111141411231320220311104323212431112033422244200010040134104021313011131214024144143423411202421302410401011220023224213042412204343213022342110142401044132010004
+-40.341217270243656
+-28.5343a0b62a68752a7b3853
+-20.70a3d70a3d7
+-1b.950hd950hd896ch4d4ab9id46f7da6gg005d76gaag564ekci64b145bih139jdcae3g011abbe8j77k929ba7867g5ih4027844k116ai077ji5jh006ijj7gf2kfehgah0ijch4ha89k71dbc5h57k00d1e69i7kg5ba3b3000cchcf702a05621796dj74a2k0855a19i04af8a0071c652ek5a7fh5kg0fdd2b1aj94ceii30ajdb0kbgj6kijj6h5854k3483k122h2b44j0jf5igh2fe67g59fe2iki5kfg22ag27j3e7kcg6j9a5ci9591hgicig2eck1habhc2ag81e2i197i6ggh9gdfec0ae0h1f80jkj5019b599k3aefc6482gj208kciidebe866b7eh84gadiafd9gk9dkc08i53019d6keg4bhah58509bda7390420idji4ebbkh76edc4784kg9khij840gjh8gfa7369c13bj3258463g58bjbki3h99jb129f640bc0ded54h6c54ij2ebi785c71bi7e91caj88ifei7k4c69dg367hd8h8ia0h9002jg74c7kgckha6hh1228k8339cbif6893fi10j9j8632k64k0a9jab9ibhk6i4e1eggb429465hh07c65a05g5a7hff4bkf7fabe5k7b69c42agb67igchad521b088dd6g103jb371h91b8hbiik7gb39a372432jc8e837095dfj01d061743hhh9c93fe43b1aih0f8i058323c88j090a514ca31aehid5cggjh7j2j843058h4e1j49gfj8hai1hc3g36bhfa2eg692ib0i26fdh9h010hh39fechg7fe10617hj8f2gj3d284kk2h92ic7303fdhhc21b1k5g57d515kcjhg0bge4ci5i77gdfkeji269fg34db96jg91i9h79ggbd37bd6j2dggd38ijifcace81e6acb6e86df260ei84a51agcg49ag2b43bhib95f9b6gj4bj18gfi2f617c4ji35acae8gia20d3dd
+-10.e2hte2hte
+-w.fu8n1fu8mt4kep0q30izfr
+RangeError
+RangeError
+0.435235
+0.435235
+0.435235
+0.011011110110101110001111100110110001001100010110010111
+0.2042002331344301041220203140412320301240114400312321030032133114041040142100334302144143210444241330412231341101412000422031433310121423140022103342420132431220032042211341303201430132313042414304001213201230122234413022332141014234233132324304113111042302404214401300331133124222424300222122420443413401442340023133002200020010143330420204000311104002122302211032043110124334330121333402122024024412132334110342310302133023034130131142343042020204100323331434114302144002404131404102303030203441240131212110114320012404112242434421223231130032204414411210101344312013202421211441012322110211403031222013010100020232020121302312133403443012424240120323240224403344140204200004140413421404233143233324300042042401300204220040024244013231030021424120410234321221031310233040320142340220022332201434034040242133203223241011142401040020414024034023343403233230401221403342420421121002224244222443404321103424310340003433431314324431404112320113343221102011321003314010443240141031311241040102013202143024011413244033444203220203104324111010441233002030441124131241013231313040140211402430114240420114104
+0.336656174661142627
+0.5281048b56048493b540683183
+0.6f6b8f9b13165c
+0.92jejee2ke6bagb157913kd7dbi4h8j1ka7h65433d7kbgf7hf5djb64di03g887kjf0ka9a9eh6f39ji77kjk1ik9e87fd4c5ha35h928hhhb50610e3jc4d0e42j95e1h67g664ifdk4b6d1g6fa4gicfjkebe45f22da6k9b886h2kf67kii2ghag3b7giek3bfbj69jhec2gbkbhh5jk37817hb8a13e2bi466b9ffd8e93ifhd31710gc73be4f6672j96hifh677384faj04114igeigb87bfj8f9109bb7fh7he79a8ek60cj6efc2fei2i4gg0i1kj27e2713c75a3ig25agh27ckjdee2c61f1dc16aabf4aic9j8gjh90i83h599eeg8f8beejkfhia0h25k5he7b8diji47a9g82h3a64ie002dhcb90gi95c2aadfeak12fkj0daaa0i44k292e0hg23bef5id5j383ieb96ji0kfg1j27akj62f6j6cgkfk190170c4aj3ga93afg6c6h14jga694eaaa1810k9b5i24k67dik74ca43h66i2d1h6kd0449f84e5cfhjgg9fdj3g646g2g2a1ijj4ka3ih9hgdfdihg2fbec3jjj6ckj1c7ch4eg4eje9b0bkfbghjb67f1e07e0ifkek3g36d49kc377b8bc4afibja31c6df6621f6ae38hgf821gek8bd931b2e14765bhf7bc27higb1baf8255hke85ae067k7d7gj2jb0h58kdj24e6jj7b5j14f3j58b59k57k4ffk61d08e02deb19aiaje4940d5f95bk433hcb5d37dfb1ckdkajji6i34c3ddgig528hbe5eeji5ab0ic9h4694jcj6bkei1gc0e73366fh40hc5fce47eke9483a5j7h3i2bhd041213i0hkf39ckba51hhkd3h95d2jf0ha478ei5i57dh2c5b9j3234ihe7e0g5dbkgb94khjee5ag3ha986888i278i317cbd0j274b3bjcc2e0c7j5e3k1ejd5k2575k0eh3c2
+0.dtlov6oj2pe
+0.fo2bo40bm1biel61z7tp7rpb9
+RangeError
+RangeError
+0.5
+0.5
+0.5
+0.1
+0.2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
+0.4
+0.6
+0.8
+0.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+0.g
+0.i
+RangeError
+RangeError
+5
+5
+5
+101
+10
+5
+5
+5
+5
+5
+5
+RangeError
+RangeError
+7.5
+7.5
+7.5
+111.1
+12.2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
+7.4
+7.6
+7.8
+7.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+7.g
+7.i
+RangeError
+RangeError
diff --git a/nashorn/test/script/basic/NASHORN-174.js b/nashorn/test/script/basic/NASHORN-174.js
new file mode 100644
index 0000000..e56c258
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-174.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-174 :  String.prototype.split does not work properly when separator is a string
+ *
+ * @test
+ * @run
+ */
+
+var nums = "24.45.8.78".split('.');
+
+if (nums.length != 4) {
+    fail("#1: split result expected to be of length 4");
+}
+   
+function check(index, value) {
+    if (nums[index] != value) {
+        fail("expected value @ " + index + " is " + value);
+    }
+}
+
+check(0, '24');
+check(1, '45');
+check(2, '8');
+check(3, '78');
+
diff --git a/nashorn/test/script/basic/NASHORN-175.js b/nashorn/test/script/basic/NASHORN-175.js
new file mode 100644
index 0000000..be60d12
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-175.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-175 :  nashorn lexer does not like if '\0' appears in source code.
+ *
+ * @test
+ * @run
+ */
+
+eval("/* This is a comment " + String.fromCharCode('\u0000') + " */");
diff --git a/nashorn/test/script/basic/NASHORN-176.js b/nashorn/test/script/basic/NASHORN-176.js
new file mode 100644
index 0000000..672362d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-176.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-176 :  Parser is not parse string with escaped new line.
+ *
+ * @test
+ * @run
+ */
+
+function func(str) {}
+
+func("first\
+second\
+");
+
+try {
+    func(eval("\"first\\\nsecond\\\n\n\""));
+    print("error expected!");
+} catch (e) {}
diff --git a/nashorn/test/script/basic/NASHORN-177.js b/nashorn/test/script/basic/NASHORN-177.js
new file mode 100644
index 0000000..024a9d1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-177.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-177 : null array elements become undefined on assignment 
+ *
+ * @test
+ * @run
+ */
+
+var n=[null];
+print(n[0]);
+
+var u=[];
+u[0] = n[0];
+print(u[0]);
+
diff --git a/nashorn/test/script/basic/NASHORN-177.js.EXPECTED b/nashorn/test/script/basic/NASHORN-177.js.EXPECTED
new file mode 100644
index 0000000..c1e4b6c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-177.js.EXPECTED
@@ -0,0 +1,2 @@
+null
+null
diff --git a/nashorn/test/script/basic/NASHORN-178.js b/nashorn/test/script/basic/NASHORN-178.js
new file mode 100644
index 0000000..4e1a919
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-178.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-178 : arguments.length is incorrect for arguments of function called using apply()
+ *
+ * @test
+ * @run
+ */
+
+function f1() {
+    print(arguments.length);
+    for (var i=0; i < arguments.length; i++) {
+        print(' '+i+': '+arguments[i]);
+    }
+}
+
+function f2() {
+    var args = [];
+    for(var i=0; i < arguments.length; i++) {
+        args[i] = arguments[i];
+    }
+    f1.apply(this, args);
+}
+
+f2(1, 2, 3);
diff --git a/nashorn/test/script/basic/NASHORN-178.js.EXPECTED b/nashorn/test/script/basic/NASHORN-178.js.EXPECTED
new file mode 100644
index 0000000..319f300
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-178.js.EXPECTED
@@ -0,0 +1,4 @@
+3
+ 0: 1
+ 1: 2
+ 2: 3
diff --git a/nashorn/test/script/basic/NASHORN-179.js b/nashorn/test/script/basic/NASHORN-179.js
new file mode 100644
index 0000000..d0b50ea
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-179.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-179 :  post increment/decrement does not work as expected with small values such as 0.1
+ *
+ * @test
+ * @run
+ */
+
+var x = 0.1;
+
+if (x++ !== 0.1) {
+    fail("x++ !== 0.1");
+}
+
+var y = 0.1;
+
+if (y-- !== 0.1) {
+    fail("y-- !== 0.1");
+}
diff --git a/nashorn/test/script/basic/NASHORN-18.js b/nashorn/test/script/basic/NASHORN-18.js
new file mode 100644
index 0000000..50115c9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-18.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-18: try-do-with fails with VerifyError.
+ *
+ * @test
+ * @run
+ */
+var obj = {};
+
+try {
+    do {
+        with(obj) {
+            throw "abc";
+        }
+    } while(false);
+} catch(e) {
+    print(e);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-18.js.EXPECTED b/nashorn/test/script/basic/NASHORN-18.js.EXPECTED
new file mode 100644
index 0000000..8baef1b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-18.js.EXPECTED
@@ -0,0 +1 @@
+abc
diff --git a/nashorn/test/script/basic/NASHORN-181.js b/nashorn/test/script/basic/NASHORN-181.js
new file mode 100644
index 0000000..0ad8da5
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-181.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-181 :  Object.create throws UnsupportedOperationException.
+ *
+ * @test
+ * @run
+ */
+
+var props = { foo: { } };
+
+try {
+    var obj = Object.create({}, props);
+    if (! obj.hasOwnProperty("foo")) { 
+        fail("obj does not have 'foo' property");
+    }
+} catch (e) {
+    fail("Object.create failed", e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-182.js b/nashorn/test/script/basic/NASHORN-182.js
new file mode 100644
index 0000000..0e908dd
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-182.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-182 :  Array.prototype.reduce does not exit early when a getter function throws error.
+ *
+ * @test
+ * @run
+ */
+
+function callback(prev, cur, idx, obj) {
+    fail("callback with " + idx);
+}     
+
+// array-like object
+var obj = { 1: 1, 2: 2, length: 3 };
+
+Object.defineProperty(obj, "0", {
+    get: function () {
+        throw new RangeError("exception from getter for '0'");
+    },
+ });
+
+obj.reduce = Array.prototype.reduce;
+
+try {
+    obj.reduce(callback);
+    fail("should have thrown RangeError");
+} catch (ex) {
+    if (! (ex instanceof RangeError)) {
+        fail("RangeException expected, got " + ex);
+    }
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-183.js b/nashorn/test/script/basic/NASHORN-183.js
new file mode 100644
index 0000000..c90e7ba
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-183.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-183 :  Array.prototype.reduce does not work for array-like objects
+ *
+ * @test
+ * @run
+ */
+
+function callback(acc, newVal) {
+    return acc + newVal;
+}
+
+function func() {
+    return Array.prototype.reduce.call(arguments, callback);
+}
+
+var val = func(232, 334, 454);
+if (val != (232 + 334 + 454)) {
+    fail("expecting " + (232 + 334 + 454));
+}
+
+var arr = [3, 4, 5, 6];
+var obj = Object.create(arr);
+val = Array.prototype.reduce.call(obj, callback);
+
+var val2 = 0;
+for (i in arr) {
+    val2 += arr[i];
+}
+
+if (val != val2) {
+    fail("val != val2, val2 is " + val2);
+}
diff --git a/nashorn/test/script/basic/NASHORN-184.js b/nashorn/test/script/basic/NASHORN-184.js
new file mode 100644
index 0000000..d1524b9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-184.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-184 :  Array.prototype.reduce and other generic array functions should accept strings
+ *
+ * @test
+ * @run
+ */
+
+var str = "java";
+
+function callback(acc, prev, idx) {
+    print(acc + ' ' + prev + ' ' + idx);
+    return prev;
+}
+
+Array.prototype.reduce.call(str, callback);
diff --git a/nashorn/test/script/basic/NASHORN-184.js.EXPECTED b/nashorn/test/script/basic/NASHORN-184.js.EXPECTED
new file mode 100644
index 0000000..b37043f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-184.js.EXPECTED
@@ -0,0 +1,3 @@
+j a 1
+a v 2
+v a 3
diff --git a/nashorn/test/script/basic/NASHORN-185.js b/nashorn/test/script/basic/NASHORN-185.js
new file mode 100644
index 0000000..508b5b3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-185.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-180 : RuntimeError from Array.shift
+ *
+ * @test
+ * @run
+ */
+
+
+function f() {
+  return Array.prototype.shift.apply(arguments);
+}
+
+print(f('a', 'b', 'c'));
+
diff --git a/nashorn/test/script/basic/NASHORN-185.js.EXPECTED b/nashorn/test/script/basic/NASHORN-185.js.EXPECTED
new file mode 100644
index 0000000..7898192
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-185.js.EXPECTED
@@ -0,0 +1 @@
+a
diff --git a/nashorn/test/script/basic/NASHORN-187.js b/nashorn/test/script/basic/NASHORN-187.js
new file mode 100644
index 0000000..7238ecf
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-187.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-187 :  Accessor property descriptor with undefined 'set' or 'get' property results in TypeError.
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+
+try {
+    Object.defineProperty(obj, "foo", { 
+         get: function() { return 22; }, 
+         set: undefined 
+    });
+} catch (e) {
+    fail("failed", e);
+}
+
+try {
+    Object.defineProperty(obj, "bar", { 
+        get: undefined
+    });
+} catch (e) {
+    fail("failed", e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-188.js b/nashorn/test/script/basic/NASHORN-188.js
new file mode 100644
index 0000000..ce72713
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-188.js
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * NASHORN-188 : Nashorn uses locale for Number.prototype.toPrecision()
+ *
+ * @test
+ * @run
+ */
+
+function format(value) {
+    print(value.toFixed());
+    print(value.toFixed(1));
+    print(value.toFixed(2));
+    print(value.toFixed(3));
+    print(value.toFixed(10));
+
+    print(value.toExponential());
+    print(value.toExponential(1));
+    print(value.toExponential(2));
+    print(value.toExponential(3));
+    print(value.toExponential(10));
+
+    print(value.toPrecision());
+    print(value.toPrecision(1));
+    print(value.toPrecision(2));
+    print(value.toPrecision(3));
+    print(value.toPrecision(10));
+
+    print();
+}
+
+format(0);
+format(1/10);
+format(1/12);
+format(1);
+format(123456789000);
+format(123456.123456);
+format(-1/10);
+format(-1/12);
+format(-1);
+format(-123456789000);
+format(-123456.123456);
+format(NaN);
+format(Infinity);
diff --git a/nashorn/test/script/basic/NASHORN-188.js.EXPECTED b/nashorn/test/script/basic/NASHORN-188.js.EXPECTED
new file mode 100644
index 0000000..8bf6c01
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-188.js.EXPECTED
@@ -0,0 +1,208 @@
+0
+0.0
+0.00
+0.000
+0.0000000000
+0e+0
+0.0e+0
+0.00e+0
+0.000e+0
+0.0000000000e+0
+0
+0
+0.0
+0.00
+0.000000000
+
+0
+0.1
+0.10
+0.100
+0.1000000000
+1e-1
+1.0e-1
+1.00e-1
+1.000e-1
+1.0000000000e-1
+0.1
+0.1
+0.10
+0.100
+0.1000000000
+
+0
+0.1
+0.08
+0.083
+0.0833333333
+8.333333333333333e-2
+8.3e-2
+8.33e-2
+8.333e-2
+8.3333333333e-2
+0.08333333333333333
+0.08
+0.083
+0.0833
+0.08333333333
+
+1
+1.0
+1.00
+1.000
+1.0000000000
+1e+0
+1.0e+0
+1.00e+0
+1.000e+0
+1.0000000000e+0
+1
+1
+1.0
+1.00
+1.000000000
+
+123456789000
+123456789000.0
+123456789000.00
+123456789000.000
+123456789000.0000000000
+1.23456789e+11
+1.2e+11
+1.23e+11
+1.235e+11
+1.2345678900e+11
+123456789000
+1e+11
+1.2e+11
+1.23e+11
+1.234567890e+11
+
+123456
+123456.1
+123456.12
+123456.123
+123456.1234560000
+1.23456123456e+5
+1.2e+5
+1.23e+5
+1.235e+5
+1.2345612346e+5
+123456.123456
+1e+5
+1.2e+5
+1.23e+5
+123456.1235
+
+-0
+-0.1
+-0.10
+-0.100
+-0.1000000000
+-1e-1
+-1.0e-1
+-1.00e-1
+-1.000e-1
+-1.0000000000e-1
+-0.1
+-0.1
+-0.10
+-0.100
+-0.1000000000
+
+-0
+-0.1
+-0.08
+-0.083
+-0.0833333333
+-8.333333333333333e-2
+-8.3e-2
+-8.33e-2
+-8.333e-2
+-8.3333333333e-2
+-0.08333333333333333
+-0.08
+-0.083
+-0.0833
+-0.08333333333
+
+-1
+-1.0
+-1.00
+-1.000
+-1.0000000000
+-1e+0
+-1.0e+0
+-1.00e+0
+-1.000e+0
+-1.0000000000e+0
+-1
+-1
+-1.0
+-1.00
+-1.000000000
+
+-123456789000
+-123456789000.0
+-123456789000.00
+-123456789000.000
+-123456789000.0000000000
+-1.23456789e+11
+-1.2e+11
+-1.23e+11
+-1.235e+11
+-1.2345678900e+11
+-123456789000
+-1e+11
+-1.2e+11
+-1.23e+11
+-1.234567890e+11
+
+-123456
+-123456.1
+-123456.12
+-123456.123
+-123456.1234560000
+-1.23456123456e+5
+-1.2e+5
+-1.23e+5
+-1.235e+5
+-1.2345612346e+5
+-123456.123456
+-1e+5
+-1.2e+5
+-1.23e+5
+-123456.1235
+
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+
diff --git a/nashorn/test/script/basic/NASHORN-19.js b/nashorn/test/script/basic/NASHORN-19.js
new file mode 100644
index 0000000..71a2db0d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-19.js
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-19:  with blocks in various scopes and breaking from them if they are inloops
+ * (also continues)
+ *
+ * @test
+ * @run
+ */
+
+
+var myvalue = "hello";
+
+var myscope = {
+    myvalue: 11
+};
+
+do {
+    with(myscope) {
+	myvalue = 12;
+	break;
+    }
+} while (false);
+
+if (myvalue != 'hello') {
+    throw "expecting to be hello";
+} else {
+    print("value is 'hello' as expected");
+}
+
+print("\n");
+
+function ten() {
+    return 0xa;
+}
+
+//make sure the scope works outside functions too
+print("starting 0");
+var value = "hello";
+var scope = {value:10};
+var scope2 = {value:20};
+while (true) {
+    with (scope) {
+	print(value);
+	value = 11;
+	print(value);
+	with (scope2) {
+	    print(value);
+	    value = 21;
+	    print(value);
+	    break;
+	}
+    }
+}
+
+print(value);
+print("\n");
+
+//two level scope
+function test1() {
+    var value = "hello";
+    var scope = {value:10};
+    var scope2 = {value:20};
+    while (true) {
+	with (scope) {
+	    print(value);
+	    value = 11;
+	    print(value);
+	    with (scope2) {
+		print(value);
+		value = 21;
+		print(value);
+		break;
+	    }
+	}
+    }
+    
+    print(value);
+}
+
+//one level scope
+function test2() {
+    var value = "hello";
+    var scope = {value:10};
+    while (true) {
+	with (scope) {
+	    print(value);
+	    value = 11;
+	    print(value);
+	    if (value > ten()) {
+		break;
+	    }
+	}
+    }
+    print(value);
+}
+
+//continue two levels
+function test3() {
+    var value = "hello";
+    var scope = {value:10};
+    var scope2 = {value:20};
+    var outer = 0;
+    while (outer < 5) {
+	var i=0;
+	while (i < 10) {
+	    with(scope) {
+		print("loop header "+i);
+		with (scope2) {
+		    value = 11;
+		    i++;
+		    if ((i & 1) != 0) {
+			print("continue");
+			continue;
+		    }
+		}
+	    }
+	    print(value);
+	}
+	outer++;
+    }
+} 
+
+//continue one level
+function test4() {
+    var value = "hello";
+    var scope = {value:10};
+    var i=0;
+    while (i < 10) {
+	print("loop header "+i);
+	with (scope) {
+	    value = 11;
+	    i++;
+	    if ((i & 1) != 0) {
+		print("continue");
+		continue;
+	    }
+	}
+    }
+    print(value);
+}
+
+
+//labelled continue;
+function test5() {
+    var value = "hello";
+    var scope = {value:10};
+    var scope2 = {value:20};
+    var outer = 0;
+    outer_label:
+    while (outer < 5) {
+	var i=0;
+	while (i < 10) {
+	    with(scope) {
+		print("loop header "+i);
+		with (scope2) {
+		    value = 11;
+		    i++;
+		    if ((i & 1) != 0) {
+			print("continue");
+			outer++;
+			continue outer_label;
+		    }
+		}
+	    }
+	    print(value);
+	}
+    }
+} 
+
+//labelled break
+function test6() {
+    var value = "hello";
+    var scope = {value:10};
+    var scope2 = {value:20};
+    outer:
+    {
+	var i=0;
+	while (i < 10) {
+	    with(scope) {
+		print("loop header "+i);
+		with (scope2) {
+		    value = 11;
+		    i++;
+		    if ((i & 1) != 0) {
+			print("break");
+			break outer;
+		    }
+		}
+	    }
+	    print(value);
+	}
+    }
+}
+
+//exceptions in one scope and then the other
+function test7() {
+    var value = "hello";
+    var scope = {value:10};
+    var scope2 = {value:20};    
+    var global = false;
+    try {
+	with(scope) {
+	    try {
+		print(value);
+		value = 4711;
+		print(value);
+		with(scope2) {
+		    print(value);
+		    value = 17;
+		    print(value);
+		    global = true;
+		    throw "inner";
+		}
+	    } catch (ei) {
+		print(ei);
+		print(value);
+		if (global) {
+		    throw "outer";
+		}
+	    }
+	}
+    } catch (eo) {
+	print(eo);
+	print(value);
+    }
+    print(value);
+}
+
+
+print("starting 1");
+test1();
+print("\n");
+
+print("starting 2");
+test2();
+print("\n");
+
+print("starting 3");
+test3();
+print("\n");
+
+print("starting 4");
+test4();
+print("\n");
+
+print("starting 5");
+test5();
+print("\n");
+
+print("starting 6");
+test6();
+print("\n");
+
+print("starting 7");
+test7();
+print("\n");
+
diff --git a/nashorn/test/script/basic/NASHORN-19.js.EXPECTED b/nashorn/test/script/basic/NASHORN-19.js.EXPECTED
new file mode 100644
index 0000000..ce3aca1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-19.js.EXPECTED
@@ -0,0 +1,177 @@
+value is 'hello' as expected
+
+
+starting 0
+10
+11
+20
+21
+hello
+
+
+starting 1
+10
+11
+20
+21
+hello
+
+
+starting 2
+10
+11
+hello
+
+
+starting 3
+loop header 0
+continue
+loop header 1
+hello
+loop header 2
+continue
+loop header 3
+hello
+loop header 4
+continue
+loop header 5
+hello
+loop header 6
+continue
+loop header 7
+hello
+loop header 8
+continue
+loop header 9
+hello
+loop header 0
+continue
+loop header 1
+hello
+loop header 2
+continue
+loop header 3
+hello
+loop header 4
+continue
+loop header 5
+hello
+loop header 6
+continue
+loop header 7
+hello
+loop header 8
+continue
+loop header 9
+hello
+loop header 0
+continue
+loop header 1
+hello
+loop header 2
+continue
+loop header 3
+hello
+loop header 4
+continue
+loop header 5
+hello
+loop header 6
+continue
+loop header 7
+hello
+loop header 8
+continue
+loop header 9
+hello
+loop header 0
+continue
+loop header 1
+hello
+loop header 2
+continue
+loop header 3
+hello
+loop header 4
+continue
+loop header 5
+hello
+loop header 6
+continue
+loop header 7
+hello
+loop header 8
+continue
+loop header 9
+hello
+loop header 0
+continue
+loop header 1
+hello
+loop header 2
+continue
+loop header 3
+hello
+loop header 4
+continue
+loop header 5
+hello
+loop header 6
+continue
+loop header 7
+hello
+loop header 8
+continue
+loop header 9
+hello
+
+
+starting 4
+loop header 0
+continue
+loop header 1
+loop header 2
+continue
+loop header 3
+loop header 4
+continue
+loop header 5
+loop header 6
+continue
+loop header 7
+loop header 8
+continue
+loop header 9
+hello
+
+
+starting 5
+loop header 0
+continue
+loop header 0
+continue
+loop header 0
+continue
+loop header 0
+continue
+loop header 0
+continue
+
+
+starting 6
+loop header 0
+break
+
+
+starting 7
+10
+4711
+20
+17
+inner
+4711
+outer
+hello
+hello
+
+
diff --git a/nashorn/test/script/basic/NASHORN-190.js b/nashorn/test/script/basic/NASHORN-190.js
new file mode 100644
index 0000000..06e51a3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-190.js
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-190 :  Object property keys should be Strings
+ *
+ * @test
+ * @run
+ */
+
+var obj = { 
+    20: 'world', "2.3": 'hello'
+};
+
+obj[true] = 30;
+obj[null] = 'java';
+obj[undefined] = 'js';
+
+if (obj[20] !== 'world') {
+    fail("obj[20] !== 'world'");
+}
+
+if (obj['20'] !== 'world') {
+    fail("obj['20'] !== 'world'");
+}
+
+if (obj[2.3] !== 'hello') {
+    fail("obj[2.3] !== 'hello'");
+}
+
+if (obj['2.3'] !== 'hello') {
+    fail("obj['2.3'] !== 'hello'");
+}
+
+if (obj[true] !== 30) {
+    fail("obj[true] !== 30");
+}
+
+if (obj['true'] !== 30) {
+    fail("obj['true'] !== 30");
+}
+
+if (obj[null] !== 'java') {
+    fail("obj[null] !== 'java'");
+}
+
+if (obj['null'] !== 'java') {
+    fail("obj['null'] !== 'java'");
+}
+
+if (obj[undefined] !== 'js') {
+    fail("obj[undefined] !== 'js'");
+}
+
+if (obj['undefined'] !== 'js') {
+    fail("obj['undefined'] !== 'js'");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-192.js b/nashorn/test/script/basic/NASHORN-192.js
new file mode 100644
index 0000000..8fdc82b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-192.js
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-192 :  User defined property setter or getter with extra arguments or lesser argument fails by throwing exception
+ * 
+ * @test
+ * @run
+ */
+
+var obj = {};
+Object.defineProperty(obj, "foo", {
+    get: function(obj) {
+        return 'hello';
+    }
+});
+
+try {
+    if (obj.foo !== 'hello') {
+        fail("getter with extra argument does not work");
+    }
+} catch (e) {
+    fail("failed to get with " + e);
+}
+
+Object.defineProperty(obj, "bar", {
+    set: function() {
+        // do nothing
+    }
+});
+
+try {
+    obj.bar = 33;
+} catch (e) {
+    fail("failed to set with " + e);
+}
+
+Object.defineProperty(obj, "prop", {
+    set: function(obj1, obj2, obj3) {
+        this.val = obj1;
+    }
+}); 
+
+try {
+    obj.prop = 33;
+    if (obj.val !== 33) {
+        fail("set with extra argument does not work");
+    }
+} catch (e) {
+    fail("failed to set with " + e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-194.js b/nashorn/test/script/basic/NASHORN-194.js
new file mode 100644
index 0000000..bbbc194
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-194.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-194 :  VM crash with SIGSERV executing S15.3.4.3_A5_T1.js
+ *
+ * @test
+ * @run
+ */
+
+var obj = "hello";
+obj.foo = "world";
+if (obj.foo !== undefined) {
+    fail("obj.foo should be undefined");
+}
+
+obj = 445;
+obj.foo = 42;
+if (obj.foo !== undefined) {
+    fail("obj.foo should be undefined");
+}
+
+obj = true;
+obj.foo = 34;
+if (obj.foo !== undefined) {
+    fail("obj.foo should be undefined");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-196.js b/nashorn/test/script/basic/NASHORN-196.js
new file mode 100644
index 0000000..071da97
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-196.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-196 :  RangeError thrown when array length is set to -0.0
+ *
+ * @test
+ * @run
+ */
+
+var arr = [0, 1];
+
+Object.defineProperty(arr, "length", {
+    value: -0
+});
+        
+if (arr.length !== 0) {
+    fail("array length is not zero!");
+}
diff --git a/nashorn/test/script/basic/NASHORN-198.js b/nashorn/test/script/basic/NASHORN-198.js
new file mode 100644
index 0000000..ea99a3b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-198.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-198 :  JSON.parse does not handle empty arrays property
+ *
+ * @test
+ * @run
+ */
+
+var x = JSON.parse('{"foo":[]}');
+
+if (! (x.foo instanceof Array)) {
+    fail("x.foo should be an Array");
+}
+
+if (x.foo.length !== 0) {
+    fail("x.foo.length should be zero");
+}
diff --git a/nashorn/test/script/basic/NASHORN-20.js b/nashorn/test/script/basic/NASHORN-20.js
new file mode 100644
index 0000000..b0d6cc9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-20.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-20:  typeof of undefined variable should not result in ReferenceError.
+ *
+ * @test
+ * @run
+ */
+
+if (typeof abc == 'undefined') {
+   print("yes, typeof 'abc' is undefined as expected");
+}
diff --git a/nashorn/test/script/basic/NASHORN-20.js.EXPECTED b/nashorn/test/script/basic/NASHORN-20.js.EXPECTED
new file mode 100644
index 0000000..457a901
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-20.js.EXPECTED
@@ -0,0 +1 @@
+yes, typeof 'abc' is undefined as expected
diff --git a/nashorn/test/script/basic/NASHORN-201.js b/nashorn/test/script/basic/NASHORN-201.js
new file mode 100644
index 0000000..11bcf27
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-201.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-201:  Date constructors does not work properly when a single String argument is passed.
+ *
+ * @test
+ * @run
+ */
+
+var expected = "1970-01-01T00:00:00.000Z";
+var d = new Date("1970");
+var str = d.toISOString();
+if (expected !== str) {
+    throw new Error("expected " + expected + ", got " + str);
+}
diff --git a/nashorn/test/script/basic/NASHORN-202.js b/nashorn/test/script/basic/NASHORN-202.js
new file mode 100644
index 0000000..53c7fb1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-202.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-202 :  Date.prototype.toJSON should accept one (unused) argument
+ *
+ * @test
+ * @run
+ */
+
+if (Date.prototype.toJSON.length !== 1) {
+    throw new Error("Date.prototype.toJSON.length !== 1");
+}
diff --git a/nashorn/test/script/basic/NASHORN-203.js b/nashorn/test/script/basic/NASHORN-203.js
new file mode 100644
index 0000000..94acb3e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-203.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-203:  Date.prototype.toISOString should throw RangeError on invalid date.
+ *
+ * @test
+ * @run
+ */
+
+var date = new Date(-Infinity, Infinity);
+
+try {
+    date.toISOString();
+    fail("toISOString should have thrown RangeError");
+} catch (ex) {
+    if (! (ex instanceof RangeError)) {
+        fail("expected RangeError but got " + ex);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-204.js b/nashorn/test/script/basic/NASHORN-204.js
new file mode 100644
index 0000000..98dedba
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-204.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-204 :  Adding two empty arrays should result in empty String but nashorn gives NaN
+ *
+ * @test
+ * @run
+ */
+
+if ([] + [] !== '') {
+    fail("[] + [] is not empty string");
+}
+
+// other related checks
+if ({} + {} !== '[object Object][object Object]') {
+    fail("{} + {} is not [object Object][object Object]");
+}
+
+if ({} + [] !== '[object Object]') {
+    fail("{} + [] is not [object Object]");
+}
+
+if ([] + {} !== '[object Object]') {
+    fail("[] + {} is not [object Object]");
+}
diff --git a/nashorn/test/script/basic/NASHORN-205.js b/nashorn/test/script/basic/NASHORN-205.js
new file mode 100644
index 0000000..15bb389
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-205.js
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-205 :  Cannot convert read-only accessor property into a data property with a new value
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+
+Object.defineProperty(obj, "foo", {
+    get: function() { return 23; },
+    set: undefined,
+    enumerable: true,
+    configurable: true
+});
+
+var desc = Object.getOwnPropertyDescriptor(obj, "foo");
+if (! desc.hasOwnProperty("get")) {
+    fail("'get' missing!!");
+}
+
+if (obj.foo !== 23) {
+    fail("obj.foo !== 23");
+}
+
+try {
+    // modify to use "value" property
+    Object.defineProperty(obj, "foo", {
+        value: 100
+    });
+} catch (e) {
+    fail("failed", e);
+}
+  
+var newDesc = Object.getOwnPropertyDescriptor(obj, "foo");
+if (! newDesc.hasOwnProperty("value")) {
+    fail("'value' missing!!");
+}
+
+if (obj.foo !== 100) {
+    fail("obj.foo !== 100");
+}
diff --git a/nashorn/test/script/basic/NASHORN-206.js b/nashorn/test/script/basic/NASHORN-206.js
new file mode 100644
index 0000000..537a990
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-206.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-206 : Trailing extra characters are ignored by parser/lexer.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval("print('hello');\n} } ) )");
+    fail("should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("expected SyntaxError but got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-207.js b/nashorn/test/script/basic/NASHORN-207.js
new file mode 100644
index 0000000..b337ce3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-207.js
@@ -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.
+ * 
+ * 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.
+ */
+
+/**
+ * NASHORN-207 : implement strict mode
+ *
+ * @test
+ * @run
+ */
+
+'use strict';
+
+// cannot delete a variable
+try {
+    eval("var fooVar = 3; delete fooVar;");
+    fail("#1 should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#2 SyntaxError expected but got " + e);
+    } 
+}
+
+// cannot delete function parameter variable
+try {
+    eval("function func(a) { delete a; }; func(2);");
+    fail("#3 should have thrown SyntaxError");
+} catch(e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#4 SyntaxError expected but got " + e);
+    } 
+}
+
+// assignment can't be used to define as new variable
+try {
+    bar = 3;
+    fail("#5 should have thrown ReferenceError");
+} catch (e) {
+    if (! (e instanceof ReferenceError)) {
+        fail("#6 ReferenceError expected but got " + e);
+    }
+}
+
+// repeated property definition is not allowed in an object literal
+try {
+    eval("var obj = { foo: 33, foo: 44 }");
+    fail("#7 should have thrown SyntaxError");
+} catch(e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#8 SyntaxError expected but got " + e);
+    }
+}
+
+// can't assign to "eval"
+try {
+    eval("var eval = 3");
+    fail("#9 should have thrown SyntaxError");
+} catch(e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#10 SyntaxError expected but got " + e);
+    }
+}
+
+// can't assign to 'arguments'
+try {
+    eval("function func() { arguments = 34; }");
+    fail("#11 should have thrown SyntaxError");
+} catch(e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#12 SyntaxError expected but got " + e);
+    }
+}
+
+// can't delete non-configurable properties
+try {
+    delete Object.prototype;
+    fail("#13 should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#14 TypeError expected but got " + e);
+    }
+}
+
+// cannot re-use function parameter name
+try {
+    eval("function func(a, a) {}");
+    fail("#15 should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#16 SyntaxError expected but got " + e);
+    }
+}
+
+// strict eval creates own scope and caller's scope is untouched!
+eval("var myVar = 4;");
+if (typeof myVar !== 'undefined') {
+    fail("#17 eval var 'myVar' created in global scope");
+}
+
+eval("function myNewFunc() {}");
+if (typeof myNewFunc !== 'undefined') {
+    fail("#18 eval function 'myNewFunc' created in global scope");
+}
+
+// no octal in strict mode
+try {
+    eval("var x = 010;");
+    fail("#19 should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#20 SyntaxError expected but got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-207_2.js b/nashorn/test/script/basic/NASHORN-207_2.js
new file mode 100644
index 0000000..681a3c2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-207_2.js
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-207 : Implement strict mode.
+ *
+ * @test
+ * @run
+ */
+
+// make sure that 'use strict' as first directive inside eval
+// also works the same way (as eval called from strict mode caller).
+
+try {
+    eval("'use strict'; foo = 4;");
+    fail("#1 should have thrown ReferenceError");
+} catch (e) {
+    if (! (e instanceof ReferenceError)) {
+        fail("#2 expected ReferenceError but got " + e);
+    }
+}
+
+if (typeof foo !== 'undefined') {
+    fail("#3 strict mode eval defined var in global scope!");
+}
+
+try {
+    eval("'use strict'; var let = 23;");
+    fail("#4 should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#5 SyntaxError expected but got " + e);
+    }
+}
+
+// non-strict mode, some of the future reserved words can be used
+// as identifiers. These include "let", "implements", "yield" etc.
+var let = 30;
+var implements = "hello";
+function yield() {}
+function public() {}
+var private = false;
+var protected = "hello";
+var interface = "interface";
+function f(package) {}
+function static() {}
+
+// in strict mode, arguments does not alias named access
+function func(x, y) {
+    'use strict';
+
+    if (x !== arguments[0]) {
+        fail("#6 arguments[0] !== x");
+    }
+
+    if (y !== arguments[1]) {
+        fail("#7 arguments[1] !== y");
+    }
+
+    arguments[0] = 1;
+    arguments[1] = 2;
+
+    if (x === arguments[0]) {
+        fail("#8 arguments[0] === x after assignment to it");
+    }
+
+    if (y === arguments[1]) {
+        fail("#9 arguments[1] === y after assignment to it ");
+    }
+}
+
+func();
+
+// functions can not be declared everywhere!!
+try {
+    eval("'use strict'; if (true) { function func() {} }");
+    fail("#10 should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#11 SyntaxError expected got " + e);
+    }
+}
+
+// arguments.caller and arguments.callee can't read or written in strict mode
+function func2() {
+    'use strict';
+
+    try {
+        print(arguments.callee);
+        fail("#12 arguments.callee should have thrown TypeError");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#13 TypeError expected, got " + e);
+        }
+    }
+
+    try {
+        print(arguments.caller);
+        fail("#14 arguments.caller should have thrown TypeError");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#15 TypeError expected, got " + e);
+        }
+    }
+
+    try {
+        arguments.caller = 10;
+        fail("#16 arguments.caller assign should have thrown TypeError");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#17 TypeError expected, got " + e);
+        }
+    }
+
+    try {
+        arguments.callee = true;
+        fail("#18 arguments.callee assign should have thrown TypeError");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#19 TypeError expected, got " + e);
+        }
+    }
+}
+
+func2();
+
+// func.caller and func.arguments can't read or written in strict mode
+function func3() {
+    'use strict';
+
+    try {
+        print(func3.arguments);
+        fail("#20 func.arguments should have thrown TypeError");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#21 TypeError expected, got " + e);
+        }
+    }
+
+    try {
+        print(func3.caller);
+        fail("#22 func3.caller should have thrown TypeError");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#23 TypeError expected, got " + e);
+        }
+    }
+
+    try {
+        func3.arguments = 10;
+        fail("#24 func3.arguments assign should have thrown TypeError");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#25 TypeError expected, got " + e);
+        }
+    }
+
+    try {
+        func3.caller = true;
+        fail("#26 func3.caller assign should have thrown TypeError");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#27 TypeError expected, got " + e);
+        }
+    }
+}
+
+func3();
+
+try {
+    eval("function eval() { 'use strict'; }");
+    fail("#28 should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#29 SyntaxError expected, got " + e);
+    }
+}
+
+function func4() {
+  'use \
+strict';
+
+    // The use strict directive can't contain line continuation.
+    // So this is not a strict mode function!!
+    with({}) {}
+}
+
+func4();
+
+function func5() {
+   'use\u2028strict';
+
+    // The use strict directive can't contain unicode whitespace escapes
+    // So this is not a strict mode function!!
+    with({}) {}
+}
+
+func5();
+
+function func6() {
+   'use\u2029strict';
+
+    // The use strict directive can't contain unicode whitespace escapes
+    // So this is not a strict mode function!!
+    with({}) {}
+}
+
+func6();
+
+try {
+    eval("'bogus directive'; 'use strict'; eval = 10");
+    fail("#30 SyntaxError expected from eval");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("#31 SyntaxError expected but got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-208.js b/nashorn/test/script/basic/NASHORN-208.js
new file mode 100644
index 0000000..f7b2861
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-208.js
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-208  
+ *
+ * @test
+ * @run
+ */
+
+var inspect = function(x) { return x; }
+
+var formatRegExp = /%[sdj%]/g;
+
+var format = function(f) {
+  if (typeof f !== 'string') {
+    var objects = [];
+    for (var i = 0; i < arguments.length; i++) {
+      objects.push(inspect(arguments[i]));
+    }
+    return objects.join(' ');
+  }
+
+  var i = 1;
+  var args = arguments;
+  var len = args.length;
+  var str = String(f).replace(formatRegExp, function(x) {
+    if (i >= len) return x;
+    switch (x) {
+      case '%s': return String(args[i++]);
+      case '%d': return Number(args[i++]);
+      case '%j': return JSON.stringify(args[i++]);
+      case '%%': return '%';
+      default:
+        return x;
+    }
+  });
+  for (var x = args[i]; i < len; x = args[++i]) {
+    if (x === null || typeof x !== 'object') {
+      str += ' ' + x;
+    } else {
+      str += ' ' + inspect(x);
+    }
+  }
+  return str;
+};
+
+var s = format('%s %s', 'foo', 'bar', 'hop');
+print(s);
+
diff --git a/nashorn/test/script/basic/NASHORN-208.js.EXPECTED b/nashorn/test/script/basic/NASHORN-208.js.EXPECTED
new file mode 100644
index 0000000..89a9f68
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-208.js.EXPECTED
@@ -0,0 +1 @@
+foo bar hop
diff --git a/nashorn/test/script/basic/NASHORN-209.js b/nashorn/test/script/basic/NASHORN-209.js
new file mode 100644
index 0000000..9fa781c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-209.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-209 :  IdentifierName is different from Identifier as per spec.
+ *
+ * @test
+ * @run
+ */
+
+var obj  = { 
+    in: 11, class: 'hello', try: false, 
+    typeof: 456, instanceof: 'world',
+    catch: function() { print("catch called"); }
+};
+
+print("obj.in = " + obj.in);
+print("obj.class = " + obj.class);
+print("obj.try = " + obj.try);
+print("obj.typeof = " + obj.typeof);
+print("obj.instanceof = " + obj.instanceof);
+obj.catch();
diff --git a/nashorn/test/script/basic/NASHORN-209.js.EXPECTED b/nashorn/test/script/basic/NASHORN-209.js.EXPECTED
new file mode 100644
index 0000000..def58d3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-209.js.EXPECTED
@@ -0,0 +1,6 @@
+obj.in = 11
+obj.class = hello
+obj.try = false
+obj.typeof = 456
+obj.instanceof = world
+catch called
diff --git a/nashorn/test/script/basic/NASHORN-21.js b/nashorn/test/script/basic/NASHORN-21.js
new file mode 100644
index 0000000..14db4dc
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-21.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-21: changed, but deleted function argument can not be returned as result
+ *
+ * @test
+ * @run
+ */
+
+function func(arg){
+    arg++;
+    delete arguments[0];
+    if (arguments[0] !== undefined) {
+        print("ERROR: arguments[0] should be undefined");
+    } else {
+        print("yes, arguments[0] is undefined");
+    }
+    return arg;
+}
+
+if (func(1) !== 2) {
+    print("ERROR: func should have returned 2");
+} else {
+    print("yes, function returned 2");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-21.js.EXPECTED b/nashorn/test/script/basic/NASHORN-21.js.EXPECTED
new file mode 100644
index 0000000..a4c8b1d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-21.js.EXPECTED
@@ -0,0 +1,2 @@
+yes, arguments[0] is undefined
+yes, function returned 2
diff --git a/nashorn/test/script/basic/NASHORN-211.js b/nashorn/test/script/basic/NASHORN-211.js
new file mode 100644
index 0000000..681caad
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-211.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-211 :  Comparison operators > and <= are not ECMA edition 5.1 compliant
+ *
+ * @test
+ * @run
+ */
+
+var x = { valueOf: function() { throw "x"; } };
+var y = { valueOf: function() { throw "y"; } };
+
+try {
+    x > y;
+    fail("expected exception with x > y");
+} catch (e) {
+    if (e !== 'x') {
+        fail("'x' expected to be thrown with x > y");
+    }
+}
+
+try {
+    x <= y;
+    fail("expected exception with x <= y");
+} catch (e) {
+    if (e !== 'x') {
+        fail("'x' expected to be thrown with x <= y");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-212.js b/nashorn/test/script/basic/NASHORN-212.js
new file mode 100644
index 0000000..681c775
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-212.js
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-212 :  Object literal property redefinition restrictions are not implemented
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval("obj = { x : 3, get x() { return 42; }");
+    fail("data property redefined as accessor");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected got " + e);
+    }
+}
+
+try {
+    eval("obj = { get x() { return 42; }, x: 'hello'");
+    fail("accessor property redefined as data");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected got " + e);
+    }
+}
+
+try {
+    eval("obj = { get x() { return 42; }, get x() { return 'hello' }");
+    fail("accessor property redefined with different getter");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected got " + e);
+    }
+}
+
+try {
+    eval("obj = { set x(val) { }, set x(val) { }");
+    fail("accessor property redefined with different setter");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("SyntaxError expected got " + e);
+    }
+}
+
+// data redefinition is fine
+obj = { x: 44, x: 'hello' };
+
+// can define getter and setter
+obj = { get x() { return 3; }, set x(val) {} };
+
diff --git a/nashorn/test/script/basic/NASHORN-213.js b/nashorn/test/script/basic/NASHORN-213.js
new file mode 100644
index 0000000..03a37d9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-213.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-213 :  double valued array indices don't work as expected
+ *
+ * @test
+ * @run
+ */
+
+var x = [];
+x[1.1] = 33;
+
+if (x[1.1] !== 33) {
+    fail("x[1.1] !== 33");
+}
+
+if (x[1] === 33) {
+    fail("x[1] === 33");
+}
diff --git a/nashorn/test/script/basic/NASHORN-215.js b/nashorn/test/script/basic/NASHORN-215.js
new file mode 100644
index 0000000..53ff42e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-215.js
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-215 : Exception parameter should be local to the catch block.
+ *
+ * @test
+ * @run
+ */
+
+var exp = new Error("Error!");
+try {
+   throw exp;
+} catch (e) {
+   print("1 " + e.message);
+   try {
+      throw new Error("Nested error");
+   } catch (e) {
+      print("2 " + e.message);
+   }
+   print("3 " + e.message);
+};
+
+try {
+   print(e);
+   print("should not reach here");
+} catch (e1) {
+   print("4 success");
+}
+
+function f() {
+    var x = 4;
+    try {
+       throw exp;
+    } catch (e) {
+       print("5 " + e.message);
+       (function() {
+           try {
+              throw new Error("Nested error.");
+           } catch (e) {
+              try {
+                print("6 " + e.message);
+                throw new Error("error in catch");
+              } catch (e) {
+                 print("7 " + e.message);
+              }
+              (function() { print("8 " + e.message); })();
+              print("9 " + e.message);
+           }
+          print("a " + e.message);
+       })();
+       print("b " + e.message);
+    };
+    return function() { return x; }();
+}
+f();
+
+try {
+  throw "asdf1";
+} catch (ex) {
+  (function() {
+    var o = {};
+    with (o) {
+      print(ex);
+    }
+  })();
+  try {
+    throw "asdf2";
+  } catch (ex) {
+    (function() {
+      var o = {};
+      with (o) {
+        print(ex);
+        ex = "asdf3";
+      }
+    })();
+    print(ex);
+  }
+  print(ex);
+}
diff --git a/nashorn/test/script/basic/NASHORN-215.js.EXPECTED b/nashorn/test/script/basic/NASHORN-215.js.EXPECTED
new file mode 100644
index 0000000..5baec98
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-215.js.EXPECTED
@@ -0,0 +1,15 @@
+1 Error!
+2 Nested error
+3 Error!
+4 success
+5 Error!
+6 Nested error.
+7 error in catch
+8 Nested error.
+9 Nested error.
+a Error!
+b Error!
+asdf1
+asdf2
+asdf3
+asdf1
diff --git a/nashorn/test/script/basic/NASHORN-216.js b/nashorn/test/script/basic/NASHORN-216.js
new file mode 100644
index 0000000..e9b1aee
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-216.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-216 :  eval inside a 'with' does not get proper scope
+ *
+ * @test
+ * @run
+ */
+
+var obj = { foo: 13 };
+
+with (obj) {
+    try {
+        if (eval('foo') !== 13) {
+            fail("eval('foo') !== 13");
+        }
+    } catch (e) {
+        fail("with " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-217.js b/nashorn/test/script/basic/NASHORN-217.js
new file mode 100644
index 0000000..3885c70
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-217.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-217 :  getter and setter name in object literal could be string, number, reserved word as well
+ *
+ * @test
+ * @run
+ */
+
+var obj = {
+   get class() { return 44; },
+   get in() { return 'hello' },
+   get typeof() { return false; },
+   set class(x) { print('class ' + x); },
+   set in(x) { print('in ' + x); },
+   set typeof(x) { print('typeof ' + x); },
+   get 14() { return 14; },
+   set 14(x) { print("14 " + x); },
+   get 'foo prop'() { return 'foo prop value' },
+   set 'foo prop'(x) { print('foo prop ' + x); }
+};
+
+print('obj.class ' + obj.class);
+print('obj.in ' + obj.in);
+print('obj.typeof ' + obj.typeof);
+print('obj[14] ' + obj[14]);
+print("obj['foo prop'] " + obj['foo prop']);
+
+obj.class = 3;
+obj.in = 'world';
+obj.typeof = 34;
+obj[14] = 34;
+obj['foo prop'] = 'new foo prop';
diff --git a/nashorn/test/script/basic/NASHORN-217.js.EXPECTED b/nashorn/test/script/basic/NASHORN-217.js.EXPECTED
new file mode 100644
index 0000000..3713188
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-217.js.EXPECTED
@@ -0,0 +1,10 @@
+obj.class 44
+obj.in hello
+obj.typeof false
+obj[14] 14
+obj['foo prop'] foo prop value
+class 3
+in world
+typeof 34
+14 34
+foo prop new foo prop
diff --git a/nashorn/test/script/basic/NASHORN-219.js b/nashorn/test/script/basic/NASHORN-219.js
new file mode 100644
index 0000000..b7da209
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-219.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-219 :  load function should accept string script and script name
+ *
+ * @test
+ * @run
+ */
+
+load({ script: 'print(__FILE__)', name: 'foo-script'});
diff --git a/nashorn/test/script/basic/NASHORN-219.js.EXPECTED b/nashorn/test/script/basic/NASHORN-219.js.EXPECTED
new file mode 100644
index 0000000..fa4ac11
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-219.js.EXPECTED
@@ -0,0 +1 @@
+foo-script
diff --git a/nashorn/test/script/basic/NASHORN-22.js b/nashorn/test/script/basic/NASHORN-22.js
new file mode 100644
index 0000000..89f677c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-22.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-22: For a global function with multiple definitions, the "last" definition should be used for invocations.
+ *
+ * @test
+ * @run
+ */
+
+
+function func() {
+    print("func, first def");
+}
+
+func();
+
+function func() {
+    print("func, second def");
+}
+
+func();
diff --git a/nashorn/test/script/basic/NASHORN-22.js.EXPECTED b/nashorn/test/script/basic/NASHORN-22.js.EXPECTED
new file mode 100644
index 0000000..59503f2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-22.js.EXPECTED
@@ -0,0 +1,2 @@
+func, second def
+func, second def
diff --git a/nashorn/test/script/basic/NASHORN-221.js b/nashorn/test/script/basic/NASHORN-221.js
new file mode 100644
index 0000000..87132bc
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-221.js
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-221 : Error and subtypes should not have "message" property if constructor was called without message argument
+ *
+ * @test
+ * @run
+ */
+
+function check(name) {
+    var e = new this[name]();
+    if (e.hasOwnProperty("message")) {
+        fail(name + " has 'message' property");
+    }
+
+    e = new this[name]("error!!");
+    if (! e.hasOwnProperty("message")) {
+        fail(name + " does not have 'message' property");
+    }
+}
+
+check("Error");
+check("EvalError");
+check("RangeError");
+check("ReferenceError");
+check("SyntaxError");
+check("TypeError");
+check("URIError");
+
+
diff --git a/nashorn/test/script/basic/NASHORN-222.js b/nashorn/test/script/basic/NASHORN-222.js
new file mode 100644
index 0000000..a5a61f0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-222.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-222 :  Wrong typeof value for properties of primitive values
+ *
+ * @test
+ * @run
+ */
+
+var x = 2;
+if (typeof x.foo !== 'undefined') {
+    fail("#1 x.foo is not undefined");
+}
+
+x = 'hello';
+if (typeof x.foo !== 'undefined') {
+    fail("#2 x.foo is not undefined");
+}
+
+x = true;
+if (typeof x.foo !== 'undefined') {
+    fail("#3 x.foo is not undefined");
+}
diff --git a/nashorn/test/script/basic/NASHORN-223.js b/nashorn/test/script/basic/NASHORN-223.js
new file mode 100644
index 0000000..dd862d5
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-223.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-223 : Function.prototype.bind fails when the function uses "arguments" object
+ *
+ * @test
+ * @run
+ */
+
+function sum() {
+    var res = 0.0;
+    for (i in arguments) res += arguments[i];
+    return res;
+}
+
+var f = sum.bind(this, 1, 2, 3);
+if (f(4) !== 10) {
+    fail("f(4) !== 10");
+}
diff --git a/nashorn/test/script/basic/NASHORN-225.js b/nashorn/test/script/basic/NASHORN-225.js
new file mode 100644
index 0000000..c7744c3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-225.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-225 :  Object.isFrozen does not handle accessor properties as per the spec
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+Object.defineProperty(obj, "foo", {
+    get: function() { return 'hello' },
+    configurable: true
+});
+
+Object.preventExtensions(obj);
+if (Object.isFrozen(obj)) {
+    fail("obj should not be frozen!");
+}
diff --git a/nashorn/test/script/basic/NASHORN-226.js b/nashorn/test/script/basic/NASHORN-226.js
new file mode 100644
index 0000000..521c3a6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-226.js
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-226 : Error.prototype.toString does not confirm to spec.
+ *
+ * @test
+ * @run
+ */
+
+var e = new Error();
+if (e.toString() !== "Error") {
+    fail("#1 expected 'Error', got " + e.toString());
+}
+
+e.message = "";
+if (e.toString() !== "Error") {
+    fail("#2 expected 'Error', got " + e.toString());
+}
+
+e.message = { toString: function() { return '' } };
+if (e.toString() !== "Error") {
+    fail("#3 expected 'Error', got " + e.toString());
+}
+
+e.name = "MyError";
+e.message = "";
+if (e.toString() !== "MyError") {
+    fail("#4 expected 'MyError', got " + e.toString());
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-227.js b/nashorn/test/script/basic/NASHORN-227.js
new file mode 100644
index 0000000..787bdfa
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-227.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-227 :  When a bound function is used as constructor, arguments are not passed as expected
+ *
+ * @test
+ * @run
+ */
+
+var func = function (x, y, z) {
+   var obj = {};
+   obj.res = "";
+   for (i in  arguments) {
+       obj.res += arguments[i];
+   }
+   return obj;
+};
+
+var MyCons = func.bind({}, "a", "b", "c");
+var newObj = new MyCons("d", "e");
+
+if (newObj.res !== "abcde") {
+    fail("newObj.res !=== 'abcde', it is " + newObj.res);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-228.js b/nashorn/test/script/basic/NASHORN-228.js
new file mode 100644
index 0000000..bb3bd8b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-228.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-228 : Array, arguments keys should be strings and not numbers
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    for (i in arguments) {
+        if (typeof i !== 'string') {
+            fail("typeof key of arguments is not 'string'");
+        }
+    }
+}
+
+func(1);
+
+var x = [1];
+for (i in x) {
+    if (typeof i !== 'string') {
+        fail("typeof key of an array is not 'string'");
+    }
+}
+
+var str = "h";
+for (i in x) {
+    if (typeof i !== 'string') {
+        fail("typeof key of a string is not 'string'");
+    }
+}
+    
diff --git a/nashorn/test/script/basic/NASHORN-229.js b/nashorn/test/script/basic/NASHORN-229.js
new file mode 100644
index 0000000..fefc318
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-229.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-229 : Strange interaction of two scripts
+ *
+ * @test
+ * @run
+ */
+
+function func1() {
+    var obj  = {};
+    obj.foo = 0;
+    return (obj.foo === 0);
+}
+
+if (! func1()) {
+    fail("func1() returned non-true value");
+}
+
+load(__DIR__ + 'NASHORN-229_subtest.js');
+    
diff --git a/nashorn/test/script/basic/NASHORN-229_subtest.js b/nashorn/test/script/basic/NASHORN-229_subtest.js
new file mode 100644
index 0000000..a722a98
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-229_subtest.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-229 :  Strange interaction of two scripts
+ *
+ * @subtest
+ */
+
+function func2() {
+    var obj2 = {
+        get bar() { return 343; }
+    }; 
+
+    return (obj2.bar === 343);
+}
+
+if (! func2()) {
+    fail("func2() returned non-true value");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-23.js b/nashorn/test/script/basic/NASHORN-23.js
new file mode 100644
index 0000000..eab229e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-23.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-23:  calling function valued global variable before it is initialized should fail.
+ * 
+ * @test
+ * @run
+ */
+
+
+try {
+    func();
+    print("huh!! we can call undefined variable as function!");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        print("TypeError expected");
+    }
+}
+
+// define now..
+var func = function() {
+  print("hello");
+}
+
+func(); // should be able to invoke now..
diff --git a/nashorn/test/script/basic/NASHORN-23.js.EXPECTED b/nashorn/test/script/basic/NASHORN-23.js.EXPECTED
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-23.js.EXPECTED
@@ -0,0 +1 @@
+hello
diff --git a/nashorn/test/script/basic/NASHORN-232.js b/nashorn/test/script/basic/NASHORN-232.js
new file mode 100644
index 0000000..a2033ba
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-232.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-232 : Property with user defined getter but no corresponding setter should not be allowed to be assigned.
+ *
+ * @test
+ * @run
+ */
+
+'use strict';
+
+var obj = {
+   get foo() { return 32; }
+};
+
+try {
+    obj.foo = 33;
+    fail("getter only property 'foo' can be set");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("TypeError expected, got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-234.js b/nashorn/test/script/basic/NASHORN-234.js
new file mode 100644
index 0000000..87fec55
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-234.js
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-234 : Inherited accessor property is not handled as per the spec.
+ *
+ * @test
+ * @run
+ */
+
+function MyCons() {};
+
+var setterCalled = false;
+Object.defineProperty(MyCons.prototype, 'foo', {
+    set: function(x) { setterCalled = true; },
+    get: function() { return  42; }
+});
+
+var myObj = new MyCons();
+
+myObj.foo = 34; // has to call setter for inherited 'foo'
+if (myObj.hasOwnProperty("foo")) {
+    fail("'foo' is own property of myObj");
+}
+if (! setterCalled) {
+    fail("inherited setter not called");
+}
+
+// Now try 'dynamic' property access.
+setterCalled = false;
+var propName = "foo";
+myObj[propName] = 42; // has to call setter for inherited 'foo'
+if (myObj.hasOwnProperty("foo")) {
+    fail("'foo' is own property of myObj");
+}
+if (! setterCalled) {
+    fail("inherited setter not called");
+}
diff --git a/nashorn/test/script/basic/NASHORN-235.js b/nashorn/test/script/basic/NASHORN-235.js
new file mode 100644
index 0000000..f01d3f4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-235.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-235 : Cannot set stack property of an Error object
+ *
+ * @test
+ * @run
+ */
+
+var e = new Error('error messsage');
+e.stack = [];
+
+if (! (e.stack instanceof Array)) {
+    fail("e.stack is not an Array");
+}
+
+if (e.stack.length !== 0) {
+    fail("e.stack.length !== 0");
+}
+
+e.stack = "no stack";
+if (e.stack !== "no stack") {
+    fail("e.stack !== 'no stack'");
+}
diff --git a/nashorn/test/script/basic/NASHORN-236.js b/nashorn/test/script/basic/NASHORN-236.js
new file mode 100644
index 0000000..5fdb7f8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-236.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/// This is a file with utf8 BOM
+/**
+ * NASHORN0-236 :  Source file with UTF8 BOM fails to parse
+ *
+ * @test
+ * @run
+ */
diff --git a/nashorn/test/script/basic/NASHORN-237.js b/nashorn/test/script/basic/NASHORN-237.js
new file mode 100644
index 0000000..37b07b3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-237.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-237 : JSON.parse and JSON.stringify don't have proper arity.
+ *
+ * @test
+ * @run
+ */
+
+if (JSON.parse.length !== 2) {
+    fail("JSON.parse.length !== 2, but " + JSON.parse.length);
+}
+
+if (JSON.stringify.length !== 3) {
+    fail("JSON.stringify.length !== 3, but " + JSON.stringify.length);
+}
diff --git a/nashorn/test/script/basic/NASHORN-239.js b/nashorn/test/script/basic/NASHORN-239.js
new file mode 100644
index 0000000..ca94bcc
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-239.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-239 : JSON.stringify eats backslashes
+ *
+ * @test
+ * @run
+ */
+
+var val = JSON.stringify({slashes: '\\\\'});
+if (val !== '{"slashes":"\\\\\\\\"}') {
+    fail("JSON.stringify eats backslahes");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-24.js b/nashorn/test/script/basic/NASHORN-24.js
new file mode 100644
index 0000000..9f4f66d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-24.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-24: function local var assignments should resolve to 'with' scope if found in scope.
+ * 
+ * @test
+ * @run
+ */
+
+var scope = { x: 44 };
+
+function func() {
+    with (scope) {
+        // this should change scope.x
+        var x = 55;
+    }
+}
+
+// should print 44
+print("scope.x == " + scope.x);
+
+// call func -- which effectively changes scope.x
+func();
+
+// should print 55
+print("scope.x == " + scope.x);
diff --git a/nashorn/test/script/basic/NASHORN-24.js.EXPECTED b/nashorn/test/script/basic/NASHORN-24.js.EXPECTED
new file mode 100644
index 0000000..51a5924
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-24.js.EXPECTED
@@ -0,0 +1,2 @@
+scope.x == 44
+scope.x == 55
diff --git a/nashorn/test/script/basic/NASHORN-241.js b/nashorn/test/script/basic/NASHORN-241.js
new file mode 100644
index 0000000..7d887a6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-241.js
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-241 : regression: "new 1" does not throw TypeError
+ *
+ * @test
+ * @run
+ */
+
+try {
+    new 1;
+    fail('new "1" should have thrown TypeError');	
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail('expected TypeError, got ' + e, e);
+    }
+}
+
+try {
+    var x = "1";
+    new x;
+    fail('var x = "1"; new x should have thrown TypeError');	
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail('var x = "1"; new x - expected TypeError, got ' + e, e);
+    }
+}
+
+try {
+    var x = "1";
+    new x();
+    fail('var x = "1"; new x() should have thrown TypeError'); 
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail('var x = "1"; new x() - expected TypeError, got ' + e); 
+    }
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-242.js b/nashorn/test/script/basic/NASHORN-242.js
new file mode 100644
index 0000000..3e362bc
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-242.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-242 : regression: eval inside with statement should use with scope variable
+ *
+ * @test
+ * @run
+ */
+
+(function () {
+    var obj = { str: "o.str" };
+    var str = "local.str";
+
+    with (obj) {
+        if (! eval("str === 'o.str'")) {
+            fail("o.str is not used inside eval");
+        }
+    }
+})();
diff --git a/nashorn/test/script/basic/NASHORN-245.js b/nashorn/test/script/basic/NASHORN-245.js
new file mode 100644
index 0000000..ced3e39
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-245.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-245 : regression : StackOverflowError when accessing inherited accessor property
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+Object.defineProperty(obj, "name", {
+    get: function () {
+        return 32;
+    }
+});
+
+var obj2 = Object.create(obj);
+
+var obj3 = Object.create(obj2);
+
+// StackOverflowError on obj3.name
+if (obj3.name !== 32) {
+    fail("obj3.name !== 32");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-247.js b/nashorn/test/script/basic/NASHORN-247.js
new file mode 100644
index 0000000..b05db7e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-247.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-247 : Object gets stale value when inherited accessor property changes to a data property
+ *
+ * @test
+ * @run
+ */
+
+var data = "foo1";
+var obj = {
+  get foo() { return data; },
+  set foo(value) { data = value; }
+};
+
+var obj2 = Object.create(obj);
+
+function checkObjFoo(expected) {
+    if (obj2.foo !== expected) {
+        fail("obj2.foo has to be " + expected);
+    }
+}
+
+checkObjFoo("foo1");
+
+obj2.foo = "foo2";
+checkObjFoo("foo2");
+
+// change the property to data property
+Object.defineProperty(obj, "foo", {
+   value: "foo3"
+});
+checkObjFoo("foo3");
+
diff --git a/nashorn/test/script/basic/NASHORN-25.js b/nashorn/test/script/basic/NASHORN-25.js
new file mode 100644
index 0000000..0d40ffe
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-25.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-25 :  A function's prototype can be non-object
+ *
+ * @test
+ * @run
+ */
+
+function MyConstructor() {
+}
+
+MyConstructor.prototype = 1;
+
+if (typeof MyConstructor.prototype != 'number') {
+    print("ERROR: expect MyConstructor.prototype to be number type");
+} else {
+    print("yes, MyConstructor.prototype is a number");
+}
+
+var myObj = new MyConstructor();
+
+if (Object.getPrototypeOf(myObj) !== Object.prototype) {
+    print("ERROR: Object.getPrototypeOf(myObj) is not Object.prototype");
+} else {
+    print("yes, Object.getPrototypeOf(myObj) is Object.prototype");
+}
diff --git a/nashorn/test/script/basic/NASHORN-25.js.EXPECTED b/nashorn/test/script/basic/NASHORN-25.js.EXPECTED
new file mode 100644
index 0000000..a222329
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-25.js.EXPECTED
@@ -0,0 +1,2 @@
+yes, MyConstructor.prototype is a number
+yes, Object.getPrototypeOf(myObj) is Object.prototype
diff --git a/nashorn/test/script/basic/NASHORN-251.js b/nashorn/test/script/basic/NASHORN-251.js
new file mode 100644
index 0000000..bc5147f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-251.js
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-251 : Global built-in constructor prototypes are destroyed by user assignments.
+ *
+ * @test
+ * @run
+ */
+
+// assign to global "Array"
+Array = 3;
+// we can create literal array
+x = [23, 33];
+if (x.join("-") !== '23-33') {
+    fail("x.join('-') !== '23-33'");
+}
+
+try {
+    new Array();
+    fail("should have thrown TypeError for 'Array' constructor!");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("should have thrown TypeError, got " + e);
+    }
+}
+
+// assign to global "RegExp"
+RegExp = true;
+// we can still create RegExp literal
+y = /foo/;
+if (! y.test("foo")) {
+   fail("y.test('foo') is not true");
+}
+
+try {
+    new RegExp();
+    fail("should have thrown TypeError for 'RegExp' constructor!");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("should have thrown TypeError, got " + e);
+    }
+}
+
+TypeError = "foo";
+try {
+    var foo = 3;
+    foo();
+} catch(e) {
+    if (! (e instanceof Error)) {
+        fail("Error subtype expected, got " + e);
+    }
+
+    if (e.name !== 'TypeError') {
+        fail("e is not of type 'TypeError'");
+    }
+}
+
+SyntaxError = 234;
+try {
+    eval("344**++33");
+} catch(e) {
+    if (! (e instanceof Error)) {
+        fail("Error subtype expected, got " + e);
+    }
+
+    if (e.name !== 'SyntaxError') {
+        fail("e is not of type 'SyntaxError'");
+    }
+}
+
+ReferenceError = "foo";
+try {
+    print(unknown);
+} catch(e) {
+    if (! (e instanceof Error)) {
+        fail("Error subtype expected, got " + e);
+    }
+
+    if (e.name !== 'ReferenceError') {
+        fail("e is not of type 'ReferenceError'");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-252.js b/nashorn/test/script/basic/NASHORN-252.js
new file mode 100644
index 0000000..5e0a652
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-252.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-252 : Nashorn has trouble with positive and negative infinities
+ *
+ * @test
+ * @run
+ */
+
+var y = -0;
+y = +y;
+if ((1/y) !== -Infinity) {
+    fail("expected -Infinity but got " + (1/y));
+}
+
+y = 0;
+y = -y;
+if ((1/y) !== -Infinity) {
+    fail("expected -Infinity but got " + (1/y));
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-253.js b/nashorn/test/script/basic/NASHORN-253.js
new file mode 100644
index 0000000..f562c97
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-253.js
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-253 :
+ *
+ * @test
+ * @run
+ */
+
+try {
+    foo();
+    fail("#1 expected error!!");
+} catch (e) {
+    if (! (e instanceof ReferenceError)) {
+        fail("#2 expected ReferenceError, got " + e);
+    }
+}
+
+try {
+    this.foo();
+    fail("#3 expected error!!");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#4 expected ReferenceError, got " + e);
+    }
+}
+
+try {
+    new foo();
+    fail("#5 expected error!!");
+} catch (e) {
+    if (! (e instanceof ReferenceError)) {
+        fail("#6 expected ReferenceError, got " + e);
+    }
+}
+
+try {
+    new this.foo();
+    fail("#7 expected error!!");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#8 expected ReferenceError, got " + e);
+    }
+}
+
+try {
+    var x = foo;
+    fail("#9 expected error!!");
+} catch (e) {
+    if (! (e instanceof ReferenceError)) {
+        fail("#10 expected ReferenceError, got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-256.js b/nashorn/test/script/basic/NASHORN-256.js
new file mode 100644
index 0000000..1885873
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-256.js
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-256 : should be able to delete global builtin objects like JSON, Math etc.
+ *
+ * @test
+ * @run
+ */
+
+function deleteAndCheck(name) {
+    if (! (delete this[name])) {
+        fail("cannot delete " + name);
+    } else {
+        if (typeof this[name] !== 'undefined') {
+            fail(name + " is not undefined after delete!");
+        }
+    }
+}
+
+deleteAndCheck("Object");
+deleteAndCheck("Function");
+deleteAndCheck("Array");
+deleteAndCheck("Boolean");
+deleteAndCheck("Date");
+deleteAndCheck("JSON");
+deleteAndCheck("JSAdapter");
+deleteAndCheck("Math");
+deleteAndCheck("Number");
+deleteAndCheck("RegExp");
+deleteAndCheck("String");
+deleteAndCheck("Error");
+deleteAndCheck("Error");
+deleteAndCheck("RangeError");
+deleteAndCheck("ReferenceError");
+deleteAndCheck("SyntaxError");
+deleteAndCheck("TypeError");
+deleteAndCheck("URIError");
+
+function deleteFailCheck(name) {
+    if (delete this[name]) {
+        fail("can delete " + name);
+    } else {
+        if (typeof this[name] === 'undefined') {
+            fail(name + " was deleted!");
+        }
+    }
+}
+
+deleteFailCheck("NaN");
+deleteFailCheck("Infinity");
+if (delete undefined) {
+    fail("can delete 'undefined'");
+}
diff --git a/nashorn/test/script/basic/NASHORN-258.js b/nashorn/test/script/basic/NASHORN-258.js
new file mode 100644
index 0000000..0f4f674
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-258.js
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-258 : Broken slot assignments to non constant members of multidimensional arrays in OP=
+ *
+ * @test
+ * @run
+ */
+
+function test3(a) {
+    for (var i = 0; i < a.length ; i++) {
+	for (var j = 0; j < a[i].length ; j++) {
+	    for (var k = 0; k < a[i][j].length ; k++) {
+		a[i][j][k] *= 8;
+	    }
+	}
+    }
+}
+
+var array = [ [[1,1,1],[1,1,1],[1,1,1]],
+	      [[1,1,1],[1,1,1],[1,1,1]],
+	      [[1,1,1],[1,1,1],[1,1,1]] ];
+	      
+test3(array);
+print(array);
+
+
+function outer() {
+    
+    var array2 = [ [[1,1,1],[1,1,1],[1,1,1]],
+		   [[1,1,1],[1,1,1],[1,1,1]],
+		   [[1,1,1],[1,1,1],[1,1,1]] ];
+    
+    var f =  function inner() {
+	for (var i = 0; i < array2.length ; i++) {
+	    for (var j = 0; j < array2[i].length ; j++) {
+		array2[i][j][2] *= 8;
+	    }
+	}	
+    };
+
+    f();
+    print(array2);
+}
+
+outer();
diff --git a/nashorn/test/script/basic/NASHORN-258.js.EXPECTED b/nashorn/test/script/basic/NASHORN-258.js.EXPECTED
new file mode 100644
index 0000000..8c95c91
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-258.js.EXPECTED
@@ -0,0 +1,2 @@
+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+1,1,8,1,1,8,1,1,8,1,1,8,1,1,8,1,1,8,1,1,8,1,1,8,1,1,8
diff --git a/nashorn/test/script/basic/NASHORN-26.js b/nashorn/test/script/basic/NASHORN-26.js
new file mode 100644
index 0000000..d4525a3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-26.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-26:  String concatenation does not work with += operator.
+ *
+ * @test
+ * @run
+ */
+
+var x = "hello";
+x += ", world";
+print(x);
+
+var y = "hello ";
+y += {};
+print(y);
+
+var z = "number is ";
+z += 42;
+print(z);
+
+var a = 2;
+a += " is the only even prime!";
+print(a);
+
+var b = true;
+b += " is beauty";
+print(b);
+
+var c = {};
+c += {};
+print(c);
diff --git a/nashorn/test/script/basic/NASHORN-26.js.EXPECTED b/nashorn/test/script/basic/NASHORN-26.js.EXPECTED
new file mode 100644
index 0000000..d0aedad
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-26.js.EXPECTED
@@ -0,0 +1,6 @@
+hello, world
+hello [object Object]
+number is 42
+2 is the only even prime!
+true is beauty
+[object Object][object Object]
diff --git a/nashorn/test/script/basic/NASHORN-260.js b/nashorn/test/script/basic/NASHORN-260.js
new file mode 100644
index 0000000..d1f1fcc
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-260.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-260 : builtin constructor (Array, RegExp) inlining is broken inside 'with' statements
+ *
+ * @test
+ * @run
+ */
+
+var globalArray = Array;
+var reachedWithArray = false;
+with ({ Array: function func() { reachedWithArray = true; } }) {
+    var v = new Array();
+
+    if (! reachedWithArray) {
+        fail("didn't reach with scope's Array func");
+    }
+
+    if (v instanceof globalArray) {
+        fail("should not have been global's Array");
+    }
+}
+
+var reached = false;
+with ({ Array: function () { reached = true } }) {
+   with({}) { }
+
+  var f = new Array();
+}
+
+if (! reached) {
+    fail("not calling with's Array");
+}
diff --git a/nashorn/test/script/basic/NASHORN-261.js b/nashorn/test/script/basic/NASHORN-261.js
new file mode 100644
index 0000000..c53facf
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-261.js
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-261 : All 'eval' calls assumed to be global builtin eval calls
+ *
+ * @test
+ * @run
+ */
+
+// call eval with no args
+if (eval() !== undefined) {
+    fail("eval with no arg should return undefined");
+}
+
+// call eval with extra (ignored) args
+function func() {
+    'use strict';
+
+    try {
+        // we pass hidden args after first arg which is code. Make sure
+        // those stay intact even when user passes extra args.
+        // Example: strict mode flag is passed as hidden arg...
+
+        eval("eval = 3", "hello", "world", "nashorn");
+        fail("SyntaxError expected!");
+    } catch (e) {
+        if (! (e instanceof SyntaxError)) {
+            fail("SyntaxError expected, got " + e);
+        }
+    }
+}
+
+func();
+
+// try calling 'eval' -- but from with scope rather than builtin one
+with ( {
+    eval: function() {
+        if (arguments.length != 1) {
+            fail("arguments.length !== 1, it is " + arguments.length);
+            for (i in arguments) { print(arguments[i]); }
+        }
+    }
+}) {
+
+    eval("hello");
+}
+
+// finally, overwrite builtin 'eval'
+var reached = false;
+eval = function() {
+    reached = true;
+    for (i in arguments) {
+        print(arguments[i]);
+    }
+}
+
+// pass no args to our overwritten eval 
+// the new eval should not print anything (no hidden args passed)
+eval();
+
+// make sure our modified eval was called
+if (! reached) {
+    fail("modified eval was not called");
+}
diff --git a/nashorn/test/script/basic/NASHORN-262.js b/nashorn/test/script/basic/NASHORN-262.js
new file mode 100644
index 0000000..42eba1c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-262.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-262 : for statement iterator variable is not checked in strict mode
+ * 
+ * @test
+ * @run
+ */
+
+'use strict';
+
+try {
+    eval("for (var eval in [2, 4]) {}");
+    fail("should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("expected SyntaxError got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-263.js b/nashorn/test/script/basic/NASHORN-263.js
new file mode 100644
index 0000000..62ce47b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-263.js
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-263 : delete of function param or caller scope var should throw SyntaxError in strict mode
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    "use strict";
+    var obj = new Boolean(false);
+
+    try {
+        eval("delete obj;");
+        fail("#1 should have thrown SyntaxError");
+    } catch (e) {
+        if (! (e instanceof SyntaxError)) {
+            fail("#2 SyntaxError expected got " + e);
+        }
+    }
+}
+
+func();
+
+function func2(y) {
+    'use strict';
+    try {
+        eval("delete y");
+        fail("#3 should have thrown SyntaxError");
+    } catch (e) {
+        if (! (e instanceof SyntaxError)) {
+            fail("#4 SyntaxError expected got " + e);
+        }
+    }
+}
+
+func2(2);
diff --git a/nashorn/test/script/basic/NASHORN-264.js b/nashorn/test/script/basic/NASHORN-264.js
new file mode 100644
index 0000000..88cd2b3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-264.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-264 : If the value of user getter property is used as function when it is not, we get ClassCastException instead of TypeError
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    var obj = {};
+    Object.defineProperty(obj, "bar", {
+        get: function()  { return 'hello'; }
+    });
+
+    try {
+        obj.bar();
+        fail("should have thrown TypeError, obj.bar is not a function");
+    } catch(e) {
+        if (! (e instanceof TypeError)) {
+            fail("expected TypeError got " + e);
+        }
+    }
+}
+
+func();
diff --git a/nashorn/test/script/basic/NASHORN-265.js b/nashorn/test/script/basic/NASHORN-265.js
new file mode 100644
index 0000000..88344f5
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-265.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/** 
+ * NASHORN-265 with scope access within a nested function can't access global var
+ *
+ * @test
+ * @run
+ */
+
+var x = 0;
+
+var obj = { x: "obj.x" };
+
+function func() {
+
+   function func2() {
+       with (obj) {
+           print(x);
+       }
+   }
+
+   func2();
+}
+
+func();
diff --git a/nashorn/test/script/basic/NASHORN-265.js.EXPECTED b/nashorn/test/script/basic/NASHORN-265.js.EXPECTED
new file mode 100644
index 0000000..3d20c3a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-265.js.EXPECTED
@@ -0,0 +1 @@
+obj.x
diff --git a/nashorn/test/script/basic/NASHORN-266.js b/nashorn/test/script/basic/NASHORN-266.js
new file mode 100644
index 0000000..bfc600f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-266.js
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-266 : Strict mode functions see scope call 'this' as undefined
+ *
+ * @test
+ * @run
+ */
+
+
+function func() {
+    'use strict';
+    return this;
+}
+
+if (func() !== undefined) {
+    fail("#1 'this' should be undefined");
+}
+
+if (this.func() !== this) {
+    fail("#2 'this' should be global");
+}
+
+function func2() {
+    return this;
+}
+
+if (func2() === undefined) {
+    fail("#3 'this' should not be undefined");
+}
+
+if (this.func2() !== this) {
+    fail("#4 'this' should be global");
+}
+
+// strict calling non-strict
+function func3() {
+    'use strict';
+
+    if (func2() === undefined) {
+        fail("#5 'this' should not be undefined");
+    }
+}
+
+func3();
diff --git a/nashorn/test/script/basic/NASHORN-269.js b/nashorn/test/script/basic/NASHORN-269.js
new file mode 100644
index 0000000..92feb76
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-269.js
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-269 : Global constructor inlining breaks when a builtin constructor is deleted
+ *
+ * @test
+ * @run
+ */
+
+delete Array;
+
+try {
+    print(new Array(3));
+    fail("#1 should have thrown ReferenceError");
+} catch (e) {
+    if (! (e instanceof ReferenceError)) {
+        fail("#2 expected ReferenceError, got " + e);
+    }
+}
+
+Object.defineProperty(this, "Array", {
+    get: function() { return 63; }
+});
+
+try {
+    print(new Array(2));
+    fail("#3 should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#4 expected TypeError, got " + e);
+    }
+}
+
+Object.defineProperty(this, "RegExp", {
+    get: function() { return 23; }
+});
+
+
+try {
+    print(new RegExp("abc"));
+    fail("#5 should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#6 expected TypeError, got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-27.js b/nashorn/test/script/basic/NASHORN-27.js
new file mode 100644
index 0000000..b949b34
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-27.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-27 :  String.prototype.substr is undefined
+ *
+ * @test
+ * @run
+ */
+
+print("substr type = " + typeof String.prototype.substr);
+print("substr arity = " + String.prototype.substr.length);
+
+var str = "hello world";
+print(str.substr(0));
+print(str.substr(3));
+print(str.substr(3, 4));
+print(str.substr(0, 3434));
+print(str.substr(-1));
+print(str.substr(-5, 5));
+print(str.substr(-11, 3));
diff --git a/nashorn/test/script/basic/NASHORN-27.js.EXPECTED b/nashorn/test/script/basic/NASHORN-27.js.EXPECTED
new file mode 100644
index 0000000..4248865
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-27.js.EXPECTED
@@ -0,0 +1,9 @@
+substr type = function
+substr arity = 2
+hello world
+lo world
+lo w
+hello world
+d
+world
+hel
diff --git a/nashorn/test/script/basic/NASHORN-270.js b/nashorn/test/script/basic/NASHORN-270.js
new file mode 100644
index 0000000..89ef0d8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-270.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-270 : Global is not received as 'this' in a bound function when bind was called with undefined 'thisArg'
+ *
+ * @test
+ * @run
+ */
+
+var global = this;
+
+function f() {
+    if (this !== global) {
+        fail("this !== global");
+    }
+}
+
+(function() {
+    f.bind()();
+})();
+
+(function() {
+    'use strict';
+    f.bind()();
+})();
diff --git a/nashorn/test/script/basic/NASHORN-271.js b/nashorn/test/script/basic/NASHORN-271.js
new file mode 100644
index 0000000..75c480d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-271.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-271 : JSON.stringify does not return expected value when replacer function returns object or array for primitive value
+ *
+ * @test
+ * @run
+ */
+
+var res = JSON.stringify(23, function(k,v) { 
+    return (v == 23)? [1, 2] : v;
+});
+
+if (res !== "[1,2]") {
+    fail("#1 expected '[1,2]' got " + res);
+}
+
+var res = JSON.stringify(23, function(k,v) { 
+    return (v == 23)? { x: 1, y: 'hello' } : v; 
+});
+
+if (res !== '{"x":1,"y":"hello"}') {
+    fail("#2 expected {\"x\":1,\"y\":\"hello\"}' got " + res);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-275.js b/nashorn/test/script/basic/NASHORN-275.js
new file mode 100644
index 0000000..46c88fe
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-275.js
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-275 : strict eval receives wrong 'this' object
+ *
+ * @test
+ * @run
+ */
+
+var global = this;
+
+function func() {
+    "use strict";
+
+    if (eval("this") === global) {
+        fail("#1 strict eval gets 'global' as 'this'");
+    }
+
+    if (eval ("typeof this") !== 'undefined') {
+        fail("#2 typeof this is not undefined in strict eval");
+    }
+}
+
+func();
+
+var global = this;
+if (eval("\"use strict\";this") !== this) {
+    fail("#3 strict mode eval receives wrong 'this'");
+}
+
+var obj = {
+  func: function() {
+      if (eval('"use strict"; this') !== obj) {
+          fail("#4 strict mode eval receives wrong 'this'");
+      }
+  }
+};
+
+obj.func();
+
+function func2() {
+   'use strict';
+   return eval('this');
+}
+
+func2.call(null);
+if (func2.call(null) !== null) {
+    fail("#5 strict mode eval receives wrong 'this'");
+}
+
+if (func2.call('hello') !== 'hello') {
+    fail("#6 strict mode eval receives wrong 'this'");
+}
+
+// indirect eval
+var my_eval = eval;
+if (my_eval("'use strict'; this; ") !== this) {
+    fail("#7 strict mode eval receives wrong 'this'");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-276.js b/nashorn/test/script/basic/NASHORN-276.js
new file mode 100644
index 0000000..3bce88f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-276.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-276 :  Octal escape sequences should result in SyntaxError in strict mode
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval('"use strict"; var x = "\\000";');
+    fail("should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("expected SyntaxError, got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-277.js b/nashorn/test/script/basic/NASHORN-277.js
new file mode 100644
index 0000000..38724b3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-277.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-277 : Array.prototype is also an array.
+ *
+ * @test
+ * @run
+ */
+
+if (! Array.isArray(Array.prototype)) {
+    fail("Array.isArray(Array.prototype) is false");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-278.js b/nashorn/test/script/basic/NASHORN-278.js
new file mode 100644
index 0000000..c8bf46e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-278.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-278 : Other directives should also be checked for strictness in strict mode
+ *
+ * @test
+ * @run
+ */
+
+try {
+    // A directive preceding 'use strict' uses octal escape
+    // This should result in SyntaxError.
+    eval(' "foo\\063"; "use strict"; ');
+    fail("should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("expected SyntaxError, got " + e);
+    }
+}
+
+
diff --git a/nashorn/test/script/basic/NASHORN-28.js b/nashorn/test/script/basic/NASHORN-28.js
new file mode 100644
index 0000000..dc964c3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-28.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-28: Issues with String representation of numbers.
+ *
+ * @test
+ * @run
+ */
+
+var str = String(0.0000001);
+if (str != "1e-7") {
+    fail("1e-7 expected, but got " + str);
+} else {
+    print("yes, it is 1e-7");
+}
+
+if (String(-0.000001) !== "-0.000001") {
+    fail('String(-0.000001) === "-0.000001". got ' + (String(-0.000001)));
+} else {
+    print('yes, String(-0.000001) === "-0.000001"');
+}
+
+if (String(-1e-6) !== "-0.000001") {
+    fail('String(-1e-6) === "0.000001". got ' + (String(-1e-6)));
+} else {
+    print('yes, String(-1e-6) === "0.000001"');
+}
+
+if (String(-1E-6) !== "-0.000001") {
+    fail('String(-1E-6) === "0.000001". got ' + (String(-1E-6)));
+} else {
+    print('yes, String(-1E-6) === "0.000001"');
+}
diff --git a/nashorn/test/script/basic/NASHORN-28.js.EXPECTED b/nashorn/test/script/basic/NASHORN-28.js.EXPECTED
new file mode 100644
index 0000000..4e4b9eb
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-28.js.EXPECTED
@@ -0,0 +1,4 @@
+yes, it is 1e-7
+yes, String(-0.000001) === "-0.000001"
+yes, String(-1e-6) === "0.000001"
+yes, String(-1E-6) === "0.000001"
diff --git a/nashorn/test/script/basic/NASHORN-281.js b/nashorn/test/script/basic/NASHORN-281.js
new file mode 100644
index 0000000..77abe81
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-281.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-281 : ScriptObject embed, spill property usage breaks in strict mode
+ *
+ * @test
+ * @run
+ */
+
+function func(arg) {
+  "use strict";
+  arg.foo = 44;
+}
+
+
+var obj = {};
+func(obj);
+
+if (obj.foo !== 44) {
+    fail("#1 obj.foo should 44, but it is " + obj.foo);
+}
+
+var obj1 = {}
+Object.preventExtensions(obj1);
+
+try {
+    func(obj1);
+    fail("#2 should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#3 expected TypeError, got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-284.js b/nashorn/test/script/basic/NASHORN-284.js
new file mode 100644
index 0000000..41f210e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-284.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-284 :  Guard setup in ScriptObject.findGetMethod is wrong for inherited properties
+ *
+ * @test
+ * @run
+ */
+
+var obj1 = { x : 44 };
+
+var obj2 = Object.create(obj1);
+// shadow obj1.x here
+obj2.x = 'hello';
+
+var obj3 = Object.create(obj2);
+
+function func(obj) {
+   print("x = " + obj.x);
+}
+
+// should print obj2.x from obj3
+func(obj3);
+// the following should expose obj1.x on obj3
+delete obj2.x;
+// now, it should print obj1.x
+func(obj3);
diff --git a/nashorn/test/script/basic/NASHORN-284.js.EXPECTED b/nashorn/test/script/basic/NASHORN-284.js.EXPECTED
new file mode 100644
index 0000000..3114cc4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-284.js.EXPECTED
@@ -0,0 +1,2 @@
+x = hello
+x = 44
diff --git a/nashorn/test/script/basic/NASHORN-285.js b/nashorn/test/script/basic/NASHORN-285.js
new file mode 100644
index 0000000..a7d586e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-285.js
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-258 : loops with continues could be marked terminal
+ *
+ * @test
+ * @run
+ */
+
+function do_not_loop_forever() {   
+    var sum = 0;
+    for (var i = 0; i < 4711; i++) {            
+	sum += i;
+	if (i >= 0) {
+            continue;                                                           
+        }  
+	return sum;
+    }  
+    return sum;
+}
+
+
+function still_tag_terminal() {
+    var sum = 0;
+    for (var i = 0; i < 4711; i++) {            
+	sum += i;
+	for (var j = 0; j < 4712; j++) {
+	    sum += j;
+	    if (j & 1) {
+		continue;
+	    }
+	}
+	return sum;
+    }  
+    return sum;
+}
+
+print(do_not_loop_forever());
+print(still_tag_terminal());
diff --git a/nashorn/test/script/basic/NASHORN-285.js.EXPECTED b/nashorn/test/script/basic/NASHORN-285.js.EXPECTED
new file mode 100644
index 0000000..1baf624
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-285.js.EXPECTED
@@ -0,0 +1,2 @@
+11094405
+11099116
diff --git a/nashorn/test/script/basic/NASHORN-288.js b/nashorn/test/script/basic/NASHORN-288.js
new file mode 100644
index 0000000..b0c43a9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-288.js
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-288 : Guard setup in ScriptObject.findGetMethod is wrong for inherited properties
+ *
+ * @test
+ * @run
+ */
+
+var obj1 = {};
+obj1.foo = function() {
+}
+
+var obj2 = Object.create(obj1);
+
+// inside function to force same callsite
+function func(o) {
+  o.foo();
+}
+
+func(obj2);
+
+// change proto's property that is called
+obj1.foo = 33;
+
+// try again. should get TypeError as 33 is called
+// as function!
+try {
+    func(obj2);
+    fail("should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("should have thrown TypeError");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-29.js b/nashorn/test/script/basic/NASHORN-29.js
new file mode 100644
index 0000000..2455fa9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-29.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-29 :  >>> operator does not work with number string literal.
+ *
+ * @test
+ * @run
+ */
+
+if (("-1.234" >>> 0) !== 4294967295) {
+    print('ERROR ("-1.234" >>> 0) === 4294967295. got ' + (("-1.234" >>> 0)));
+} else {
+    print('yes ("-1.234" >>> 0) === 4294967295"');
+}
+
+var x = ("-1.234" >>> 0);
+if (x !== 4294967295) {
+    print('ERROR x === 4294967295. got ' + (x));
+} else {
+    print('yes x === 4294967295');
+}
diff --git a/nashorn/test/script/basic/NASHORN-29.js.EXPECTED b/nashorn/test/script/basic/NASHORN-29.js.EXPECTED
new file mode 100644
index 0000000..4bb3e80
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-29.js.EXPECTED
@@ -0,0 +1,2 @@
+yes ("-1.234" >>> 0) === 4294967295"
+yes x === 4294967295
diff --git a/nashorn/test/script/basic/NASHORN-293.js b/nashorn/test/script/basic/NASHORN-293.js
new file mode 100644
index 0000000..cd83ec4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-293.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-293: Per-context caching of compiled script classes.
+ *
+ * @test
+ * @run
+ */
+
+// Make sure repeated evals are executed correctly
+for (var i = 0; i < 3; i++) {
+    eval("print('hello')");
+}
+
+// Same content should produce same class only with same source name
+var src = "(void 0).foo";
+
+for (var i = 0; i < 3; i++) {
+    try {
+        eval(src);
+    } catch (e) {
+        var location =  e.fileName ? e.fileName.slice(-9) : "unknown source";
+        print(e.name, "@", location);
+    }
+}
+for (var i = 0; i < 3; i++) {
+    try {
+        eval(src);
+    } catch (e) {
+        var location =  e.fileName ? e.fileName.slice(-9) : "unknown source";
+        print(e.name, "@", location);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-293.js.EXPECTED b/nashorn/test/script/basic/NASHORN-293.js.EXPECTED
new file mode 100644
index 0000000..6827810
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-293.js.EXPECTED
@@ -0,0 +1,9 @@
+hello
+hello
+hello
+TypeError @ #41<eval>
+TypeError @ #41<eval>
+TypeError @ #41<eval>
+TypeError @ #49<eval>
+TypeError @ #49<eval>
+TypeError @ #49<eval>
diff --git a/nashorn/test/script/basic/NASHORN-294.js b/nashorn/test/script/basic/NASHORN-294.js
new file mode 100644
index 0000000..5de3f90
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-294.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-294 : NativeString.lookPrimitive guard is wrong
+ *
+ * @test
+ * @run
+ */
+
+function func(s) {
+    return s.charAt(0);
+}
+
+if (func("hello") !== 'h') {
+    fail("expected 'h' here");
+}
+
+String.prototype.charAt = function() {
+    return "foo";
+}
+
+if (func("world") !== 'foo') {
+    fail("expected 'foo' here");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-296.js b/nashorn/test/script/basic/NASHORN-296.js
new file mode 100644
index 0000000..cbb752f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-296.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-296 : load messes file name in some cases
+ *
+ * @test
+ * @run
+ */
+
+function test(name) {
+    try {
+        load({ script: 'throw new Error()', name: name });
+    } catch(e) {
+        // normalize windows path separator to URL style
+        var actual = e.stack[0].fileName;
+        if (actual !== name) {
+            fail("expected file name to be " + name +
+                 ", actually got file name " + actual);
+        }
+    }
+}
+
+// test inexistent file
+test("com/oracle/node/sample.js");
+
+// test filename without file:/ prefix
+try {
+    throw new Error();
+} catch (e) {
+    test(e.stack[0].fileName.substring(6));
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-297.js b/nashorn/test/script/basic/NASHORN-297.js
new file mode 100644
index 0000000..5486a13
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-297.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-297 : ClassCastException in runcrypto
+ *
+ * @test
+ * @run
+ */
+
+function func(s) {
+    return s.length;
+}
+
+try {
+    if (func(new String("hello")) !== 5) {
+        fail("#1 expected new String('hello').length to be 5");
+    }
+
+    if (func("hello") !== 5) {
+        fail("#2 expected 'hello'.length to be 5");
+    }
+} catch(e) {
+    fail("failed", e);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-30.js b/nashorn/test/script/basic/NASHORN-30.js
new file mode 100644
index 0000000..95676cf
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-30.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-30 :  < operator with string on LHS does not call valueOf of obj on RHS.
+ *
+ * @test
+ * @run
+ */
+
+var obj = {
+    valueOf: function() {
+        print("valueOf call"); 
+        return -2 
+    },
+
+    toString: function() { 
+        print("toString call");
+        return "-2";
+    }
+};
+
+if ("-1" < obj) {
+    fail("('-1' < obj) should be true");
+} else {
+    print("yes, ('-1' < obj) is true");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-30.js.EXPECTED b/nashorn/test/script/basic/NASHORN-30.js.EXPECTED
new file mode 100644
index 0000000..463cb46
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-30.js.EXPECTED
@@ -0,0 +1,2 @@
+valueOf call
+yes, ('-1' < obj) is true
diff --git a/nashorn/test/script/basic/NASHORN-300.js b/nashorn/test/script/basic/NASHORN-300.js
new file mode 100644
index 0000000..fce230a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-300.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-300 : java.lang.VerifyError by node.jar/target/test-classes/simple/test-fs-open.js:25
+ *
+ * @test
+ * @run
+ */
+
+function func1(foo) {
+    if (foo) {  
+       var encoding = arguments[3];
+    }  
+
+    var s = encoding;
+}
+
+function func2() {
+    print(arguments);
+    var x;
+    print(x);
+}
diff --git a/nashorn/test/script/basic/NASHORN-301.js b/nashorn/test/script/basic/NASHORN-301.js
new file mode 100644
index 0000000..b00b78d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-301.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-301 : radix was ignored for toString
+ *
+ * @test
+ * @run
+ */
+
+var i = 255;
+for (radix=2; radix<=36; radix++) {
+    print(i.toString(radix));
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-301.js.EXPECTED b/nashorn/test/script/basic/NASHORN-301.js.EXPECTED
new file mode 100644
index 0000000..764fc93
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-301.js.EXPECTED
@@ -0,0 +1,35 @@
+11111111
+100110
+3333
+2010
+1103
+513
+377
+313
+255
+212
+193
+168
+143
+120
+ff
+f0
+e3
+d8
+cf
+c3
+bd
+b2
+af
+a5
+9l
+9c
+93
+8n
+8f
+87
+7v
+7o
+7h
+7a
+73
diff --git a/nashorn/test/script/basic/NASHORN-304.js b/nashorn/test/script/basic/NASHORN-304.js
new file mode 100644
index 0000000..4d740e0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-304.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-304 :
+ *
+ * @test
+ * @run
+ */
+
+function func(x, y, z) {
+    z = arguments[arguments.length - 1];
+    return { length: arguments.length, x : x, y: y, z: z };
+}
+
+var res = func(42);
+
+if (res.length !== 1) {
+    fail("#1 arguments.length !== 1");
+}
+
+if (res.x !== 42) {
+    fail("#2 x != 42");
+}
+
+if (typeof res.y !== 'undefined') {
+    fail("#3 y is not undefined");
+}
+
+if (res.z !== 42) {
+    fail("#3 z != 42");
+}
diff --git a/nashorn/test/script/basic/NASHORN-310.js b/nashorn/test/script/basic/NASHORN-310.js
new file mode 100644
index 0000000..c49c2b4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-310.js
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-310 : Failed: test-next-tick-errors.js
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+Object.defineProperty(obj, "nextTick", {
+    value: function(callback) {
+        (function() {
+            callback();
+        })();
+    }
+});
+
+obj.nextTick(function (foo) {
+    print("callback one");
+});
+
+obj.nextTick(function (foo) {
+    print("callback two");
+});
+
+function func(callback) {
+    (function() {
+        callback();
+     })();
+}
+
+func(function() { print("callback one"); });
+func(function() { print("callback two"); });
+
+
diff --git a/nashorn/test/script/basic/NASHORN-310.js.EXPECTED b/nashorn/test/script/basic/NASHORN-310.js.EXPECTED
new file mode 100644
index 0000000..8c9b382
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-310.js.EXPECTED
@@ -0,0 +1,4 @@
+callback one
+callback two
+callback one
+callback two
diff --git a/nashorn/test/script/basic/NASHORN-318.js b/nashorn/test/script/basic/NASHORN-318.js
new file mode 100644
index 0000000..209a6bd
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-318.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-318 : (null == {}) evaluates to true and (null != {}) evaluates to false
+ *
+ * @test
+ * @run
+ */
+
+print("null == {} ? " + (null == {}));
+print("null != {} ? " + (null != {}));
+
+var x = null;
+print("null == x ? " + (null == x));
+print("x == null ? " + (x == null));
diff --git a/nashorn/test/script/basic/NASHORN-318.js.EXPECTED b/nashorn/test/script/basic/NASHORN-318.js.EXPECTED
new file mode 100644
index 0000000..8b649a4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-318.js.EXPECTED
@@ -0,0 +1,4 @@
+null == {} ? false
+null != {} ? true
+null == x ? true
+x == null ? true
diff --git a/nashorn/test/script/basic/NASHORN-32.js b/nashorn/test/script/basic/NASHORN-32.js
new file mode 100644
index 0000000..0fd625b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-32.js
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-32: should not be able to read, write, call properties from null literal.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    print(null["foo"]);
+} catch (e) {
+    print(e instanceof TypeError);
+    print(e);
+}
+
+try {
+    print(null.foo);
+} catch (e) {
+    print(e instanceof TypeError);
+    print(e);
+}
+
+try {
+    null["foo"] = 55;
+} catch (e) {
+    print(e instanceof TypeError);
+    print(e);
+}
+
+try {
+    null.foo = 55;
+} catch (e) {
+    print(e instanceof TypeError);
+    print(e);
+}
+
+try {
+    print(null.foo());
+} catch (e) {
+    print(e instanceof TypeError);
+    print(e);
+}
+
+try {
+    print(new null());
+} catch (e) {
+    print(e instanceof TypeError);
+    print(e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-32.js.EXPECTED b/nashorn/test/script/basic/NASHORN-32.js.EXPECTED
new file mode 100644
index 0000000..6c08641
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-32.js.EXPECTED
@@ -0,0 +1,12 @@
+true
+TypeError: Cannot get property "foo" of null
+true
+TypeError: Cannot get property "foo" of null
+true
+TypeError: Cannot set property "foo" of null
+true
+TypeError: Cannot set property "foo" of null
+true
+TypeError: null has no such function "foo"
+true
+TypeError: null is not a function
diff --git a/nashorn/test/script/basic/NASHORN-321.js b/nashorn/test/script/basic/NASHORN-321.js
new file mode 100644
index 0000000..9510c17
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-321.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-321 : Global function change is not seen by a callsite
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+   print("func one");
+}
+
+function f() { func(); }
+
+f();
+
+func = function() {
+   print("func two");
+}
+
+f();
diff --git a/nashorn/test/script/basic/NASHORN-321.js.EXPECTED b/nashorn/test/script/basic/NASHORN-321.js.EXPECTED
new file mode 100644
index 0000000..88ac4b6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-321.js.EXPECTED
@@ -0,0 +1,2 @@
+func one
+func two
diff --git a/nashorn/test/script/basic/NASHORN-323.js b/nashorn/test/script/basic/NASHORN-323.js
new file mode 100644
index 0000000..c1715c0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-323.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-323 : Broken int EQ/NE
+ *
+ * @test
+ * @run
+ */
+
+function f() {
+    var x = 8;
+    print (x == 4);
+}
+
+f();
+
+
diff --git a/nashorn/test/script/basic/NASHORN-323.js.EXPECTED b/nashorn/test/script/basic/NASHORN-323.js.EXPECTED
new file mode 100644
index 0000000..c508d53
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-323.js.EXPECTED
@@ -0,0 +1 @@
+false
diff --git a/nashorn/test/script/basic/NASHORN-324.js b/nashorn/test/script/basic/NASHORN-324.js
new file mode 100644
index 0000000..11aa51c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-324.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-324 : Array.prototype.reduceRight function broken
+ *
+ * @test
+ * @run
+ */
+
+var called = 0;
+
+function callbackfn(preVal, val, idx, obj) {
+    called++;
+}
+
+var arr = [0, 1, 2, 3];
+Object.defineProperty(arr, "4", {
+    get: function () { arr.length = 2; },
+    configurable: true
+});
+
+arr.reduceRight(callbackfn, "initialValue");
+
+if (called !== 3) {
+    fail("called count !== 3");
+}
diff --git a/nashorn/test/script/basic/NASHORN-33.js b/nashorn/test/script/basic/NASHORN-33.js
new file mode 100644
index 0000000..2ed87e4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-33.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-33 : local variable type inference should take all paths into account.
+ *
+ * @test
+ * @run
+ */
+
+function func(y) {
+   var x;
+
+   if (y == 1) {
+      x = 4.4;
+   }
+
+   return x;
+}
+
+print(typeof(func(1)));
+print(typeof(func(0)));
+
+
+
diff --git a/nashorn/test/script/basic/NASHORN-33.js.EXPECTED b/nashorn/test/script/basic/NASHORN-33.js.EXPECTED
new file mode 100644
index 0000000..72ce2f4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-33.js.EXPECTED
@@ -0,0 +1,2 @@
+number
+undefined
diff --git a/nashorn/test/script/basic/NASHORN-331.js b/nashorn/test/script/basic/NASHORN-331.js
new file mode 100644
index 0000000..41ce529
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-331.js
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-331 : Nan compares 
+ *
+ * @test
+ * @run
+ */
+
+print(undefined == null);
+print(undefined != null);
+print(undefined === null);
+print(undefined !== null);
+print(null == undefined);
+print(null != undefined);
+print(null === undefined);
+print(null !== undefined);
+
+var n = Math.NaN;
+var x = 17;
+print(x < n);
+print(x > n);
+print(x >= n);
+print(x <= n);
+print(x == n);
+print(x != n);
+print(x == n);
+print(x !== n);
+
+var u = undefined;
+var y = 18;
+print(x < u);
+print(x > u);
+print(x >= u);
+print(x <= u);
+print(x == u);
+print(x != u);
+print(x == u);
+print(x !== u);
diff --git a/nashorn/test/script/basic/NASHORN-331.js.EXPECTED b/nashorn/test/script/basic/NASHORN-331.js.EXPECTED
new file mode 100644
index 0000000..7681906
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-331.js.EXPECTED
@@ -0,0 +1,24 @@
+true
+false
+false
+true
+true
+false
+false
+true
+false
+false
+false
+false
+false
+true
+false
+true
+false
+false
+false
+false
+false
+true
+false
+true
diff --git a/nashorn/test/script/basic/NASHORN-337.js b/nashorn/test/script/basic/NASHORN-337.js
new file mode 100644
index 0000000..dc8bac1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-337.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-337 - Erroneous DCMPL/DCMPG instructions were generated
+ * 
+ * @test
+ * @run
+ */
+
+var x;
+
+print("Value: " + x);
+print("Numerical Value: " + (+x));
+print("Boolean Value(>0): " + ((+x) > 0));
+print("Boolean Value(<0): " + ((+x) < 0));
+print("Boolean Value(==0): " + ((+x) == 0));
+
+print("NaN > 0? " + (NaN > 0));
+print("NaN < 0? " + (NaN < 0));
+print("NaN == 0? " + (NaN == 0));
+
+
diff --git a/nashorn/test/script/basic/NASHORN-337.js.EXPECTED b/nashorn/test/script/basic/NASHORN-337.js.EXPECTED
new file mode 100644
index 0000000..e1c2259
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-337.js.EXPECTED
@@ -0,0 +1,8 @@
+Value: undefined
+Numerical Value: NaN
+Boolean Value(>0): false
+Boolean Value(<0): false
+Boolean Value(==0): false
+NaN > 0? false
+NaN < 0? false
+NaN == 0? false
diff --git a/nashorn/test/script/basic/NASHORN-34.js b/nashorn/test/script/basic/NASHORN-34.js
new file mode 100644
index 0000000..267768d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-34.js
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/**
+ * Extend Java abstract classes using script functions.
+ *
+ * @test
+ * @run
+ */
+
+var task = new java.util.TimerTask({
+    run: function() {
+        print("Inside run function");
+    }
+});
+
+// now call the 'run' method on the extended class
+task.run();
+
+// The following sytax sugar should also be fine..
+
+var task2 = new java.util.TimerTask() {
+   run: function() {
+       print("This is TimerTask.run");
+   }
+};
+
+task2.run();
+
diff --git a/nashorn/test/script/basic/NASHORN-34.js.EXPECTED b/nashorn/test/script/basic/NASHORN-34.js.EXPECTED
new file mode 100644
index 0000000..221834d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-34.js.EXPECTED
@@ -0,0 +1,2 @@
+Inside run function
+This is TimerTask.run
diff --git a/nashorn/test/script/basic/NASHORN-340.js b/nashorn/test/script/basic/NASHORN-340.js
new file mode 100644
index 0000000..c20ceab
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-340.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-340 : Uninitialized variables incorrectly handled in array literals.
+ *
+ * @test
+ * @run
+ */
+
+var x;
+var undef = undefined;
+var a = [ 1, x ];
+var b = [ 3.14, x ];
+var c = [ x ];
+var d = [ 1, undef ];
+var e = [ 1, undefined ];
+var f = [ 1, , ];
+print('"' + a + '"');
+print('"' + b + '"');
+print('"' + c + '"');
+print('"' + d + '"');
+print('"' + e + '"');
+print('"' + f + '"');
diff --git a/nashorn/test/script/basic/NASHORN-340.js.EXPECTED b/nashorn/test/script/basic/NASHORN-340.js.EXPECTED
new file mode 100644
index 0000000..9324ebf
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-340.js.EXPECTED
@@ -0,0 +1,6 @@
+"1,"
+"3.14,"
+""
+"1,"
+"1,"
+"1,"
diff --git a/nashorn/test/script/basic/NASHORN-349.js b/nashorn/test/script/basic/NASHORN-349.js
new file mode 100644
index 0000000..a611a58
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-349.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * Remove lower optimization to transform obj['foo'] as obj.foo
+ *
+ * @test
+ * @run
+ */
+
+var m = new java.util.HashMap();
+m.put("foo", "hello");
+
+// map allows keys to be accessed using indexed access
+if (m['foo'] !== 'hello') {
+    fail("m['foo'] !== 'hello'");
+}
+
+var prop = 'foo';
+if (m[prop] !== 'hello') {
+    fail("m['foo'] !== 'hello'");
+}
+
+// map keys are accessible as properties when there's no matching bean property.
+if (m.foo !== 'hello') {
+    fail("m.foo !== 'hello'");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-354.js b/nashorn/test/script/basic/NASHORN-354.js
new file mode 100644
index 0000000..506a032
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-354.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-354
+ *
+ * @test
+ * @run
+ */
+
+function f() {
+    var zero = 0;
+    return zero !== false;
+}
+var i = 0;
+function g() {
+    return (i++) !== false;
+}
+print(f());
+print(g());
+print(i);
diff --git a/nashorn/test/script/basic/NASHORN-354.js.EXPECTED b/nashorn/test/script/basic/NASHORN-354.js.EXPECTED
new file mode 100644
index 0000000..a46dbf7
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-354.js.EXPECTED
@@ -0,0 +1,3 @@
+true
+true
+1
diff --git a/nashorn/test/script/basic/NASHORN-355.js b/nashorn/test/script/basic/NASHORN-355.js
new file mode 100644
index 0000000..f036072
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-355.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-355
+ *
+ * @test
+ * @run
+ */
+
+var a = "gorilla";
+
+var c = function() {
+  this.a = "ape";
+  this.m = function() { print("a=" + this.a); };
+}
+
+var o = new c();
+o.m();
+o["m"]();
+var method = "m";
+o[method]();
diff --git a/nashorn/test/script/basic/NASHORN-355.js.EXPECTED b/nashorn/test/script/basic/NASHORN-355.js.EXPECTED
new file mode 100644
index 0000000..5359eb2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-355.js.EXPECTED
@@ -0,0 +1,3 @@
+a=ape
+a=ape
+a=ape
diff --git a/nashorn/test/script/basic/NASHORN-36.js b/nashorn/test/script/basic/NASHORN-36.js
new file mode 100644
index 0000000..3a8a0c9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-36.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-36 : Not all line terminators are accepted for single line comments.
+ *
+ * @test
+ * @run
+ */
+
+// refer to ECMA section 7.3 Line Terminators
+// Table 3 Line Terminator Characters.
+
+// Because line comment ends with any of line terminators
+// the following evals should set global 'x' with values.
+
+eval("// line comment\u000A x = 1;");
+print(x); // should print 1
+
+eval("// line comment\u000D x = 2;");
+print(x); // should print 2
+
+eval("// line comment\u2028 x = 3;");
+print(x); // should print 3
+
+eval("// line comment\u2029 x = 4;");
+print(x); // should print 4
+
diff --git a/nashorn/test/script/basic/NASHORN-36.js.EXPECTED b/nashorn/test/script/basic/NASHORN-36.js.EXPECTED
new file mode 100644
index 0000000..94ebaf9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-36.js.EXPECTED
@@ -0,0 +1,4 @@
+1
+2
+3
+4
diff --git a/nashorn/test/script/basic/NASHORN-365.js b/nashorn/test/script/basic/NASHORN-365.js
new file mode 100644
index 0000000..fe79e8c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-365.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-365 : JSON.parse should complain about junk at the end of the parsed string
+ *
+ * @test
+ * @run
+ */
+
+function check(str) {
+    try {
+        JSON.parse(str);
+        fail("should have got SyntaxError for " + str);
+    } catch (e) {
+        if (! (e instanceof SyntaxError)) {
+            fail("SyntaxError expected got " + e);
+        }
+    }
+}
+
+check("34\t454");
+check("34  55");
+check("{ 'foo': 34 } 343");
+check("[344, 55] 454");
diff --git a/nashorn/test/script/basic/NASHORN-366.js b/nashorn/test/script/basic/NASHORN-366.js
new file mode 100644
index 0000000..fae219b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-366.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-366 : RegExp.prototype is a RegExp object and should support properties like source, global etc.
+ *
+ * @test
+ * @run
+ */
+
+print(typeof RegExp.prototype.lastIndex)
+print(typeof RegExp.prototype.source)
+print(typeof RegExp.prototype.global)
+print(typeof RegExp.prototype.ignoreCase)
+print(typeof RegExp.prototype.multiline)
diff --git a/nashorn/test/script/basic/NASHORN-366.js.EXPECTED b/nashorn/test/script/basic/NASHORN-366.js.EXPECTED
new file mode 100644
index 0000000..5316ccb
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-366.js.EXPECTED
@@ -0,0 +1,5 @@
+number
+string
+boolean
+boolean
+boolean
diff --git a/nashorn/test/script/basic/NASHORN-368.js b/nashorn/test/script/basic/NASHORN-368.js
new file mode 100644
index 0000000..a1b1ba2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-368.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-368: RegExp.exec: lastIndex not reset to 0 if lastIndex == string.length()
+ *
+ * @test
+ * @run
+ */
+
+function test() {
+  var r = /regex/g;
+  var str = "regex regex regex";
+  var str2 = "nooooooooooooooooooooo!";
+  for (var i = 0; i < 10; i++) {
+    print(r.exec(i != 6 ? str : str2));
+    print(r.lastIndex);
+  }
+}
+test();
diff --git a/nashorn/test/script/basic/NASHORN-368.js.EXPECTED b/nashorn/test/script/basic/NASHORN-368.js.EXPECTED
new file mode 100644
index 0000000..75fa806
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-368.js.EXPECTED
@@ -0,0 +1,20 @@
+regex
+5
+regex
+11
+regex
+17
+null
+0
+regex
+5
+regex
+11
+null
+0
+regex
+5
+regex
+11
+regex
+17
diff --git a/nashorn/test/script/basic/NASHORN-37.js b/nashorn/test/script/basic/NASHORN-37.js
new file mode 100644
index 0000000..74ee037
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-37.js
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-37 :  object and array properties defined with special keys can be accessed be by special or string keys
+ * 
+ * @test
+ * @run
+ */
+
+var obj = {};
+
+obj[true] = "hello";
+print(obj["true"]);
+print(obj[true]);
+
+obj["false"] = 33;
+print(obj[false]);
+print(obj['false']);
+
+obj[null] = "foo";
+print(obj["null"]);
+print(obj[null]);
+
+obj[undefined] = "bar";
+print(obj["undefined"]);
+print(obj["undefined"]);
+
+obj[33] = 343;
+print(obj[33]);
+print(obj['33']);
+
+obj['2'] = 3.14;
+print(obj[2]);
+print(obj['2']);
+
+var key = {
+    toString: function() {
+        print("key.toString called");
+        return 'key';
+    }
+};
+
+obj[key] = 'value';
+print(obj[key]);
+print(obj['key']);
+
+var array = [ "foo", "bar" ];
+
+print(array[0]);
+print(array["0"]);
+
+print(array[1]);
+print(array["1"]);
+
diff --git a/nashorn/test/script/basic/NASHORN-37.js.EXPECTED b/nashorn/test/script/basic/NASHORN-37.js.EXPECTED
new file mode 100644
index 0000000..1ddbb05
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-37.js.EXPECTED
@@ -0,0 +1,20 @@
+hello
+hello
+33
+33
+foo
+foo
+bar
+bar
+343
+343
+3.14
+3.14
+key.toString called
+key.toString called
+value
+value
+foo
+foo
+bar
+bar
diff --git a/nashorn/test/script/basic/NASHORN-375.js b/nashorn/test/script/basic/NASHORN-375.js
new file mode 100644
index 0000000..6f84148
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-375.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-375 : Invalid hex and unicode escapes in strings and identifiers are not reported as error
+ *
+ * @test
+ * @run
+ */
+
+function check(code) {
+    try {
+        eval(code);
+        fail("should have thrown SyntaxError for " + name);
+    } catch (e) {
+        if (! (e instanceof SyntaxError)) {
+            print("Expected SyntaxError for " + name + ", got " + e);
+        }
+    }
+}
+
+// invalid hex escape in string
+check("var str = '\\xzworld';");
+
+// invalid unicode escape in string
+check("var s = '\\uihello';");
+
+// invalid hex escape in string
+check("var str = '\\xzworld';");
+
+if ("\x00" !== "\0") {
+    fail("'\\x00' != '\\0'");
+}
diff --git a/nashorn/test/script/basic/NASHORN-376.js b/nashorn/test/script/basic/NASHORN-376.js
new file mode 100644
index 0000000..37aa345
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-376.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-376 : using 'this' keyword as operand for ++ or -- or as L-value of assignment operator should result in error
+ *
+ * @test
+ * @run
+ */
+
+function check(code) {
+    try {
+        eval(code);
+        fail("should have result in error " + code);
+    } catch (e) {
+        if (! (e instanceof ReferenceError)) {
+            fail("ReferenceError expected for '" + code + "' , got " + e);
+        }
+    }
+}
+
+check("this = 4;");
+check("this++");
+check("++this");
+check("this--");
+check("--this");
diff --git a/nashorn/test/script/basic/NASHORN-377.js b/nashorn/test/script/basic/NASHORN-377.js
new file mode 100644
index 0000000..e77be2b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-377.js
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-377: Typed arrays.
+ *
+ * @test
+ * @run
+ */
+
+var types = [Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];
+
+//---------------------------------------------------------------------------
+// utility functions
+//---------------------------------------------------------------------------
+function tohex(d, w) {
+  var hex = Number(d).toString(16);
+  var pad = (w ? w : 8) - hex.length;
+  hex = "00000000".substr(0, pad) + hex;
+  return hex;
+}
+
+function arrstr(a, n, w) {
+  var s = "";
+  if (typeof n == "undefined") n = a.length;
+  if (typeof w == "undefined") w = a.BYTES_PER_ELEMENT * 2;
+  for (var i = 0; i < n; i++) {
+    s += tohex(a[i], w);
+  }
+  return s;
+}
+function bufstr(b) {
+  if (b.buffer !== undefined) {
+    b = b.buffer;
+  }
+  return arrstr(new Uint8Array(b));
+}
+
+function assertFail(f) {
+  try {
+    f();
+  } catch (e) {
+    //print(e);
+    return;
+  }
+  throw "assertion failed: expected exception";
+}
+
+function assertTrue(f) {
+  if (f() !== true) throw "assertion failed: " + f;
+}
+
+function isUndefined(x) {
+  return typeof x === "undefined";
+}
+
+function fillArray(a, start) {
+  if (typeof start == "undefined") start = 1;
+  for (var i = 0; i < a.length; i++) {
+    a[i] = i + start;
+  }
+  return a;
+}
+
+//---------------------------------------------------------------------------
+// tests
+//---------------------------------------------------------------------------
+(function() {
+  var b = new ArrayBuffer(8);
+  var i8 = new Int8Array(b);
+  print(i8.buffer.byteLength, b.byteLength, i8.buffer === b, b.length);
+  print(b, i8.buffer, i8);
+})();
+
+(function test_attributes() {
+  var b = new ArrayBuffer(8);
+  for (var i in types) {
+    var x = new types[i](b);
+    print(x.byteOffset, x.byteLength, x.length, x.BYTES_PER_ELEMENT);
+    assertTrue(function(){ return x.constructor === types[i] });
+  }
+})();
+
+(function() {
+  var b = new ArrayBuffer(8);
+  var i8 = new Int8Array(b);
+  fillArray(i8, 0x70);
+
+  var i8_2 = new Int8Array(b, 2);
+  var i8_2_4 = new Uint8Array(b, 2, 4);
+
+  i8_2_4[3] = 0x80;
+
+  print(arrstr(i8, 8, 2)  + " " + bufstr(i8));
+  print(arrstr(i8_2, 6)   + " " + i8_2.byteOffset   + " " + i8_2.byteLength);
+  print(arrstr(i8_2_4, 4) + " " + i8_2_4.byteOffset + " " + i8_2_4.byteLength);
+
+  var i8_1_5 = i8.subarray(1, 5);
+  i8_2_4.subarray(1, 5);
+  print(arrstr(i8_1_5, 4) + " " + i8_1_5.byteOffset + " " + i8_1_5.byteLength);
+
+  print(bufstr(b.slice(1,7)));
+})();
+
+(function() {
+  var b = new ArrayBuffer(8);
+  fillArray(new Int8Array(b), 0x70);
+  new Int8Array(b)[5] = 0x80;
+
+  var i32 = new Int32Array(b);
+  var u32 = new Uint32Array(b);
+  print(arrstr(i32), i32[0], i32[1]);
+  i32[1] = 0xfefdfcfb;
+  print(arrstr(i32), i32[0], i32[1]);
+  print(arrstr(u32), u32[0], u32[1]);
+
+  var pi = 3.1415926;
+  var f32 = new Float32Array(b);
+  var f64 = new Float64Array(b);
+  f32[0] = pi;
+  print(bufstr(b), f32.length);
+  f64[0] = pi;
+  print(bufstr(b), f64.length);
+  print(arrstr(u32), u32[0], u32[1]);
+
+  var d = new Int32Array(3);
+  d.set(i32,1);
+  print(bufstr(d));
+
+  var s = new Int16Array(b);
+  var t = new Uint16Array(b);
+  print(arrstr(s), arrstr(t));
+  s[0] = -1; s[1] = 0x80;
+  print(arrstr(s), arrstr(t));
+})();
+
+(function enumerate_properties() {
+  var i8 = new Int8Array(new ArrayBuffer(8));
+  var s = ""; for (var i in i8) { s += i + " "; } print(s.trim());
+})();
+
+// check that ScriptObject fallback is still working
+// DISABLED because correct behavior is unclear
+(function() {
+  // NB: firefox will never set any out-of-bounds or non-array values although it does get both from prototype.
+  var z = new Uint8Array(4);
+  z["asdf"] = "asdf"; print(z["asdf"]);
+  z[0x100000000] = "asdf"; print(z[0x100000000]);
+  z[-1] = "asdf"; print(z[-1]);
+
+  // v8 and nashorn disagree on out-of-bounds uint32 indices: v8 won't go to the prototype.
+  z[0xf0000000] = "asdf"; print(z[0xf0000000]);
+  z[0xffffffff] = "asdf"; print(z[0xffffffff]);
+  z[0x70000000] = "asdf"; print(z[0x70000000]);
+
+  // this will work in firefox and nashorn (not in v8).
+  Uint8Array.prototype[4] = "asdf"; print(z[4]);
+});
+
+(function test_exceptions() {
+  assertFail(function() { new Int32Array(new ArrayBuffer(7)); });
+  assertFail(function() { new Int32Array(new ArrayBuffer(8), 0, 4); });
+  assertFail(function() { new Int32Array(new ArrayBuffer(8),-1, 2); });
+  assertFail(function() { new Int32Array(new ArrayBuffer(8), 0,-1); });
+})();
+
+(function test_subarray() {
+  var x = fillArray(new Int8Array(8));
+  print(arrstr(x));
+  print("subarray(2,4)=" + arrstr(x.subarray(2, 4)), "subarray(-6,-4)=" + arrstr(x.subarray(-6, -4))); // negative index refers from the end of the array
+  print(arrstr(x.subarray(-10, -2))); // negative index clamped to 0
+  assertTrue(function(){ return arrstr(x.subarray(6, 4)) === ""; }); // negative length clamped to 0
+  print(arrstr(x.subarray(1,-1).subarray(1,-1)), arrstr(x.subarray(1,-1).subarray(1,-1).subarray(1,-1))); // subarray of subarray
+})();
+
+(function test_slice() {
+  var b = ArrayBuffer(16);
+  fillArray(new Int8Array(b));
+  print(bufstr(b));
+  print("slice(4,8)=" + bufstr(b.slice(4, 8)), "slice(-8,-4)=" + bufstr(b.slice(-8, -4))); // negative index refers from the end of the array
+  print(bufstr(b.slice(-20, -4))); // negative index clamped to 0
+  assertTrue(function(){ return bufstr(b.slice(8, 4)) === ""; }); // negative length clamped to 0
+  print(arrstr(new Int16Array(b.slice(1,-1).slice(2,-1).slice(1,-2).slice(1,-1)))); // slice of slice
+})();
+
+(function test_clamped() {
+  var a = new Uint8ClampedArray(10);
+  a[0] = -17;       // clamped to 0
+  a[1] = 4711;      // clamped to 255
+  a[2] = 17.5;      // clamped to 18
+  a[3] = 16.5;      // clamped to 16
+  a[4] = 255.9;     // clamped to 255
+  a[5] = Infinity;  // clamped to 255
+  a[6] = -Infinity; // clamped to 0
+  a[7] = NaN;       // 0
+  assertTrue(function(){ return a[0] === 0 && a[1] === 255 && a[2] === 18 && a[3] === 16 && a[4] === 255 && a[5] === 255 && a[6] === 0 && a[7] === 0; });
+})();
+
+(function test_out_of_bounds() {
+  var a = new Int32Array(10);
+  a[10] = 10;
+  a[100] = 100;
+  a[1000] = 1000;
+  assertTrue(function(){ return isUndefined(a[10]) && isUndefined(a[11]) && isUndefined(a[100]) && isUndefined(a[123]) && isUndefined(a[1000]); });
+})();
+
diff --git a/nashorn/test/script/basic/NASHORN-377.js.EXPECTED b/nashorn/test/script/basic/NASHORN-377.js.EXPECTED
new file mode 100644
index 0000000..76bf14d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-377.js.EXPECTED
@@ -0,0 +1,34 @@
+8 8 true undefined
+[object Object] [object Object] [object Object]
+0 8 8 1
+0 8 8 1
+0 8 8 1
+0 8 4 2
+0 8 4 2
+0 8 2 4
+0 8 2 4
+0 8 2 4
+0 8 1 8
+7071727374-807677 7071727374807677
+727374-807677 2 6
+72737480 2 4
+71727374 1 4
+717273748076
+7372717077768074 1936879984 2004254836
+73727170-1020305 1936879984 -16909061
+73727170fefdfcfb 1936879984 4278058235
+da0f4940fbfcfdfe 2
+4ad8124dfb210940 1
+4d12d84a400921fb 1293080650 1074340347
+000000004ad8124dfb210940
+-27b64d1221fb4009 d84a4d1221fb4009
+00-1008021fb4009 ffff008021fb4009
+0 1 2 3 4 5 6 7
+0102030405060708
+subarray(2,4)=0304 subarray(-6,-4)=0304
+010203040506
+03040506 0405
+0102030405060708090a0b0c0d0e0f10
+slice(4,8)=05060708 slice(-8,-4)=090a0b0c
+0102030405060708090a0b0c
+070609080b0a
diff --git a/nashorn/test/script/basic/NASHORN-378.js b/nashorn/test/script/basic/NASHORN-378.js
new file mode 100644
index 0000000..0bf2a74
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-378.js
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-378 : Redefining a configurable accessor property to be a data property on a non-extensible object fails with NPE
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+Object.defineProperty(obj, "foo", 
+    { get: function() { return 42; },
+      configurable: true});
+
+if (obj.foo !== 42) {
+    fail("#0 obj.foo !== 42");
+}
+
+Object.preventExtensions(obj);
+Object.defineProperty(obj, "foo", { value: "hello"});
+
+var desc = Object.getOwnPropertyDescriptor(obj, "foo");
+
+if (obj.foo !== "hello") {
+    fail("#1 obj.foo !== 'hello'");
+}
+
+if (desc.get !== undefined) {
+    fail("#2 getter found on a date property");
+}
+
+if (desc.set !== undefined) {
+    fail("#3 setter found on a date property");
+}
+
+if (desc.value !== 'hello') {
+    fail("#4 value property is wrong");
+}
diff --git a/nashorn/test/script/basic/NASHORN-38.js b/nashorn/test/script/basic/NASHORN-38.js
new file mode 100644
index 0000000..b02ecf7
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-38.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-38 : Nested function is visible from the start of the outer function definition.
+ *
+ * @test
+ * @run
+ */
+
+function func(){
+    // 'f' is visible and it is function
+    // defined later in lexical order (see below)
+    print(typeof f);
+    return f;
+  
+    function f(){
+        print("inside function 'f'");
+    }
+}
+
+// calling the returned function from 'func'
+func()();
diff --git a/nashorn/test/script/basic/NASHORN-38.js.EXPECTED b/nashorn/test/script/basic/NASHORN-38.js.EXPECTED
new file mode 100644
index 0000000..b1000c2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-38.js.EXPECTED
@@ -0,0 +1,2 @@
+function
+inside function 'f'
diff --git a/nashorn/test/script/basic/NASHORN-380.js b/nashorn/test/script/basic/NASHORN-380.js
new file mode 100644
index 0000000..e41380e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-380.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-380 : JSAdapter should support 'overrides' feature
+ *
+ * @test
+ * @run
+ */
+
+var obj = new JSAdapter({ foo: 444, bar: 6546 }) {
+   __get__: function(name) { print("in getter"); return name; }
+};
+
+print(obj.func);   // calls __get__('func')
+print(obj.foo);    // just gets 444 as it is a override
+print(obj.bar);    // get 6546 as it is a override
diff --git a/nashorn/test/script/basic/NASHORN-380.js.EXPECTED b/nashorn/test/script/basic/NASHORN-380.js.EXPECTED
new file mode 100644
index 0000000..0b91e6d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-380.js.EXPECTED
@@ -0,0 +1,4 @@
+in getter
+func
+444
+6546
diff --git a/nashorn/test/script/basic/NASHORN-381.js b/nashorn/test/script/basic/NASHORN-381.js
new file mode 100644
index 0000000..53237fa
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-381.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-381 : JSAdapter override mechanism should not search properties of it's own proto
+ *
+ * @test
+ * @run
+ */
+
+var toStringAccessed = false;
+
+var obj = new JSAdapter({}) {
+    __get__: function(name) {
+        if (name == 'toString') {
+           toStringAccessed = true;
+        }
+    }
+};
+
+if (obj.toString === Object.prototype.toString) {
+    fail("JSAdapter uses Object.prototype properties");
+}
+
+if (! toStringAccessed) {
+    fail("JSAdapter does not use __get__ for toString access");
+}
diff --git a/nashorn/test/script/basic/NASHORN-382.js b/nashorn/test/script/basic/NASHORN-382.js
new file mode 100644
index 0000000..71ab3a5
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-382.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-382 : We should be able to pass __proto__ to JSAdapter constructor.
+ *
+ * @test
+ * @run
+ */
+
+var obj1 = new JSAdapter() {};
+if (!(obj1 instanceof JSAdapter)) {
+    fail("#1 !(obj1 instanceof JSAdapter)");
+}
+
+function Buffer() {}
+var obj2 = new JSAdapter(Buffer.prototype, {}) {};
+if (!(obj2 instanceof Buffer)) {
+    fail("#2 !(obj2 instanceof Buffer)");
+}
diff --git a/nashorn/test/script/basic/NASHORN-383.js b/nashorn/test/script/basic/NASHORN-383.js
new file mode 100644
index 0000000..ae1a06e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-383.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-383 : JSAdapter __get__ is not called from a callsite exercised earlier by an array object
+ *
+ * @test
+ * @run
+ */
+
+function func(obj) {
+    return obj[0];
+}
+
+var arr = [3, 4];
+if (arr[0] !== func(arr)) {
+    fail("#1 func does not return array element");
+}
+
+var getterCalled = false;
+var res = func(new JSAdapter() {
+   __get__: function(name) {
+       getterCalled = true;
+       return name;
+   }
+});
+
+if (! getterCalled) {
+    fail("#2 __get__ not called");
+}
+
+if (res !== 0) {
+    fail("#3 __get__ did not return '0'");
+}
diff --git a/nashorn/test/script/basic/NASHORN-384.js b/nashorn/test/script/basic/NASHORN-384.js
new file mode 100644
index 0000000..4c40050
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-384.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-384 : array pop preceded by shift does not work as expected
+ *
+ * @test
+ * @run
+ */
+
+var a = [1, 2];
+print(a.shift());
+print(a.pop());
+
diff --git a/nashorn/test/script/basic/NASHORN-384.js.EXPECTED b/nashorn/test/script/basic/NASHORN-384.js.EXPECTED
new file mode 100644
index 0000000..1191247
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-384.js.EXPECTED
@@ -0,0 +1,2 @@
+1
+2
diff --git a/nashorn/test/script/basic/NASHORN-385.js b/nashorn/test/script/basic/NASHORN-385.js
new file mode 100644
index 0000000..27b328e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-385.js
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-385 : JSAdapter throws AssertionError when adaptee does not define hook methods like __get__, __put__ etc.
+ *
+ * @test
+ * @run
+ */
+
+var proto = {};
+var o = new JSAdapter(proto);
+
+function checkGetter() {
+    print("o.foo => " + o.foo);
+}
+
+function checkSetter() {
+    o.bar = 44;
+} 
+
+function checkCall() {
+    try {
+        o.func();
+    } catch (e) {
+        print(e);
+    }
+}
+
+checkGetter();
+checkSetter();
+checkCall();
+
+proto.__get__ = function(name) { 
+    print("in __get__: " + name); 
+    return name;
+};
+
+proto.__put__ = function(name) {
+    print("in __put__: " + name);
+}
+
+proto.__call__ = function(name) {
+    print("in __call__: " + name);
+}
+
+checkGetter();
+checkSetter();
+checkCall();
diff --git a/nashorn/test/script/basic/NASHORN-385.js.EXPECTED b/nashorn/test/script/basic/NASHORN-385.js.EXPECTED
new file mode 100644
index 0000000..5765485
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-385.js.EXPECTED
@@ -0,0 +1,6 @@
+o.foo => undefined
+TypeError: [object JSAdapter] has no such function "func"
+in __get__: foo
+o.foo => foo
+in __put__: bar
+in __call__: func
diff --git a/nashorn/test/script/basic/NASHORN-389.js b/nashorn/test/script/basic/NASHORN-389.js
new file mode 100644
index 0000000..71f9731
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-389.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * NASHORN-389 : number to string conversion issues.
+ *
+ * @test
+ * @run
+ */
+
+print(1000000000000000000000);
+print(0.000000000100000000000);
+print(1e-5);
+var x = -1.23456789e+21;
+var y = -1.23456789e+20;
+print(x.toFixed(9));
+print(y.toFixed(9).indexOf(",") === -1); // no grouping
+//print(y.toFixed(9)); // FIXME expected: -123456788999999995904.000000000
+//print(1000000000000000128); // FIXME expected: 1000000000000000100
+//print((1000000000000000128).toFixed(0)); // FIXME expected: 1000000000000000128
diff --git a/nashorn/test/script/basic/NASHORN-389.js.EXPECTED b/nashorn/test/script/basic/NASHORN-389.js.EXPECTED
new file mode 100644
index 0000000..5981d96
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-389.js.EXPECTED
@@ -0,0 +1,5 @@
+1e+21
+1e-10
+0.00001
+-1.23456789e+21
+true
diff --git a/nashorn/test/script/basic/NASHORN-393.js b/nashorn/test/script/basic/NASHORN-393.js
new file mode 100644
index 0000000..80f4083
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-393.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * NASHORN-384 : array pop pops incorrect element
+ *
+ * @test
+ * @run
+ */
+
+var a = [1, 2];
+a.length = 4;
+
+print(a);
+a.pop();
+print(a);
+
diff --git a/nashorn/test/script/basic/NASHORN-393.js.EXPECTED b/nashorn/test/script/basic/NASHORN-393.js.EXPECTED
new file mode 100644
index 0000000..1657afc
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-393.js.EXPECTED
@@ -0,0 +1,2 @@
+1,2,,
+1,2,
diff --git a/nashorn/test/script/basic/NASHORN-394.js b/nashorn/test/script/basic/NASHORN-394.js
new file mode 100644
index 0000000..a265f16
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-394.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-394 : array pop converts undefined into 0
+ *
+ * @test
+ * @run
+ */
+
+var a = [];
+a.length = 2;
+print(a.pop());
+
diff --git a/nashorn/test/script/basic/NASHORN-394.js.EXPECTED b/nashorn/test/script/basic/NASHORN-394.js.EXPECTED
new file mode 100644
index 0000000..417b7b5
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-394.js.EXPECTED
@@ -0,0 +1 @@
+undefined
diff --git a/nashorn/test/script/basic/NASHORN-396.js b/nashorn/test/script/basic/NASHORN-396.js
new file mode 100644
index 0000000..46bcf77
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-396.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-396 : In strict mode ToObject conversion should not be done on thisArg
+ *
+ * @test
+ * @run
+ */
+ 
+Object.defineProperty(Number.prototype, 
+    "foo", 
+    { get: function () { 'use strict'; return this; }
+}); 
+
+if(!((5).foo === 5)) {
+    fail("#1 ToObject conversion on 'thisArg' for strict getter");
+}
+
+Number.prototype.func = function() { 
+    'use strict';
+    return this;
+};
+
+if ((typeof (34).func()) != 'number') {
+    fail("#2 ToObject called on 'thisArg' when calling strict func");
+}
diff --git a/nashorn/test/script/basic/NASHORN-397.js b/nashorn/test/script/basic/NASHORN-397.js
new file mode 100644
index 0000000..6bd55bf
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-397.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-397 : typeof on certain member access expressions computes to undefined wrongly
+ *
+ * @test
+ * @run
+ */
+
+Object.defineProperty(Number.prototype, 'x',
+    { get : function() { return 42; } });
+
+if (typeof (5).x !== 'number') {
+    fail("typeof(5).x is not 'number'");
+}
+
+if (typeof (java.lang.System.out) != 'object') {
+    fail("typeof java.lang.System.out is not 'object'");
+}
+
+if (typeof (java.lang.Math.PI) != 'number') {
+    fail("typeof java.lang.Math.PI is not 'number'");
+}
+
+if (typeof (java.io.File.separator) != 'string') {
+    fail("typeof java.io.File.separator is not 'string'");
+}
diff --git a/nashorn/test/script/basic/NASHORN-398.js b/nashorn/test/script/basic/NASHORN-398.js
new file mode 100644
index 0000000..6a0535f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-398.js
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-398 : Should not be able to set non-existing indexed property if object is not extensible
+ *
+ * @test
+ * @run
+ */
+
+function funcNonStrict(array) {
+    var obj = array? [] : {};
+    Object.preventExtensions(obj);
+    obj[0] = 12;
+    if (obj[0] === 12) {
+        fail("#1 obj[0] has been set");
+    }
+
+    if (obj.hasOwnProperty("0")) {
+        fail("#2 has property '0'");
+    }
+}
+
+funcNonStrict(true);
+funcNonStrict(false);
+
+function funcStrict(array) {
+    'use strict';
+
+    var obj = array? [] : {};
+    Object.preventExtensions(obj);
+    try {
+        obj[0] = 12;
+        fail("#3 should have thrown TypeError");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#4 TypeError expected, got " + e);
+        }
+    }
+
+    if (obj[0] === 12) {
+        fail("#5 obj[0] has been set");
+    }
+
+    if (obj.hasOwnProperty("0")) {
+        fail("has property '0'");
+    }
+}
+
+funcStrict(true);
+funcStrict(false);
+
diff --git a/nashorn/test/script/basic/NASHORN-40.js b/nashorn/test/script/basic/NASHORN-40.js
new file mode 100644
index 0000000..f031730
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-40.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-40 : Member select expression without the select object expression (nothing before ".") crashes compiler with NPE.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval("print(.foo)");
+} catch (e) {
+    print(e.toString().replace(/\\/g, '/'));
+}
+
+try {
+    eval(".bar = 3423;");
+} catch (e) {
+    print(e.toString().replace(/\\/g, '/'));
+}
diff --git a/nashorn/test/script/basic/NASHORN-40.js.EXPECTED b/nashorn/test/script/basic/NASHORN-40.js.EXPECTED
new file mode 100644
index 0000000..0e03cab
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-40.js.EXPECTED
@@ -0,0 +1,6 @@
+SyntaxError: test/script/basic/NASHORN-40.js#32<eval>:1:6 Expected an operand but found .
+print(.foo)
+      ^
+SyntaxError: test/script/basic/NASHORN-40.js#38<eval>:1:0 Expected an operand but found .
+.bar = 3423;
+^
diff --git a/nashorn/test/script/basic/NASHORN-400.js b/nashorn/test/script/basic/NASHORN-400.js
new file mode 100644
index 0000000..eabb8ad
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-400.js
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-400 : java.lang.VerifyError with shadow arguments.
+ *
+ * @test
+ * @run
+ */
+
+function test(value, cb) {
+    print(cb(value))
+}
+
+function x (er) {
+    if (!er) {}
+    test("nest", function (er) {
+        if (er) return er
+    });
+}
+x(5);
+
+function inof(a) {
+  if (!a) {}
+  return a instanceof Number;
+}
+inof(42);
+
+function forin(a) {
+  if (!a) {}
+  for (var i in a);
+}
+forin(42);
+
+function forinlocal() {
+ var I = 42;
+ for (var i in I) print(i);
+}
+forinlocal();
+
+function add(d) {
+  if (!d) {}
+  print(d + 10);
+}
+add("3")
+
diff --git a/nashorn/test/script/basic/NASHORN-400.js.EXPECTED b/nashorn/test/script/basic/NASHORN-400.js.EXPECTED
new file mode 100644
index 0000000..e6257d6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-400.js.EXPECTED
@@ -0,0 +1,2 @@
+nest
+310
diff --git a/nashorn/test/script/basic/NASHORN-401.js b/nashorn/test/script/basic/NASHORN-401.js
new file mode 100644
index 0000000..b6058a9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-401.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-401 : Overloaded method resolution not selecting correctly between double, int, string
+ *
+ * @test
+ * @run
+ */
+
+var t = new Packages.jdk.nashorn.internal.runtime.Nashorn401TestSubject();
+
+print(t.method2(10));
+print(t.method2(10.2));
+print(t.method2("a"));
+
+print(t.method3(10));
+print(t.method3("10"));
+print(t.method3("10.2"));
+print(t.method3("foo"));
+
+print(t.method4(10));
+print(t.method4(10.2));
+print(t.method4("foo"));
diff --git a/nashorn/test/script/basic/NASHORN-401.js.EXPECTED b/nashorn/test/script/basic/NASHORN-401.js.EXPECTED
new file mode 100644
index 0000000..b7d3303
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-401.js.EXPECTED
@@ -0,0 +1,10 @@
+int method 2
+double method 2
+string method 2
+int method 3: 10
+double method 3: 10.0
+double method 3: 10.2
+double method 3: NaN
+int method 4: 10
+double method 4: 10.2
+double method 4: NaN
diff --git a/nashorn/test/script/basic/NASHORN-402.js b/nashorn/test/script/basic/NASHORN-402.js
new file mode 100644
index 0000000..33c02a1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-402.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-402 : Implement RegExp.prototype.compile function
+ *
+ * @test
+ * @run
+ */
+
+var str = "JavaScript is a scripting language";
+var re = new RegExp;
+re.compile ("\\w+", "g");
+var match;
+while ((match = re.exec(str)) != null) {
+    print(match.index + "-" + re.lastIndex + " " + match[0]);
+    if (! (match instanceof Array)) {
+        fail("RegExp.prototype.exec result has to be an array");
+    }
+    if (! Array.isArray(match)) {
+        fail("RegExp.prototype.exec result has to be an array");
+    }
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-402.js.EXPECTED b/nashorn/test/script/basic/NASHORN-402.js.EXPECTED
new file mode 100644
index 0000000..cc6b538
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-402.js.EXPECTED
@@ -0,0 +1,5 @@
+0-10 JavaScript
+11-13 is
+14-15 a
+16-25 scripting
+26-34 language
diff --git a/nashorn/test/script/basic/NASHORN-404.js b/nashorn/test/script/basic/NASHORN-404.js
new file mode 100644
index 0000000..672fe89
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-404.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-404 : Error.prototype and subtypes do not have any enumerable properties
+ *
+ * @test
+ * @run
+ */
+
+function check(name) {
+    var obj = this[name].prototype;
+    for (i in obj) {
+        fail("enumerable property: " + name  + ".prototype." + i);
+    }
+}
+
+check("Error");
+check("EvalError");
+check("RangeError");
+check("ReferenceError");
+check("SyntaxError");
+check("URIError");
diff --git a/nashorn/test/script/basic/NASHORN-405.js b/nashorn/test/script/basic/NASHORN-405.js
new file mode 100644
index 0000000..c104924
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-405.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-405 make sure slice does not modify arrays
+ * 
+ * @test
+ * @run
+ */
+
+var x = ['foo', '%zx'];
+var s = x.slice(1); 
+print(s);
+print(x);
+
diff --git a/nashorn/test/script/basic/NASHORN-405.js.EXPECTED b/nashorn/test/script/basic/NASHORN-405.js.EXPECTED
new file mode 100644
index 0000000..c560c09
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-405.js.EXPECTED
@@ -0,0 +1,2 @@
+%zx
+foo,%zx
diff --git a/nashorn/test/script/basic/NASHORN-406.js b/nashorn/test/script/basic/NASHORN-406.js
new file mode 100644
index 0000000..a1f362f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-406.js
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-406 : Property descriptor properties should be enumerable 
+ *
+ * @test
+ * @run
+ */
+
+var obj = {
+    foo : 10,
+    get bar() { return 32; },
+    set bar(x) {},
+};
+
+function checkData() {
+   var desc = Object.getOwnPropertyDescriptor(obj, "foo");
+   var enumSeen = false, writeSeen = false, 
+       configSeen = false, valueSeen = false;
+   for (i in desc) {
+       switch(i) {
+           case 'enumerable':
+               enumSeen = true; break;
+           case 'writable':
+               writeSeen = true; break;
+           case 'configurable':
+               configSeen = true; break;
+           case 'value':
+               valueSeen = true; break;
+       }
+   }
+   
+   return enumSeen && writeSeen && configSeen && valueSeen;
+}
+
+if (!checkData()) {
+    fail("data descriptor check failed");
+}
+
+function checkAccessor() {
+   var desc = Object.getOwnPropertyDescriptor(obj, "bar");
+   var enumSeen = false, getterSeen = false, 
+       configSeen = false, setterSeen = false;
+   for (i in desc) {
+       switch(i) {
+           case 'enumerable':
+               enumSeen = true; break;
+           case 'configurable':
+               configSeen = true; break;
+           case 'get':
+               getterSeen = true; break;
+           case 'set':
+               setterSeen = true; break;
+        }
+   }
+
+   return enumSeen && configSeen && getterSeen && setterSeen;
+}
+
+if (!checkAccessor()) {
+    fail("accessor descriptor check failed");
+}
diff --git a/nashorn/test/script/basic/NASHORN-408.js b/nashorn/test/script/basic/NASHORN-408.js
new file mode 100644
index 0000000..1c3375c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-408.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-408 :Object.getOwnPropertyDescriptor does not work for String indices
+ *
+ * @test
+ * @run
+ */
+
+var str = new String("hello");
+for (var i = 0; i < str.length; i++) {
+    var desc = Object.getOwnPropertyDescriptor(str, i + '');
+    print("{ configurable: " + desc.configurable + ", " +
+    "enumerable: " + desc.enumerable + ", " +
+    "writable: " + desc.writable + ", " +
+    "value = " + desc.value + " }");
+}
diff --git a/nashorn/test/script/basic/NASHORN-408.js.EXPECTED b/nashorn/test/script/basic/NASHORN-408.js.EXPECTED
new file mode 100644
index 0000000..0d72a3d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-408.js.EXPECTED
@@ -0,0 +1,5 @@
+{ configurable: false, enumerable: true, writable: false, value = h }
+{ configurable: false, enumerable: true, writable: false, value = e }
+{ configurable: false, enumerable: true, writable: false, value = l }
+{ configurable: false, enumerable: true, writable: false, value = l }
+{ configurable: false, enumerable: true, writable: false, value = o }
diff --git a/nashorn/test/script/basic/NASHORN-415.js b/nashorn/test/script/basic/NASHORN-415.js
new file mode 100644
index 0000000..6f29f1a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-415.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-415 : Object.keys should return String indexes for String objects
+ *
+ * @test
+ * @run
+ */
+
+var str = new String("hello");
+
+print(Object.keys(str));
+str.foo = 33;
+print(Object.keys(str));
diff --git a/nashorn/test/script/basic/NASHORN-415.js.EXPECTED b/nashorn/test/script/basic/NASHORN-415.js.EXPECTED
new file mode 100644
index 0000000..1e8a3a9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-415.js.EXPECTED
@@ -0,0 +1,2 @@
+0,1,2,3,4
+0,1,2,3,4,foo
diff --git a/nashorn/test/script/basic/NASHORN-416.js b/nashorn/test/script/basic/NASHORN-416.js
new file mode 100644
index 0000000..387629a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-416.js
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-416 : Setting setter method using defineProperty erases old getter method
+ *
+ * @test
+ * @run
+ */
+
+var obj = {}
+
+function getter() { return 32; }
+
+Object.defineProperty(obj, "foo", 
+  { get: getter, configurable: true });
+
+function setter(x) { print(x); }
+
+Object.defineProperty(obj, "foo",
+ { set: setter });
+
+var desc = Object.getOwnPropertyDescriptor(obj, "foo");
+
+if (desc.get !== getter) {
+    fail("desc.get !== getter");
+}
+
+if (desc.set !== setter) {
+    fail("desc.set !== setter");
+}
diff --git a/nashorn/test/script/basic/NASHORN-417.js b/nashorn/test/script/basic/NASHORN-417.js
new file mode 100644
index 0000000..6148f06
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-417.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-417 : Accessor descriptor property with undefined getter and setter is reported as data descriptor property
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+Object.defineProperty(obj, "foo", {
+    get: undefined, set: undefined });
+
+var desc = Object.getOwnPropertyDescriptor(obj, "foo");
+if (! ('get' in desc)) {
+    fail("#1 desc does not have 'get'");
+}
+
+if (! ('set' in desc)) {
+    fail("#2 desc does not have 'set'");
+}
+
+if ('value' in desc) {
+    fail("#3 desc has 'value'");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-418.js b/nashorn/test/script/basic/NASHORN-418.js
new file mode 100644
index 0000000..b42bd83
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-418.js
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-418 : When a data descriptor property is changed to an accessor descriptor property, new configurable, enumerable flags are not set
+ *
+ * @test
+ * @run
+ */
+
+var obj = { foo: 33 };
+
+var oldDesc = Object.getOwnPropertyDescriptor(obj, "foo");
+if (! oldDesc.enumerable) {
+    fail("#1 'foo' is not enumerable");
+}
+
+if (! oldDesc.configurable) {
+    fail("#2 'foo' is not configurable");
+}
+
+Object.defineProperty(obj, "foo", {
+    enumerable: false, configurable: false,
+    get: function() { return 'hello' } });
+
+var newDesc = Object.getOwnPropertyDescriptor(obj, "foo");
+if (newDesc.enumerable) {
+    fail("#3 'foo' is enumerable");
+}
+
+if (newDesc.configurable) {
+    fail("#4 'foo' is configurable");
+}
+
+var obj2 = {};
+
+Object.defineProperty(obj2, "foo", {
+    value : 34, writable: false, configurable: true });
+
+var setterCalled = true;
+// descriptor type change, writable is not inherited
+Object.defineProperty(obj2, "foo", {
+  get: undefined, set: function(x) { setterCalled = true } });
+
+// can still attempt to write
+obj2.foo = 44;
+if (! setterCalled) {
+    fail("#5 obj2.foo setter not called");
+}
+
+var obj3 = {};
+
+Object.defineProperty(obj3, "foo", {
+  get: undefined, set: function(x) { }, configurable: true });
+
+Object.defineProperty(obj3, "foo", { value: 33 });
+
+var desc = Object.getOwnPropertyDescriptor(obj3, "foo");
+if (desc.writable) {
+    fail("#6 obj3.foo is writable");
+}
diff --git a/nashorn/test/script/basic/NASHORN-420.js b/nashorn/test/script/basic/NASHORN-420.js
new file mode 100644
index 0000000..741b940
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-420.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-420 : When an existing array element attributes are changed by defineProperty, element value becomes undefined
+ *
+ * @test
+ * @run
+ */
+
+var arrObj = [100];
+Object.defineProperty(arrObj, "0", {
+    writable: false,
+    enumerable: false,
+    configurable: false
+});
+
+var desc = Object.getOwnPropertyDescriptor(arrObj, "0");
+if (desc.value !== arrObj[0]) {
+    fail("#1 desc.value !== arrObj[0]");
+}
+
+if (desc.value !== 100) {
+    fail("#2 desc.value !== 100");
+}
diff --git a/nashorn/test/script/basic/NASHORN-421.js b/nashorn/test/script/basic/NASHORN-421.js
new file mode 100644
index 0000000..3a81fe6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-421.js
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-421 : Many Array.prototype functions miss ToObject conversion of 'self' as required by specification
+ *
+ * @test
+ * @run
+ */
+
+function checkUndefined(name) {
+   try {
+       Array.prototype[name].call(undefined);
+       fail( name + " - no TypeError for undefined 'this'");
+       return false;
+    } catch (e) {
+       if (! (e instanceof TypeError)) {
+           throw e;
+       }
+    }
+}
+
+function checkNull(name) {
+   try {
+       Array.prototype[name].call(null);
+       fail(name + " - no TypeError for null 'this'");
+       return false;
+    } catch (e) {
+       if (! (e instanceof TypeError)) {
+           throw e;
+       }
+    }
+}
+
+var methods = [ "concat", "join", "pop", "push", "reverse", 
+    "shift", "unshift", "slice", "sort", "splice",
+    "indexOf", "lastIndexOf", "every", "some", "forEach", 
+    "map", "filter", "reduce", "reduceRight" ];
+
+for (var m in methods) {
+    checkUndefined(methods[m]);
+    checkNull(methods[m]);
+}
diff --git a/nashorn/test/script/basic/NASHORN-423.js b/nashorn/test/script/basic/NASHORN-423.js
new file mode 100644
index 0000000..7fa1b00
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-423.js
@@ -0,0 +1,4030 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-423 - Large scripts don't fit into a single class file and need to be split.
+ *
+ * @test
+ * @run
+ */
+
+print(0);
+print(1);
+print(2);
+print(3);
+print(4);
+print(5);
+print(6);
+print(7);
+print(8);
+print(9);
+print(10);
+print(11);
+print(12);
+print(13);
+print(14);
+print(15);
+print(16);
+print(17);
+print(18);
+print(19);
+print(20);
+print(21);
+print(22);
+print(23);
+print(24);
+print(25);
+print(26);
+print(27);
+print(28);
+print(29);
+print(30);
+print(31);
+print(32);
+print(33);
+print(34);
+print(35);
+print(36);
+print(37);
+print(38);
+print(39);
+print(40);
+print(41);
+print(42);
+print(43);
+print(44);
+print(45);
+print(46);
+print(47);
+print(48);
+print(49);
+print(50);
+print(51);
+print(52);
+print(53);
+print(54);
+print(55);
+print(56);
+print(57);
+print(58);
+print(59);
+print(60);
+print(61);
+print(62);
+print(63);
+print(64);
+print(65);
+print(66);
+print(67);
+print(68);
+print(69);
+print(70);
+print(71);
+print(72);
+print(73);
+print(74);
+print(75);
+print(76);
+print(77);
+print(78);
+print(79);
+print(80);
+print(81);
+print(82);
+print(83);
+print(84);
+print(85);
+print(86);
+print(87);
+print(88);
+print(89);
+print(90);
+print(91);
+print(92);
+print(93);
+print(94);
+print(95);
+print(96);
+print(97);
+print(98);
+print(99);
+print(100);
+print(101);
+print(102);
+print(103);
+print(104);
+print(105);
+print(106);
+print(107);
+print(108);
+print(109);
+print(110);
+print(111);
+print(112);
+print(113);
+print(114);
+print(115);
+print(116);
+print(117);
+print(118);
+print(119);
+print(120);
+print(121);
+print(122);
+print(123);
+print(124);
+print(125);
+print(126);
+print(127);
+print(128);
+print(129);
+print(130);
+print(131);
+print(132);
+print(133);
+print(134);
+print(135);
+print(136);
+print(137);
+print(138);
+print(139);
+print(140);
+print(141);
+print(142);
+print(143);
+print(144);
+print(145);
+print(146);
+print(147);
+print(148);
+print(149);
+print(150);
+print(151);
+print(152);
+print(153);
+print(154);
+print(155);
+print(156);
+print(157);
+print(158);
+print(159);
+print(160);
+print(161);
+print(162);
+print(163);
+print(164);
+print(165);
+print(166);
+print(167);
+print(168);
+print(169);
+print(170);
+print(171);
+print(172);
+print(173);
+print(174);
+print(175);
+print(176);
+print(177);
+print(178);
+print(179);
+print(180);
+print(181);
+print(182);
+print(183);
+print(184);
+print(185);
+print(186);
+print(187);
+print(188);
+print(189);
+print(190);
+print(191);
+print(192);
+print(193);
+print(194);
+print(195);
+print(196);
+print(197);
+print(198);
+print(199);
+print(200);
+print(201);
+print(202);
+print(203);
+print(204);
+print(205);
+print(206);
+print(207);
+print(208);
+print(209);
+print(210);
+print(211);
+print(212);
+print(213);
+print(214);
+print(215);
+print(216);
+print(217);
+print(218);
+print(219);
+print(220);
+print(221);
+print(222);
+print(223);
+print(224);
+print(225);
+print(226);
+print(227);
+print(228);
+print(229);
+print(230);
+print(231);
+print(232);
+print(233);
+print(234);
+print(235);
+print(236);
+print(237);
+print(238);
+print(239);
+print(240);
+print(241);
+print(242);
+print(243);
+print(244);
+print(245);
+print(246);
+print(247);
+print(248);
+print(249);
+print(250);
+print(251);
+print(252);
+print(253);
+print(254);
+print(255);
+print(256);
+print(257);
+print(258);
+print(259);
+print(260);
+print(261);
+print(262);
+print(263);
+print(264);
+print(265);
+print(266);
+print(267);
+print(268);
+print(269);
+print(270);
+print(271);
+print(272);
+print(273);
+print(274);
+print(275);
+print(276);
+print(277);
+print(278);
+print(279);
+print(280);
+print(281);
+print(282);
+print(283);
+print(284);
+print(285);
+print(286);
+print(287);
+print(288);
+print(289);
+print(290);
+print(291);
+print(292);
+print(293);
+print(294);
+print(295);
+print(296);
+print(297);
+print(298);
+print(299);
+print(300);
+print(301);
+print(302);
+print(303);
+print(304);
+print(305);
+print(306);
+print(307);
+print(308);
+print(309);
+print(310);
+print(311);
+print(312);
+print(313);
+print(314);
+print(315);
+print(316);
+print(317);
+print(318);
+print(319);
+print(320);
+print(321);
+print(322);
+print(323);
+print(324);
+print(325);
+print(326);
+print(327);
+print(328);
+print(329);
+print(330);
+print(331);
+print(332);
+print(333);
+print(334);
+print(335);
+print(336);
+print(337);
+print(338);
+print(339);
+print(340);
+print(341);
+print(342);
+print(343);
+print(344);
+print(345);
+print(346);
+print(347);
+print(348);
+print(349);
+print(350);
+print(351);
+print(352);
+print(353);
+print(354);
+print(355);
+print(356);
+print(357);
+print(358);
+print(359);
+print(360);
+print(361);
+print(362);
+print(363);
+print(364);
+print(365);
+print(366);
+print(367);
+print(368);
+print(369);
+print(370);
+print(371);
+print(372);
+print(373);
+print(374);
+print(375);
+print(376);
+print(377);
+print(378);
+print(379);
+print(380);
+print(381);
+print(382);
+print(383);
+print(384);
+print(385);
+print(386);
+print(387);
+print(388);
+print(389);
+print(390);
+print(391);
+print(392);
+print(393);
+print(394);
+print(395);
+print(396);
+print(397);
+print(398);
+print(399);
+print(400);
+print(401);
+print(402);
+print(403);
+print(404);
+print(405);
+print(406);
+print(407);
+print(408);
+print(409);
+print(410);
+print(411);
+print(412);
+print(413);
+print(414);
+print(415);
+print(416);
+print(417);
+print(418);
+print(419);
+print(420);
+print(421);
+print(422);
+print(423);
+print(424);
+print(425);
+print(426);
+print(427);
+print(428);
+print(429);
+print(430);
+print(431);
+print(432);
+print(433);
+print(434);
+print(435);
+print(436);
+print(437);
+print(438);
+print(439);
+print(440);
+print(441);
+print(442);
+print(443);
+print(444);
+print(445);
+print(446);
+print(447);
+print(448);
+print(449);
+print(450);
+print(451);
+print(452);
+print(453);
+print(454);
+print(455);
+print(456);
+print(457);
+print(458);
+print(459);
+print(460);
+print(461);
+print(462);
+print(463);
+print(464);
+print(465);
+print(466);
+print(467);
+print(468);
+print(469);
+print(470);
+print(471);
+print(472);
+print(473);
+print(474);
+print(475);
+print(476);
+print(477);
+print(478);
+print(479);
+print(480);
+print(481);
+print(482);
+print(483);
+print(484);
+print(485);
+print(486);
+print(487);
+print(488);
+print(489);
+print(490);
+print(491);
+print(492);
+print(493);
+print(494);
+print(495);
+print(496);
+print(497);
+print(498);
+print(499);
+print(500);
+print(501);
+print(502);
+print(503);
+print(504);
+print(505);
+print(506);
+print(507);
+print(508);
+print(509);
+print(510);
+print(511);
+print(512);
+print(513);
+print(514);
+print(515);
+print(516);
+print(517);
+print(518);
+print(519);
+print(520);
+print(521);
+print(522);
+print(523);
+print(524);
+print(525);
+print(526);
+print(527);
+print(528);
+print(529);
+print(530);
+print(531);
+print(532);
+print(533);
+print(534);
+print(535);
+print(536);
+print(537);
+print(538);
+print(539);
+print(540);
+print(541);
+print(542);
+print(543);
+print(544);
+print(545);
+print(546);
+print(547);
+print(548);
+print(549);
+print(550);
+print(551);
+print(552);
+print(553);
+print(554);
+print(555);
+print(556);
+print(557);
+print(558);
+print(559);
+print(560);
+print(561);
+print(562);
+print(563);
+print(564);
+print(565);
+print(566);
+print(567);
+print(568);
+print(569);
+print(570);
+print(571);
+print(572);
+print(573);
+print(574);
+print(575);
+print(576);
+print(577);
+print(578);
+print(579);
+print(580);
+print(581);
+print(582);
+print(583);
+print(584);
+print(585);
+print(586);
+print(587);
+print(588);
+print(589);
+print(590);
+print(591);
+print(592);
+print(593);
+print(594);
+print(595);
+print(596);
+print(597);
+print(598);
+print(599);
+print(600);
+print(601);
+print(602);
+print(603);
+print(604);
+print(605);
+print(606);
+print(607);
+print(608);
+print(609);
+print(610);
+print(611);
+print(612);
+print(613);
+print(614);
+print(615);
+print(616);
+print(617);
+print(618);
+print(619);
+print(620);
+print(621);
+print(622);
+print(623);
+print(624);
+print(625);
+print(626);
+print(627);
+print(628);
+print(629);
+print(630);
+print(631);
+print(632);
+print(633);
+print(634);
+print(635);
+print(636);
+print(637);
+print(638);
+print(639);
+print(640);
+print(641);
+print(642);
+print(643);
+print(644);
+print(645);
+print(646);
+print(647);
+print(648);
+print(649);
+print(650);
+print(651);
+print(652);
+print(653);
+print(654);
+print(655);
+print(656);
+print(657);
+print(658);
+print(659);
+print(660);
+print(661);
+print(662);
+print(663);
+print(664);
+print(665);
+print(666);
+print(667);
+print(668);
+print(669);
+print(670);
+print(671);
+print(672);
+print(673);
+print(674);
+print(675);
+print(676);
+print(677);
+print(678);
+print(679);
+print(680);
+print(681);
+print(682);
+print(683);
+print(684);
+print(685);
+print(686);
+print(687);
+print(688);
+print(689);
+print(690);
+print(691);
+print(692);
+print(693);
+print(694);
+print(695);
+print(696);
+print(697);
+print(698);
+print(699);
+print(700);
+print(701);
+print(702);
+print(703);
+print(704);
+print(705);
+print(706);
+print(707);
+print(708);
+print(709);
+print(710);
+print(711);
+print(712);
+print(713);
+print(714);
+print(715);
+print(716);
+print(717);
+print(718);
+print(719);
+print(720);
+print(721);
+print(722);
+print(723);
+print(724);
+print(725);
+print(726);
+print(727);
+print(728);
+print(729);
+print(730);
+print(731);
+print(732);
+print(733);
+print(734);
+print(735);
+print(736);
+print(737);
+print(738);
+print(739);
+print(740);
+print(741);
+print(742);
+print(743);
+print(744);
+print(745);
+print(746);
+print(747);
+print(748);
+print(749);
+print(750);
+print(751);
+print(752);
+print(753);
+print(754);
+print(755);
+print(756);
+print(757);
+print(758);
+print(759);
+print(760);
+print(761);
+print(762);
+print(763);
+print(764);
+print(765);
+print(766);
+print(767);
+print(768);
+print(769);
+print(770);
+print(771);
+print(772);
+print(773);
+print(774);
+print(775);
+print(776);
+print(777);
+print(778);
+print(779);
+print(780);
+print(781);
+print(782);
+print(783);
+print(784);
+print(785);
+print(786);
+print(787);
+print(788);
+print(789);
+print(790);
+print(791);
+print(792);
+print(793);
+print(794);
+print(795);
+print(796);
+print(797);
+print(798);
+print(799);
+print(800);
+print(801);
+print(802);
+print(803);
+print(804);
+print(805);
+print(806);
+print(807);
+print(808);
+print(809);
+print(810);
+print(811);
+print(812);
+print(813);
+print(814);
+print(815);
+print(816);
+print(817);
+print(818);
+print(819);
+print(820);
+print(821);
+print(822);
+print(823);
+print(824);
+print(825);
+print(826);
+print(827);
+print(828);
+print(829);
+print(830);
+print(831);
+print(832);
+print(833);
+print(834);
+print(835);
+print(836);
+print(837);
+print(838);
+print(839);
+print(840);
+print(841);
+print(842);
+print(843);
+print(844);
+print(845);
+print(846);
+print(847);
+print(848);
+print(849);
+print(850);
+print(851);
+print(852);
+print(853);
+print(854);
+print(855);
+print(856);
+print(857);
+print(858);
+print(859);
+print(860);
+print(861);
+print(862);
+print(863);
+print(864);
+print(865);
+print(866);
+print(867);
+print(868);
+print(869);
+print(870);
+print(871);
+print(872);
+print(873);
+print(874);
+print(875);
+print(876);
+print(877);
+print(878);
+print(879);
+print(880);
+print(881);
+print(882);
+print(883);
+print(884);
+print(885);
+print(886);
+print(887);
+print(888);
+print(889);
+print(890);
+print(891);
+print(892);
+print(893);
+print(894);
+print(895);
+print(896);
+print(897);
+print(898);
+print(899);
+print(900);
+print(901);
+print(902);
+print(903);
+print(904);
+print(905);
+print(906);
+print(907);
+print(908);
+print(909);
+print(910);
+print(911);
+print(912);
+print(913);
+print(914);
+print(915);
+print(916);
+print(917);
+print(918);
+print(919);
+print(920);
+print(921);
+print(922);
+print(923);
+print(924);
+print(925);
+print(926);
+print(927);
+print(928);
+print(929);
+print(930);
+print(931);
+print(932);
+print(933);
+print(934);
+print(935);
+print(936);
+print(937);
+print(938);
+print(939);
+print(940);
+print(941);
+print(942);
+print(943);
+print(944);
+print(945);
+print(946);
+print(947);
+print(948);
+print(949);
+print(950);
+print(951);
+print(952);
+print(953);
+print(954);
+print(955);
+print(956);
+print(957);
+print(958);
+print(959);
+print(960);
+print(961);
+print(962);
+print(963);
+print(964);
+print(965);
+print(966);
+print(967);
+print(968);
+print(969);
+print(970);
+print(971);
+print(972);
+print(973);
+print(974);
+print(975);
+print(976);
+print(977);
+print(978);
+print(979);
+print(980);
+print(981);
+print(982);
+print(983);
+print(984);
+print(985);
+print(986);
+print(987);
+print(988);
+print(989);
+print(990);
+print(991);
+print(992);
+print(993);
+print(994);
+print(995);
+print(996);
+print(997);
+print(998);
+print(999);
+print(1000);
+print(1001);
+print(1002);
+print(1003);
+print(1004);
+print(1005);
+print(1006);
+print(1007);
+print(1008);
+print(1009);
+print(1010);
+print(1011);
+print(1012);
+print(1013);
+print(1014);
+print(1015);
+print(1016);
+print(1017);
+print(1018);
+print(1019);
+print(1020);
+print(1021);
+print(1022);
+print(1023);
+print(1024);
+print(1025);
+print(1026);
+print(1027);
+print(1028);
+print(1029);
+print(1030);
+print(1031);
+print(1032);
+print(1033);
+print(1034);
+print(1035);
+print(1036);
+print(1037);
+print(1038);
+print(1039);
+print(1040);
+print(1041);
+print(1042);
+print(1043);
+print(1044);
+print(1045);
+print(1046);
+print(1047);
+print(1048);
+print(1049);
+print(1050);
+print(1051);
+print(1052);
+print(1053);
+print(1054);
+print(1055);
+print(1056);
+print(1057);
+print(1058);
+print(1059);
+print(1060);
+print(1061);
+print(1062);
+print(1063);
+print(1064);
+print(1065);
+print(1066);
+print(1067);
+print(1068);
+print(1069);
+print(1070);
+print(1071);
+print(1072);
+print(1073);
+print(1074);
+print(1075);
+print(1076);
+print(1077);
+print(1078);
+print(1079);
+print(1080);
+print(1081);
+print(1082);
+print(1083);
+print(1084);
+print(1085);
+print(1086);
+print(1087);
+print(1088);
+print(1089);
+print(1090);
+print(1091);
+print(1092);
+print(1093);
+print(1094);
+print(1095);
+print(1096);
+print(1097);
+print(1098);
+print(1099);
+print(1100);
+print(1101);
+print(1102);
+print(1103);
+print(1104);
+print(1105);
+print(1106);
+print(1107);
+print(1108);
+print(1109);
+print(1110);
+print(1111);
+print(1112);
+print(1113);
+print(1114);
+print(1115);
+print(1116);
+print(1117);
+print(1118);
+print(1119);
+print(1120);
+print(1121);
+print(1122);
+print(1123);
+print(1124);
+print(1125);
+print(1126);
+print(1127);
+print(1128);
+print(1129);
+print(1130);
+print(1131);
+print(1132);
+print(1133);
+print(1134);
+print(1135);
+print(1136);
+print(1137);
+print(1138);
+print(1139);
+print(1140);
+print(1141);
+print(1142);
+print(1143);
+print(1144);
+print(1145);
+print(1146);
+print(1147);
+print(1148);
+print(1149);
+print(1150);
+print(1151);
+print(1152);
+print(1153);
+print(1154);
+print(1155);
+print(1156);
+print(1157);
+print(1158);
+print(1159);
+print(1160);
+print(1161);
+print(1162);
+print(1163);
+print(1164);
+print(1165);
+print(1166);
+print(1167);
+print(1168);
+print(1169);
+print(1170);
+print(1171);
+print(1172);
+print(1173);
+print(1174);
+print(1175);
+print(1176);
+print(1177);
+print(1178);
+print(1179);
+print(1180);
+print(1181);
+print(1182);
+print(1183);
+print(1184);
+print(1185);
+print(1186);
+print(1187);
+print(1188);
+print(1189);
+print(1190);
+print(1191);
+print(1192);
+print(1193);
+print(1194);
+print(1195);
+print(1196);
+print(1197);
+print(1198);
+print(1199);
+print(1200);
+print(1201);
+print(1202);
+print(1203);
+print(1204);
+print(1205);
+print(1206);
+print(1207);
+print(1208);
+print(1209);
+print(1210);
+print(1211);
+print(1212);
+print(1213);
+print(1214);
+print(1215);
+print(1216);
+print(1217);
+print(1218);
+print(1219);
+print(1220);
+print(1221);
+print(1222);
+print(1223);
+print(1224);
+print(1225);
+print(1226);
+print(1227);
+print(1228);
+print(1229);
+print(1230);
+print(1231);
+print(1232);
+print(1233);
+print(1234);
+print(1235);
+print(1236);
+print(1237);
+print(1238);
+print(1239);
+print(1240);
+print(1241);
+print(1242);
+print(1243);
+print(1244);
+print(1245);
+print(1246);
+print(1247);
+print(1248);
+print(1249);
+print(1250);
+print(1251);
+print(1252);
+print(1253);
+print(1254);
+print(1255);
+print(1256);
+print(1257);
+print(1258);
+print(1259);
+print(1260);
+print(1261);
+print(1262);
+print(1263);
+print(1264);
+print(1265);
+print(1266);
+print(1267);
+print(1268);
+print(1269);
+print(1270);
+print(1271);
+print(1272);
+print(1273);
+print(1274);
+print(1275);
+print(1276);
+print(1277);
+print(1278);
+print(1279);
+print(1280);
+print(1281);
+print(1282);
+print(1283);
+print(1284);
+print(1285);
+print(1286);
+print(1287);
+print(1288);
+print(1289);
+print(1290);
+print(1291);
+print(1292);
+print(1293);
+print(1294);
+print(1295);
+print(1296);
+print(1297);
+print(1298);
+print(1299);
+print(1300);
+print(1301);
+print(1302);
+print(1303);
+print(1304);
+print(1305);
+print(1306);
+print(1307);
+print(1308);
+print(1309);
+print(1310);
+print(1311);
+print(1312);
+print(1313);
+print(1314);
+print(1315);
+print(1316);
+print(1317);
+print(1318);
+print(1319);
+print(1320);
+print(1321);
+print(1322);
+print(1323);
+print(1324);
+print(1325);
+print(1326);
+print(1327);
+print(1328);
+print(1329);
+print(1330);
+print(1331);
+print(1332);
+print(1333);
+print(1334);
+print(1335);
+print(1336);
+print(1337);
+print(1338);
+print(1339);
+print(1340);
+print(1341);
+print(1342);
+print(1343);
+print(1344);
+print(1345);
+print(1346);
+print(1347);
+print(1348);
+print(1349);
+print(1350);
+print(1351);
+print(1352);
+print(1353);
+print(1354);
+print(1355);
+print(1356);
+print(1357);
+print(1358);
+print(1359);
+print(1360);
+print(1361);
+print(1362);
+print(1363);
+print(1364);
+print(1365);
+print(1366);
+print(1367);
+print(1368);
+print(1369);
+print(1370);
+print(1371);
+print(1372);
+print(1373);
+print(1374);
+print(1375);
+print(1376);
+print(1377);
+print(1378);
+print(1379);
+print(1380);
+print(1381);
+print(1382);
+print(1383);
+print(1384);
+print(1385);
+print(1386);
+print(1387);
+print(1388);
+print(1389);
+print(1390);
+print(1391);
+print(1392);
+print(1393);
+print(1394);
+print(1395);
+print(1396);
+print(1397);
+print(1398);
+print(1399);
+print(1400);
+print(1401);
+print(1402);
+print(1403);
+print(1404);
+print(1405);
+print(1406);
+print(1407);
+print(1408);
+print(1409);
+print(1410);
+print(1411);
+print(1412);
+print(1413);
+print(1414);
+print(1415);
+print(1416);
+print(1417);
+print(1418);
+print(1419);
+print(1420);
+print(1421);
+print(1422);
+print(1423);
+print(1424);
+print(1425);
+print(1426);
+print(1427);
+print(1428);
+print(1429);
+print(1430);
+print(1431);
+print(1432);
+print(1433);
+print(1434);
+print(1435);
+print(1436);
+print(1437);
+print(1438);
+print(1439);
+print(1440);
+print(1441);
+print(1442);
+print(1443);
+print(1444);
+print(1445);
+print(1446);
+print(1447);
+print(1448);
+print(1449);
+print(1450);
+print(1451);
+print(1452);
+print(1453);
+print(1454);
+print(1455);
+print(1456);
+print(1457);
+print(1458);
+print(1459);
+print(1460);
+print(1461);
+print(1462);
+print(1463);
+print(1464);
+print(1465);
+print(1466);
+print(1467);
+print(1468);
+print(1469);
+print(1470);
+print(1471);
+print(1472);
+print(1473);
+print(1474);
+print(1475);
+print(1476);
+print(1477);
+print(1478);
+print(1479);
+print(1480);
+print(1481);
+print(1482);
+print(1483);
+print(1484);
+print(1485);
+print(1486);
+print(1487);
+print(1488);
+print(1489);
+print(1490);
+print(1491);
+print(1492);
+print(1493);
+print(1494);
+print(1495);
+print(1496);
+print(1497);
+print(1498);
+print(1499);
+print(1500);
+print(1501);
+print(1502);
+print(1503);
+print(1504);
+print(1505);
+print(1506);
+print(1507);
+print(1508);
+print(1509);
+print(1510);
+print(1511);
+print(1512);
+print(1513);
+print(1514);
+print(1515);
+print(1516);
+print(1517);
+print(1518);
+print(1519);
+print(1520);
+print(1521);
+print(1522);
+print(1523);
+print(1524);
+print(1525);
+print(1526);
+print(1527);
+print(1528);
+print(1529);
+print(1530);
+print(1531);
+print(1532);
+print(1533);
+print(1534);
+print(1535);
+print(1536);
+print(1537);
+print(1538);
+print(1539);
+print(1540);
+print(1541);
+print(1542);
+print(1543);
+print(1544);
+print(1545);
+print(1546);
+print(1547);
+print(1548);
+print(1549);
+print(1550);
+print(1551);
+print(1552);
+print(1553);
+print(1554);
+print(1555);
+print(1556);
+print(1557);
+print(1558);
+print(1559);
+print(1560);
+print(1561);
+print(1562);
+print(1563);
+print(1564);
+print(1565);
+print(1566);
+print(1567);
+print(1568);
+print(1569);
+print(1570);
+print(1571);
+print(1572);
+print(1573);
+print(1574);
+print(1575);
+print(1576);
+print(1577);
+print(1578);
+print(1579);
+print(1580);
+print(1581);
+print(1582);
+print(1583);
+print(1584);
+print(1585);
+print(1586);
+print(1587);
+print(1588);
+print(1589);
+print(1590);
+print(1591);
+print(1592);
+print(1593);
+print(1594);
+print(1595);
+print(1596);
+print(1597);
+print(1598);
+print(1599);
+print(1600);
+print(1601);
+print(1602);
+print(1603);
+print(1604);
+print(1605);
+print(1606);
+print(1607);
+print(1608);
+print(1609);
+print(1610);
+print(1611);
+print(1612);
+print(1613);
+print(1614);
+print(1615);
+print(1616);
+print(1617);
+print(1618);
+print(1619);
+print(1620);
+print(1621);
+print(1622);
+print(1623);
+print(1624);
+print(1625);
+print(1626);
+print(1627);
+print(1628);
+print(1629);
+print(1630);
+print(1631);
+print(1632);
+print(1633);
+print(1634);
+print(1635);
+print(1636);
+print(1637);
+print(1638);
+print(1639);
+print(1640);
+print(1641);
+print(1642);
+print(1643);
+print(1644);
+print(1645);
+print(1646);
+print(1647);
+print(1648);
+print(1649);
+print(1650);
+print(1651);
+print(1652);
+print(1653);
+print(1654);
+print(1655);
+print(1656);
+print(1657);
+print(1658);
+print(1659);
+print(1660);
+print(1661);
+print(1662);
+print(1663);
+print(1664);
+print(1665);
+print(1666);
+print(1667);
+print(1668);
+print(1669);
+print(1670);
+print(1671);
+print(1672);
+print(1673);
+print(1674);
+print(1675);
+print(1676);
+print(1677);
+print(1678);
+print(1679);
+print(1680);
+print(1681);
+print(1682);
+print(1683);
+print(1684);
+print(1685);
+print(1686);
+print(1687);
+print(1688);
+print(1689);
+print(1690);
+print(1691);
+print(1692);
+print(1693);
+print(1694);
+print(1695);
+print(1696);
+print(1697);
+print(1698);
+print(1699);
+print(1700);
+print(1701);
+print(1702);
+print(1703);
+print(1704);
+print(1705);
+print(1706);
+print(1707);
+print(1708);
+print(1709);
+print(1710);
+print(1711);
+print(1712);
+print(1713);
+print(1714);
+print(1715);
+print(1716);
+print(1717);
+print(1718);
+print(1719);
+print(1720);
+print(1721);
+print(1722);
+print(1723);
+print(1724);
+print(1725);
+print(1726);
+print(1727);
+print(1728);
+print(1729);
+print(1730);
+print(1731);
+print(1732);
+print(1733);
+print(1734);
+print(1735);
+print(1736);
+print(1737);
+print(1738);
+print(1739);
+print(1740);
+print(1741);
+print(1742);
+print(1743);
+print(1744);
+print(1745);
+print(1746);
+print(1747);
+print(1748);
+print(1749);
+print(1750);
+print(1751);
+print(1752);
+print(1753);
+print(1754);
+print(1755);
+print(1756);
+print(1757);
+print(1758);
+print(1759);
+print(1760);
+print(1761);
+print(1762);
+print(1763);
+print(1764);
+print(1765);
+print(1766);
+print(1767);
+print(1768);
+print(1769);
+print(1770);
+print(1771);
+print(1772);
+print(1773);
+print(1774);
+print(1775);
+print(1776);
+print(1777);
+print(1778);
+print(1779);
+print(1780);
+print(1781);
+print(1782);
+print(1783);
+print(1784);
+print(1785);
+print(1786);
+print(1787);
+print(1788);
+print(1789);
+print(1790);
+print(1791);
+print(1792);
+print(1793);
+print(1794);
+print(1795);
+print(1796);
+print(1797);
+print(1798);
+print(1799);
+print(1800);
+print(1801);
+print(1802);
+print(1803);
+print(1804);
+print(1805);
+print(1806);
+print(1807);
+print(1808);
+print(1809);
+print(1810);
+print(1811);
+print(1812);
+print(1813);
+print(1814);
+print(1815);
+print(1816);
+print(1817);
+print(1818);
+print(1819);
+print(1820);
+print(1821);
+print(1822);
+print(1823);
+print(1824);
+print(1825);
+print(1826);
+print(1827);
+print(1828);
+print(1829);
+print(1830);
+print(1831);
+print(1832);
+print(1833);
+print(1834);
+print(1835);
+print(1836);
+print(1837);
+print(1838);
+print(1839);
+print(1840);
+print(1841);
+print(1842);
+print(1843);
+print(1844);
+print(1845);
+print(1846);
+print(1847);
+print(1848);
+print(1849);
+print(1850);
+print(1851);
+print(1852);
+print(1853);
+print(1854);
+print(1855);
+print(1856);
+print(1857);
+print(1858);
+print(1859);
+print(1860);
+print(1861);
+print(1862);
+print(1863);
+print(1864);
+print(1865);
+print(1866);
+print(1867);
+print(1868);
+print(1869);
+print(1870);
+print(1871);
+print(1872);
+print(1873);
+print(1874);
+print(1875);
+print(1876);
+print(1877);
+print(1878);
+print(1879);
+print(1880);
+print(1881);
+print(1882);
+print(1883);
+print(1884);
+print(1885);
+print(1886);
+print(1887);
+print(1888);
+print(1889);
+print(1890);
+print(1891);
+print(1892);
+print(1893);
+print(1894);
+print(1895);
+print(1896);
+print(1897);
+print(1898);
+print(1899);
+print(1900);
+print(1901);
+print(1902);
+print(1903);
+print(1904);
+print(1905);
+print(1906);
+print(1907);
+print(1908);
+print(1909);
+print(1910);
+print(1911);
+print(1912);
+print(1913);
+print(1914);
+print(1915);
+print(1916);
+print(1917);
+print(1918);
+print(1919);
+print(1920);
+print(1921);
+print(1922);
+print(1923);
+print(1924);
+print(1925);
+print(1926);
+print(1927);
+print(1928);
+print(1929);
+print(1930);
+print(1931);
+print(1932);
+print(1933);
+print(1934);
+print(1935);
+print(1936);
+print(1937);
+print(1938);
+print(1939);
+print(1940);
+print(1941);
+print(1942);
+print(1943);
+print(1944);
+print(1945);
+print(1946);
+print(1947);
+print(1948);
+print(1949);
+print(1950);
+print(1951);
+print(1952);
+print(1953);
+print(1954);
+print(1955);
+print(1956);
+print(1957);
+print(1958);
+print(1959);
+print(1960);
+print(1961);
+print(1962);
+print(1963);
+print(1964);
+print(1965);
+print(1966);
+print(1967);
+print(1968);
+print(1969);
+print(1970);
+print(1971);
+print(1972);
+print(1973);
+print(1974);
+print(1975);
+print(1976);
+print(1977);
+print(1978);
+print(1979);
+print(1980);
+print(1981);
+print(1982);
+print(1983);
+print(1984);
+print(1985);
+print(1986);
+print(1987);
+print(1988);
+print(1989);
+print(1990);
+print(1991);
+print(1992);
+print(1993);
+print(1994);
+print(1995);
+print(1996);
+print(1997);
+print(1998);
+print(1999);
+print(2000);
+print(2001);
+print(2002);
+print(2003);
+print(2004);
+print(2005);
+print(2006);
+print(2007);
+print(2008);
+print(2009);
+print(2010);
+print(2011);
+print(2012);
+print(2013);
+print(2014);
+print(2015);
+print(2016);
+print(2017);
+print(2018);
+print(2019);
+print(2020);
+print(2021);
+print(2022);
+print(2023);
+print(2024);
+print(2025);
+print(2026);
+print(2027);
+print(2028);
+print(2029);
+print(2030);
+print(2031);
+print(2032);
+print(2033);
+print(2034);
+print(2035);
+print(2036);
+print(2037);
+print(2038);
+print(2039);
+print(2040);
+print(2041);
+print(2042);
+print(2043);
+print(2044);
+print(2045);
+print(2046);
+print(2047);
+print(2048);
+print(2049);
+print(2050);
+print(2051);
+print(2052);
+print(2053);
+print(2054);
+print(2055);
+print(2056);
+print(2057);
+print(2058);
+print(2059);
+print(2060);
+print(2061);
+print(2062);
+print(2063);
+print(2064);
+print(2065);
+print(2066);
+print(2067);
+print(2068);
+print(2069);
+print(2070);
+print(2071);
+print(2072);
+print(2073);
+print(2074);
+print(2075);
+print(2076);
+print(2077);
+print(2078);
+print(2079);
+print(2080);
+print(2081);
+print(2082);
+print(2083);
+print(2084);
+print(2085);
+print(2086);
+print(2087);
+print(2088);
+print(2089);
+print(2090);
+print(2091);
+print(2092);
+print(2093);
+print(2094);
+print(2095);
+print(2096);
+print(2097);
+print(2098);
+print(2099);
+print(2100);
+print(2101);
+print(2102);
+print(2103);
+print(2104);
+print(2105);
+print(2106);
+print(2107);
+print(2108);
+print(2109);
+print(2110);
+print(2111);
+print(2112);
+print(2113);
+print(2114);
+print(2115);
+print(2116);
+print(2117);
+print(2118);
+print(2119);
+print(2120);
+print(2121);
+print(2122);
+print(2123);
+print(2124);
+print(2125);
+print(2126);
+print(2127);
+print(2128);
+print(2129);
+print(2130);
+print(2131);
+print(2132);
+print(2133);
+print(2134);
+print(2135);
+print(2136);
+print(2137);
+print(2138);
+print(2139);
+print(2140);
+print(2141);
+print(2142);
+print(2143);
+print(2144);
+print(2145);
+print(2146);
+print(2147);
+print(2148);
+print(2149);
+print(2150);
+print(2151);
+print(2152);
+print(2153);
+print(2154);
+print(2155);
+print(2156);
+print(2157);
+print(2158);
+print(2159);
+print(2160);
+print(2161);
+print(2162);
+print(2163);
+print(2164);
+print(2165);
+print(2166);
+print(2167);
+print(2168);
+print(2169);
+print(2170);
+print(2171);
+print(2172);
+print(2173);
+print(2174);
+print(2175);
+print(2176);
+print(2177);
+print(2178);
+print(2179);
+print(2180);
+print(2181);
+print(2182);
+print(2183);
+print(2184);
+print(2185);
+print(2186);
+print(2187);
+print(2188);
+print(2189);
+print(2190);
+print(2191);
+print(2192);
+print(2193);
+print(2194);
+print(2195);
+print(2196);
+print(2197);
+print(2198);
+print(2199);
+print(2200);
+print(2201);
+print(2202);
+print(2203);
+print(2204);
+print(2205);
+print(2206);
+print(2207);
+print(2208);
+print(2209);
+print(2210);
+print(2211);
+print(2212);
+print(2213);
+print(2214);
+print(2215);
+print(2216);
+print(2217);
+print(2218);
+print(2219);
+print(2220);
+print(2221);
+print(2222);
+print(2223);
+print(2224);
+print(2225);
+print(2226);
+print(2227);
+print(2228);
+print(2229);
+print(2230);
+print(2231);
+print(2232);
+print(2233);
+print(2234);
+print(2235);
+print(2236);
+print(2237);
+print(2238);
+print(2239);
+print(2240);
+print(2241);
+print(2242);
+print(2243);
+print(2244);
+print(2245);
+print(2246);
+print(2247);
+print(2248);
+print(2249);
+print(2250);
+print(2251);
+print(2252);
+print(2253);
+print(2254);
+print(2255);
+print(2256);
+print(2257);
+print(2258);
+print(2259);
+print(2260);
+print(2261);
+print(2262);
+print(2263);
+print(2264);
+print(2265);
+print(2266);
+print(2267);
+print(2268);
+print(2269);
+print(2270);
+print(2271);
+print(2272);
+print(2273);
+print(2274);
+print(2275);
+print(2276);
+print(2277);
+print(2278);
+print(2279);
+print(2280);
+print(2281);
+print(2282);
+print(2283);
+print(2284);
+print(2285);
+print(2286);
+print(2287);
+print(2288);
+print(2289);
+print(2290);
+print(2291);
+print(2292);
+print(2293);
+print(2294);
+print(2295);
+print(2296);
+print(2297);
+print(2298);
+print(2299);
+print(2300);
+print(2301);
+print(2302);
+print(2303);
+print(2304);
+print(2305);
+print(2306);
+print(2307);
+print(2308);
+print(2309);
+print(2310);
+print(2311);
+print(2312);
+print(2313);
+print(2314);
+print(2315);
+print(2316);
+print(2317);
+print(2318);
+print(2319);
+print(2320);
+print(2321);
+print(2322);
+print(2323);
+print(2324);
+print(2325);
+print(2326);
+print(2327);
+print(2328);
+print(2329);
+print(2330);
+print(2331);
+print(2332);
+print(2333);
+print(2334);
+print(2335);
+print(2336);
+print(2337);
+print(2338);
+print(2339);
+print(2340);
+print(2341);
+print(2342);
+print(2343);
+print(2344);
+print(2345);
+print(2346);
+print(2347);
+print(2348);
+print(2349);
+print(2350);
+print(2351);
+print(2352);
+print(2353);
+print(2354);
+print(2355);
+print(2356);
+print(2357);
+print(2358);
+print(2359);
+print(2360);
+print(2361);
+print(2362);
+print(2363);
+print(2364);
+print(2365);
+print(2366);
+print(2367);
+print(2368);
+print(2369);
+print(2370);
+print(2371);
+print(2372);
+print(2373);
+print(2374);
+print(2375);
+print(2376);
+print(2377);
+print(2378);
+print(2379);
+print(2380);
+print(2381);
+print(2382);
+print(2383);
+print(2384);
+print(2385);
+print(2386);
+print(2387);
+print(2388);
+print(2389);
+print(2390);
+print(2391);
+print(2392);
+print(2393);
+print(2394);
+print(2395);
+print(2396);
+print(2397);
+print(2398);
+print(2399);
+print(2400);
+print(2401);
+print(2402);
+print(2403);
+print(2404);
+print(2405);
+print(2406);
+print(2407);
+print(2408);
+print(2409);
+print(2410);
+print(2411);
+print(2412);
+print(2413);
+print(2414);
+print(2415);
+print(2416);
+print(2417);
+print(2418);
+print(2419);
+print(2420);
+print(2421);
+print(2422);
+print(2423);
+print(2424);
+print(2425);
+print(2426);
+print(2427);
+print(2428);
+print(2429);
+print(2430);
+print(2431);
+print(2432);
+print(2433);
+print(2434);
+print(2435);
+print(2436);
+print(2437);
+print(2438);
+print(2439);
+print(2440);
+print(2441);
+print(2442);
+print(2443);
+print(2444);
+print(2445);
+print(2446);
+print(2447);
+print(2448);
+print(2449);
+print(2450);
+print(2451);
+print(2452);
+print(2453);
+print(2454);
+print(2455);
+print(2456);
+print(2457);
+print(2458);
+print(2459);
+print(2460);
+print(2461);
+print(2462);
+print(2463);
+print(2464);
+print(2465);
+print(2466);
+print(2467);
+print(2468);
+print(2469);
+print(2470);
+print(2471);
+print(2472);
+print(2473);
+print(2474);
+print(2475);
+print(2476);
+print(2477);
+print(2478);
+print(2479);
+print(2480);
+print(2481);
+print(2482);
+print(2483);
+print(2484);
+print(2485);
+print(2486);
+print(2487);
+print(2488);
+print(2489);
+print(2490);
+print(2491);
+print(2492);
+print(2493);
+print(2494);
+print(2495);
+print(2496);
+print(2497);
+print(2498);
+print(2499);
+print(2500);
+print(2501);
+print(2502);
+print(2503);
+print(2504);
+print(2505);
+print(2506);
+print(2507);
+print(2508);
+print(2509);
+print(2510);
+print(2511);
+print(2512);
+print(2513);
+print(2514);
+print(2515);
+print(2516);
+print(2517);
+print(2518);
+print(2519);
+print(2520);
+print(2521);
+print(2522);
+print(2523);
+print(2524);
+print(2525);
+print(2526);
+print(2527);
+print(2528);
+print(2529);
+print(2530);
+print(2531);
+print(2532);
+print(2533);
+print(2534);
+print(2535);
+print(2536);
+print(2537);
+print(2538);
+print(2539);
+print(2540);
+print(2541);
+print(2542);
+print(2543);
+print(2544);
+print(2545);
+print(2546);
+print(2547);
+print(2548);
+print(2549);
+print(2550);
+print(2551);
+print(2552);
+print(2553);
+print(2554);
+print(2555);
+print(2556);
+print(2557);
+print(2558);
+print(2559);
+print(2560);
+print(2561);
+print(2562);
+print(2563);
+print(2564);
+print(2565);
+print(2566);
+print(2567);
+print(2568);
+print(2569);
+print(2570);
+print(2571);
+print(2572);
+print(2573);
+print(2574);
+print(2575);
+print(2576);
+print(2577);
+print(2578);
+print(2579);
+print(2580);
+print(2581);
+print(2582);
+print(2583);
+print(2584);
+print(2585);
+print(2586);
+print(2587);
+print(2588);
+print(2589);
+print(2590);
+print(2591);
+print(2592);
+print(2593);
+print(2594);
+print(2595);
+print(2596);
+print(2597);
+print(2598);
+print(2599);
+print(2600);
+print(2601);
+print(2602);
+print(2603);
+print(2604);
+print(2605);
+print(2606);
+print(2607);
+print(2608);
+print(2609);
+print(2610);
+print(2611);
+print(2612);
+print(2613);
+print(2614);
+print(2615);
+print(2616);
+print(2617);
+print(2618);
+print(2619);
+print(2620);
+print(2621);
+print(2622);
+print(2623);
+print(2624);
+print(2625);
+print(2626);
+print(2627);
+print(2628);
+print(2629);
+print(2630);
+print(2631);
+print(2632);
+print(2633);
+print(2634);
+print(2635);
+print(2636);
+print(2637);
+print(2638);
+print(2639);
+print(2640);
+print(2641);
+print(2642);
+print(2643);
+print(2644);
+print(2645);
+print(2646);
+print(2647);
+print(2648);
+print(2649);
+print(2650);
+print(2651);
+print(2652);
+print(2653);
+print(2654);
+print(2655);
+print(2656);
+print(2657);
+print(2658);
+print(2659);
+print(2660);
+print(2661);
+print(2662);
+print(2663);
+print(2664);
+print(2665);
+print(2666);
+print(2667);
+print(2668);
+print(2669);
+print(2670);
+print(2671);
+print(2672);
+print(2673);
+print(2674);
+print(2675);
+print(2676);
+print(2677);
+print(2678);
+print(2679);
+print(2680);
+print(2681);
+print(2682);
+print(2683);
+print(2684);
+print(2685);
+print(2686);
+print(2687);
+print(2688);
+print(2689);
+print(2690);
+print(2691);
+print(2692);
+print(2693);
+print(2694);
+print(2695);
+print(2696);
+print(2697);
+print(2698);
+print(2699);
+print(2700);
+print(2701);
+print(2702);
+print(2703);
+print(2704);
+print(2705);
+print(2706);
+print(2707);
+print(2708);
+print(2709);
+print(2710);
+print(2711);
+print(2712);
+print(2713);
+print(2714);
+print(2715);
+print(2716);
+print(2717);
+print(2718);
+print(2719);
+print(2720);
+print(2721);
+print(2722);
+print(2723);
+print(2724);
+print(2725);
+print(2726);
+print(2727);
+print(2728);
+print(2729);
+print(2730);
+print(2731);
+print(2732);
+print(2733);
+print(2734);
+print(2735);
+print(2736);
+print(2737);
+print(2738);
+print(2739);
+print(2740);
+print(2741);
+print(2742);
+print(2743);
+print(2744);
+print(2745);
+print(2746);
+print(2747);
+print(2748);
+print(2749);
+print(2750);
+print(2751);
+print(2752);
+print(2753);
+print(2754);
+print(2755);
+print(2756);
+print(2757);
+print(2758);
+print(2759);
+print(2760);
+print(2761);
+print(2762);
+print(2763);
+print(2764);
+print(2765);
+print(2766);
+print(2767);
+print(2768);
+print(2769);
+print(2770);
+print(2771);
+print(2772);
+print(2773);
+print(2774);
+print(2775);
+print(2776);
+print(2777);
+print(2778);
+print(2779);
+print(2780);
+print(2781);
+print(2782);
+print(2783);
+print(2784);
+print(2785);
+print(2786);
+print(2787);
+print(2788);
+print(2789);
+print(2790);
+print(2791);
+print(2792);
+print(2793);
+print(2794);
+print(2795);
+print(2796);
+print(2797);
+print(2798);
+print(2799);
+print(2800);
+print(2801);
+print(2802);
+print(2803);
+print(2804);
+print(2805);
+print(2806);
+print(2807);
+print(2808);
+print(2809);
+print(2810);
+print(2811);
+print(2812);
+print(2813);
+print(2814);
+print(2815);
+print(2816);
+print(2817);
+print(2818);
+print(2819);
+print(2820);
+print(2821);
+print(2822);
+print(2823);
+print(2824);
+print(2825);
+print(2826);
+print(2827);
+print(2828);
+print(2829);
+print(2830);
+print(2831);
+print(2832);
+print(2833);
+print(2834);
+print(2835);
+print(2836);
+print(2837);
+print(2838);
+print(2839);
+print(2840);
+print(2841);
+print(2842);
+print(2843);
+print(2844);
+print(2845);
+print(2846);
+print(2847);
+print(2848);
+print(2849);
+print(2850);
+print(2851);
+print(2852);
+print(2853);
+print(2854);
+print(2855);
+print(2856);
+print(2857);
+print(2858);
+print(2859);
+print(2860);
+print(2861);
+print(2862);
+print(2863);
+print(2864);
+print(2865);
+print(2866);
+print(2867);
+print(2868);
+print(2869);
+print(2870);
+print(2871);
+print(2872);
+print(2873);
+print(2874);
+print(2875);
+print(2876);
+print(2877);
+print(2878);
+print(2879);
+print(2880);
+print(2881);
+print(2882);
+print(2883);
+print(2884);
+print(2885);
+print(2886);
+print(2887);
+print(2888);
+print(2889);
+print(2890);
+print(2891);
+print(2892);
+print(2893);
+print(2894);
+print(2895);
+print(2896);
+print(2897);
+print(2898);
+print(2899);
+print(2900);
+print(2901);
+print(2902);
+print(2903);
+print(2904);
+print(2905);
+print(2906);
+print(2907);
+print(2908);
+print(2909);
+print(2910);
+print(2911);
+print(2912);
+print(2913);
+print(2914);
+print(2915);
+print(2916);
+print(2917);
+print(2918);
+print(2919);
+print(2920);
+print(2921);
+print(2922);
+print(2923);
+print(2924);
+print(2925);
+print(2926);
+print(2927);
+print(2928);
+print(2929);
+print(2930);
+print(2931);
+print(2932);
+print(2933);
+print(2934);
+print(2935);
+print(2936);
+print(2937);
+print(2938);
+print(2939);
+print(2940);
+print(2941);
+print(2942);
+print(2943);
+print(2944);
+print(2945);
+print(2946);
+print(2947);
+print(2948);
+print(2949);
+print(2950);
+print(2951);
+print(2952);
+print(2953);
+print(2954);
+print(2955);
+print(2956);
+print(2957);
+print(2958);
+print(2959);
+print(2960);
+print(2961);
+print(2962);
+print(2963);
+print(2964);
+print(2965);
+print(2966);
+print(2967);
+print(2968);
+print(2969);
+print(2970);
+print(2971);
+print(2972);
+print(2973);
+print(2974);
+print(2975);
+print(2976);
+print(2977);
+print(2978);
+print(2979);
+print(2980);
+print(2981);
+print(2982);
+print(2983);
+print(2984);
+print(2985);
+print(2986);
+print(2987);
+print(2988);
+print(2989);
+print(2990);
+print(2991);
+print(2992);
+print(2993);
+print(2994);
+print(2995);
+print(2996);
+print(2997);
+print(2998);
+print(2999);
+print(3000);
+print(3001);
+print(3002);
+print(3003);
+print(3004);
+print(3005);
+print(3006);
+print(3007);
+print(3008);
+print(3009);
+print(3010);
+print(3011);
+print(3012);
+print(3013);
+print(3014);
+print(3015);
+print(3016);
+print(3017);
+print(3018);
+print(3019);
+print(3020);
+print(3021);
+print(3022);
+print(3023);
+print(3024);
+print(3025);
+print(3026);
+print(3027);
+print(3028);
+print(3029);
+print(3030);
+print(3031);
+print(3032);
+print(3033);
+print(3034);
+print(3035);
+print(3036);
+print(3037);
+print(3038);
+print(3039);
+print(3040);
+print(3041);
+print(3042);
+print(3043);
+print(3044);
+print(3045);
+print(3046);
+print(3047);
+print(3048);
+print(3049);
+print(3050);
+print(3051);
+print(3052);
+print(3053);
+print(3054);
+print(3055);
+print(3056);
+print(3057);
+print(3058);
+print(3059);
+print(3060);
+print(3061);
+print(3062);
+print(3063);
+print(3064);
+print(3065);
+print(3066);
+print(3067);
+print(3068);
+print(3069);
+print(3070);
+print(3071);
+print(3072);
+print(3073);
+print(3074);
+print(3075);
+print(3076);
+print(3077);
+print(3078);
+print(3079);
+print(3080);
+print(3081);
+print(3082);
+print(3083);
+print(3084);
+print(3085);
+print(3086);
+print(3087);
+print(3088);
+print(3089);
+print(3090);
+print(3091);
+print(3092);
+print(3093);
+print(3094);
+print(3095);
+print(3096);
+print(3097);
+print(3098);
+print(3099);
+print(3100);
+print(3101);
+print(3102);
+print(3103);
+print(3104);
+print(3105);
+print(3106);
+print(3107);
+print(3108);
+print(3109);
+print(3110);
+print(3111);
+print(3112);
+print(3113);
+print(3114);
+print(3115);
+print(3116);
+print(3117);
+print(3118);
+print(3119);
+print(3120);
+print(3121);
+print(3122);
+print(3123);
+print(3124);
+print(3125);
+print(3126);
+print(3127);
+print(3128);
+print(3129);
+print(3130);
+print(3131);
+print(3132);
+print(3133);
+print(3134);
+print(3135);
+print(3136);
+print(3137);
+print(3138);
+print(3139);
+print(3140);
+print(3141);
+print(3142);
+print(3143);
+print(3144);
+print(3145);
+print(3146);
+print(3147);
+print(3148);
+print(3149);
+print(3150);
+print(3151);
+print(3152);
+print(3153);
+print(3154);
+print(3155);
+print(3156);
+print(3157);
+print(3158);
+print(3159);
+print(3160);
+print(3161);
+print(3162);
+print(3163);
+print(3164);
+print(3165);
+print(3166);
+print(3167);
+print(3168);
+print(3169);
+print(3170);
+print(3171);
+print(3172);
+print(3173);
+print(3174);
+print(3175);
+print(3176);
+print(3177);
+print(3178);
+print(3179);
+print(3180);
+print(3181);
+print(3182);
+print(3183);
+print(3184);
+print(3185);
+print(3186);
+print(3187);
+print(3188);
+print(3189);
+print(3190);
+print(3191);
+print(3192);
+print(3193);
+print(3194);
+print(3195);
+print(3196);
+print(3197);
+print(3198);
+print(3199);
+print(3200);
+print(3201);
+print(3202);
+print(3203);
+print(3204);
+print(3205);
+print(3206);
+print(3207);
+print(3208);
+print(3209);
+print(3210);
+print(3211);
+print(3212);
+print(3213);
+print(3214);
+print(3215);
+print(3216);
+print(3217);
+print(3218);
+print(3219);
+print(3220);
+print(3221);
+print(3222);
+print(3223);
+print(3224);
+print(3225);
+print(3226);
+print(3227);
+print(3228);
+print(3229);
+print(3230);
+print(3231);
+print(3232);
+print(3233);
+print(3234);
+print(3235);
+print(3236);
+print(3237);
+print(3238);
+print(3239);
+print(3240);
+print(3241);
+print(3242);
+print(3243);
+print(3244);
+print(3245);
+print(3246);
+print(3247);
+print(3248);
+print(3249);
+print(3250);
+print(3251);
+print(3252);
+print(3253);
+print(3254);
+print(3255);
+print(3256);
+print(3257);
+print(3258);
+print(3259);
+print(3260);
+print(3261);
+print(3262);
+print(3263);
+print(3264);
+print(3265);
+print(3266);
+print(3267);
+print(3268);
+print(3269);
+print(3270);
+print(3271);
+print(3272);
+print(3273);
+print(3274);
+print(3275);
+print(3276);
+print(3277);
+print(3278);
+print(3279);
+print(3280);
+print(3281);
+print(3282);
+print(3283);
+print(3284);
+print(3285);
+print(3286);
+print(3287);
+print(3288);
+print(3289);
+print(3290);
+print(3291);
+print(3292);
+print(3293);
+print(3294);
+print(3295);
+print(3296);
+print(3297);
+print(3298);
+print(3299);
+print(3300);
+print(3301);
+print(3302);
+print(3303);
+print(3304);
+print(3305);
+print(3306);
+print(3307);
+print(3308);
+print(3309);
+print(3310);
+print(3311);
+print(3312);
+print(3313);
+print(3314);
+print(3315);
+print(3316);
+print(3317);
+print(3318);
+print(3319);
+print(3320);
+print(3321);
+print(3322);
+print(3323);
+print(3324);
+print(3325);
+print(3326);
+print(3327);
+print(3328);
+print(3329);
+print(3330);
+print(3331);
+print(3332);
+print(3333);
+print(3334);
+print(3335);
+print(3336);
+print(3337);
+print(3338);
+print(3339);
+print(3340);
+print(3341);
+print(3342);
+print(3343);
+print(3344);
+print(3345);
+print(3346);
+print(3347);
+print(3348);
+print(3349);
+print(3350);
+print(3351);
+print(3352);
+print(3353);
+print(3354);
+print(3355);
+print(3356);
+print(3357);
+print(3358);
+print(3359);
+print(3360);
+print(3361);
+print(3362);
+print(3363);
+print(3364);
+print(3365);
+print(3366);
+print(3367);
+print(3368);
+print(3369);
+print(3370);
+print(3371);
+print(3372);
+print(3373);
+print(3374);
+print(3375);
+print(3376);
+print(3377);
+print(3378);
+print(3379);
+print(3380);
+print(3381);
+print(3382);
+print(3383);
+print(3384);
+print(3385);
+print(3386);
+print(3387);
+print(3388);
+print(3389);
+print(3390);
+print(3391);
+print(3392);
+print(3393);
+print(3394);
+print(3395);
+print(3396);
+print(3397);
+print(3398);
+print(3399);
+print(3400);
+print(3401);
+print(3402);
+print(3403);
+print(3404);
+print(3405);
+print(3406);
+print(3407);
+print(3408);
+print(3409);
+print(3410);
+print(3411);
+print(3412);
+print(3413);
+print(3414);
+print(3415);
+print(3416);
+print(3417);
+print(3418);
+print(3419);
+print(3420);
+print(3421);
+print(3422);
+print(3423);
+print(3424);
+print(3425);
+print(3426);
+print(3427);
+print(3428);
+print(3429);
+print(3430);
+print(3431);
+print(3432);
+print(3433);
+print(3434);
+print(3435);
+print(3436);
+print(3437);
+print(3438);
+print(3439);
+print(3440);
+print(3441);
+print(3442);
+print(3443);
+print(3444);
+print(3445);
+print(3446);
+print(3447);
+print(3448);
+print(3449);
+print(3450);
+print(3451);
+print(3452);
+print(3453);
+print(3454);
+print(3455);
+print(3456);
+print(3457);
+print(3458);
+print(3459);
+print(3460);
+print(3461);
+print(3462);
+print(3463);
+print(3464);
+print(3465);
+print(3466);
+print(3467);
+print(3468);
+print(3469);
+print(3470);
+print(3471);
+print(3472);
+print(3473);
+print(3474);
+print(3475);
+print(3476);
+print(3477);
+print(3478);
+print(3479);
+print(3480);
+print(3481);
+print(3482);
+print(3483);
+print(3484);
+print(3485);
+print(3486);
+print(3487);
+print(3488);
+print(3489);
+print(3490);
+print(3491);
+print(3492);
+print(3493);
+print(3494);
+print(3495);
+print(3496);
+print(3497);
+print(3498);
+print(3499);
+print(3500);
+print(3501);
+print(3502);
+print(3503);
+print(3504);
+print(3505);
+print(3506);
+print(3507);
+print(3508);
+print(3509);
+print(3510);
+print(3511);
+print(3512);
+print(3513);
+print(3514);
+print(3515);
+print(3516);
+print(3517);
+print(3518);
+print(3519);
+print(3520);
+print(3521);
+print(3522);
+print(3523);
+print(3524);
+print(3525);
+print(3526);
+print(3527);
+print(3528);
+print(3529);
+print(3530);
+print(3531);
+print(3532);
+print(3533);
+print(3534);
+print(3535);
+print(3536);
+print(3537);
+print(3538);
+print(3539);
+print(3540);
+print(3541);
+print(3542);
+print(3543);
+print(3544);
+print(3545);
+print(3546);
+print(3547);
+print(3548);
+print(3549);
+print(3550);
+print(3551);
+print(3552);
+print(3553);
+print(3554);
+print(3555);
+print(3556);
+print(3557);
+print(3558);
+print(3559);
+print(3560);
+print(3561);
+print(3562);
+print(3563);
+print(3564);
+print(3565);
+print(3566);
+print(3567);
+print(3568);
+print(3569);
+print(3570);
+print(3571);
+print(3572);
+print(3573);
+print(3574);
+print(3575);
+print(3576);
+print(3577);
+print(3578);
+print(3579);
+print(3580);
+print(3581);
+print(3582);
+print(3583);
+print(3584);
+print(3585);
+print(3586);
+print(3587);
+print(3588);
+print(3589);
+print(3590);
+print(3591);
+print(3592);
+print(3593);
+print(3594);
+print(3595);
+print(3596);
+print(3597);
+print(3598);
+print(3599);
+print(3600);
+print(3601);
+print(3602);
+print(3603);
+print(3604);
+print(3605);
+print(3606);
+print(3607);
+print(3608);
+print(3609);
+print(3610);
+print(3611);
+print(3612);
+print(3613);
+print(3614);
+print(3615);
+print(3616);
+print(3617);
+print(3618);
+print(3619);
+print(3620);
+print(3621);
+print(3622);
+print(3623);
+print(3624);
+print(3625);
+print(3626);
+print(3627);
+print(3628);
+print(3629);
+print(3630);
+print(3631);
+print(3632);
+print(3633);
+print(3634);
+print(3635);
+print(3636);
+print(3637);
+print(3638);
+print(3639);
+print(3640);
+print(3641);
+print(3642);
+print(3643);
+print(3644);
+print(3645);
+print(3646);
+print(3647);
+print(3648);
+print(3649);
+print(3650);
+print(3651);
+print(3652);
+print(3653);
+print(3654);
+print(3655);
+print(3656);
+print(3657);
+print(3658);
+print(3659);
+print(3660);
+print(3661);
+print(3662);
+print(3663);
+print(3664);
+print(3665);
+print(3666);
+print(3667);
+print(3668);
+print(3669);
+print(3670);
+print(3671);
+print(3672);
+print(3673);
+print(3674);
+print(3675);
+print(3676);
+print(3677);
+print(3678);
+print(3679);
+print(3680);
+print(3681);
+print(3682);
+print(3683);
+print(3684);
+print(3685);
+print(3686);
+print(3687);
+print(3688);
+print(3689);
+print(3690);
+print(3691);
+print(3692);
+print(3693);
+print(3694);
+print(3695);
+print(3696);
+print(3697);
+print(3698);
+print(3699);
+print(3700);
+print(3701);
+print(3702);
+print(3703);
+print(3704);
+print(3705);
+print(3706);
+print(3707);
+print(3708);
+print(3709);
+print(3710);
+print(3711);
+print(3712);
+print(3713);
+print(3714);
+print(3715);
+print(3716);
+print(3717);
+print(3718);
+print(3719);
+print(3720);
+print(3721);
+print(3722);
+print(3723);
+print(3724);
+print(3725);
+print(3726);
+print(3727);
+print(3728);
+print(3729);
+print(3730);
+print(3731);
+print(3732);
+print(3733);
+print(3734);
+print(3735);
+print(3736);
+print(3737);
+print(3738);
+print(3739);
+print(3740);
+print(3741);
+print(3742);
+print(3743);
+print(3744);
+print(3745);
+print(3746);
+print(3747);
+print(3748);
+print(3749);
+print(3750);
+print(3751);
+print(3752);
+print(3753);
+print(3754);
+print(3755);
+print(3756);
+print(3757);
+print(3758);
+print(3759);
+print(3760);
+print(3761);
+print(3762);
+print(3763);
+print(3764);
+print(3765);
+print(3766);
+print(3767);
+print(3768);
+print(3769);
+print(3770);
+print(3771);
+print(3772);
+print(3773);
+print(3774);
+print(3775);
+print(3776);
+print(3777);
+print(3778);
+print(3779);
+print(3780);
+print(3781);
+print(3782);
+print(3783);
+print(3784);
+print(3785);
+print(3786);
+print(3787);
+print(3788);
+print(3789);
+print(3790);
+print(3791);
+print(3792);
+print(3793);
+print(3794);
+print(3795);
+print(3796);
+print(3797);
+print(3798);
+print(3799);
+print(3800);
+print(3801);
+print(3802);
+print(3803);
+print(3804);
+print(3805);
+print(3806);
+print(3807);
+print(3808);
+print(3809);
+print(3810);
+print(3811);
+print(3812);
+print(3813);
+print(3814);
+print(3815);
+print(3816);
+print(3817);
+print(3818);
+print(3819);
+print(3820);
+print(3821);
+print(3822);
+print(3823);
+print(3824);
+print(3825);
+print(3826);
+print(3827);
+print(3828);
+print(3829);
+print(3830);
+print(3831);
+print(3832);
+print(3833);
+print(3834);
+print(3835);
+print(3836);
+print(3837);
+print(3838);
+print(3839);
+print(3840);
+print(3841);
+print(3842);
+print(3843);
+print(3844);
+print(3845);
+print(3846);
+print(3847);
+print(3848);
+print(3849);
+print(3850);
+print(3851);
+print(3852);
+print(3853);
+print(3854);
+print(3855);
+print(3856);
+print(3857);
+print(3858);
+print(3859);
+print(3860);
+print(3861);
+print(3862);
+print(3863);
+print(3864);
+print(3865);
+print(3866);
+print(3867);
+print(3868);
+print(3869);
+print(3870);
+print(3871);
+print(3872);
+print(3873);
+print(3874);
+print(3875);
+print(3876);
+print(3877);
+print(3878);
+print(3879);
+print(3880);
+print(3881);
+print(3882);
+print(3883);
+print(3884);
+print(3885);
+print(3886);
+print(3887);
+print(3888);
+print(3889);
+print(3890);
+print(3891);
+print(3892);
+print(3893);
+print(3894);
+print(3895);
+print(3896);
+print(3897);
+print(3898);
+print(3899);
+print(3900);
+print(3901);
+print(3902);
+print(3903);
+print(3904);
+print(3905);
+print(3906);
+print(3907);
+print(3908);
+print(3909);
+print(3910);
+print(3911);
+print(3912);
+print(3913);
+print(3914);
+print(3915);
+print(3916);
+print(3917);
+print(3918);
+print(3919);
+print(3920);
+print(3921);
+print(3922);
+print(3923);
+print(3924);
+print(3925);
+print(3926);
+print(3927);
+print(3928);
+print(3929);
+print(3930);
+print(3931);
+print(3932);
+print(3933);
+print(3934);
+print(3935);
+print(3936);
+print(3937);
+print(3938);
+print(3939);
+print(3940);
+print(3941);
+print(3942);
+print(3943);
+print(3944);
+print(3945);
+print(3946);
+print(3947);
+print(3948);
+print(3949);
+print(3950);
+print(3951);
+print(3952);
+print(3953);
+print(3954);
+print(3955);
+print(3956);
+print(3957);
+print(3958);
+print(3959);
+print(3960);
+print(3961);
+print(3962);
+print(3963);
+print(3964);
+print(3965);
+print(3966);
+print(3967);
+print(3968);
+print(3969);
+print(3970);
+print(3971);
+print(3972);
+print(3973);
+print(3974);
+print(3975);
+print(3976);
+print(3977);
+print(3978);
+print(3979);
+print(3980);
+print(3981);
+print(3982);
+print(3983);
+print(3984);
+print(3985);
+print(3986);
+print(3987);
+print(3988);
+print(3989);
+print(3990);
+print(3991);
+print(3992);
+print(3993);
+print(3994);
+print(3995);
+print(3996);
+print(3997);
+print(3998);
+print(3999);
diff --git a/nashorn/test/script/basic/NASHORN-423.js.EXPECTED b/nashorn/test/script/basic/NASHORN-423.js.EXPECTED
new file mode 100644
index 0000000..fb53d53
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-423.js.EXPECTED
@@ -0,0 +1,4000 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
+2539
+2540
+2541
+2542
+2543
+2544
+2545
+2546
+2547
+2548
+2549
+2550
+2551
+2552
+2553
+2554
+2555
+2556
+2557
+2558
+2559
+2560
+2561
+2562
+2563
+2564
+2565
+2566
+2567
+2568
+2569
+2570
+2571
+2572
+2573
+2574
+2575
+2576
+2577
+2578
+2579
+2580
+2581
+2582
+2583
+2584
+2585
+2586
+2587
+2588
+2589
+2590
+2591
+2592
+2593
+2594
+2595
+2596
+2597
+2598
+2599
+2600
+2601
+2602
+2603
+2604
+2605
+2606
+2607
+2608
+2609
+2610
+2611
+2612
+2613
+2614
+2615
+2616
+2617
+2618
+2619
+2620
+2621
+2622
+2623
+2624
+2625
+2626
+2627
+2628
+2629
+2630
+2631
+2632
+2633
+2634
+2635
+2636
+2637
+2638
+2639
+2640
+2641
+2642
+2643
+2644
+2645
+2646
+2647
+2648
+2649
+2650
+2651
+2652
+2653
+2654
+2655
+2656
+2657
+2658
+2659
+2660
+2661
+2662
+2663
+2664
+2665
+2666
+2667
+2668
+2669
+2670
+2671
+2672
+2673
+2674
+2675
+2676
+2677
+2678
+2679
+2680
+2681
+2682
+2683
+2684
+2685
+2686
+2687
+2688
+2689
+2690
+2691
+2692
+2693
+2694
+2695
+2696
+2697
+2698
+2699
+2700
+2701
+2702
+2703
+2704
+2705
+2706
+2707
+2708
+2709
+2710
+2711
+2712
+2713
+2714
+2715
+2716
+2717
+2718
+2719
+2720
+2721
+2722
+2723
+2724
+2725
+2726
+2727
+2728
+2729
+2730
+2731
+2732
+2733
+2734
+2735
+2736
+2737
+2738
+2739
+2740
+2741
+2742
+2743
+2744
+2745
+2746
+2747
+2748
+2749
+2750
+2751
+2752
+2753
+2754
+2755
+2756
+2757
+2758
+2759
+2760
+2761
+2762
+2763
+2764
+2765
+2766
+2767
+2768
+2769
+2770
+2771
+2772
+2773
+2774
+2775
+2776
+2777
+2778
+2779
+2780
+2781
+2782
+2783
+2784
+2785
+2786
+2787
+2788
+2789
+2790
+2791
+2792
+2793
+2794
+2795
+2796
+2797
+2798
+2799
+2800
+2801
+2802
+2803
+2804
+2805
+2806
+2807
+2808
+2809
+2810
+2811
+2812
+2813
+2814
+2815
+2816
+2817
+2818
+2819
+2820
+2821
+2822
+2823
+2824
+2825
+2826
+2827
+2828
+2829
+2830
+2831
+2832
+2833
+2834
+2835
+2836
+2837
+2838
+2839
+2840
+2841
+2842
+2843
+2844
+2845
+2846
+2847
+2848
+2849
+2850
+2851
+2852
+2853
+2854
+2855
+2856
+2857
+2858
+2859
+2860
+2861
+2862
+2863
+2864
+2865
+2866
+2867
+2868
+2869
+2870
+2871
+2872
+2873
+2874
+2875
+2876
+2877
+2878
+2879
+2880
+2881
+2882
+2883
+2884
+2885
+2886
+2887
+2888
+2889
+2890
+2891
+2892
+2893
+2894
+2895
+2896
+2897
+2898
+2899
+2900
+2901
+2902
+2903
+2904
+2905
+2906
+2907
+2908
+2909
+2910
+2911
+2912
+2913
+2914
+2915
+2916
+2917
+2918
+2919
+2920
+2921
+2922
+2923
+2924
+2925
+2926
+2927
+2928
+2929
+2930
+2931
+2932
+2933
+2934
+2935
+2936
+2937
+2938
+2939
+2940
+2941
+2942
+2943
+2944
+2945
+2946
+2947
+2948
+2949
+2950
+2951
+2952
+2953
+2954
+2955
+2956
+2957
+2958
+2959
+2960
+2961
+2962
+2963
+2964
+2965
+2966
+2967
+2968
+2969
+2970
+2971
+2972
+2973
+2974
+2975
+2976
+2977
+2978
+2979
+2980
+2981
+2982
+2983
+2984
+2985
+2986
+2987
+2988
+2989
+2990
+2991
+2992
+2993
+2994
+2995
+2996
+2997
+2998
+2999
+3000
+3001
+3002
+3003
+3004
+3005
+3006
+3007
+3008
+3009
+3010
+3011
+3012
+3013
+3014
+3015
+3016
+3017
+3018
+3019
+3020
+3021
+3022
+3023
+3024
+3025
+3026
+3027
+3028
+3029
+3030
+3031
+3032
+3033
+3034
+3035
+3036
+3037
+3038
+3039
+3040
+3041
+3042
+3043
+3044
+3045
+3046
+3047
+3048
+3049
+3050
+3051
+3052
+3053
+3054
+3055
+3056
+3057
+3058
+3059
+3060
+3061
+3062
+3063
+3064
+3065
+3066
+3067
+3068
+3069
+3070
+3071
+3072
+3073
+3074
+3075
+3076
+3077
+3078
+3079
+3080
+3081
+3082
+3083
+3084
+3085
+3086
+3087
+3088
+3089
+3090
+3091
+3092
+3093
+3094
+3095
+3096
+3097
+3098
+3099
+3100
+3101
+3102
+3103
+3104
+3105
+3106
+3107
+3108
+3109
+3110
+3111
+3112
+3113
+3114
+3115
+3116
+3117
+3118
+3119
+3120
+3121
+3122
+3123
+3124
+3125
+3126
+3127
+3128
+3129
+3130
+3131
+3132
+3133
+3134
+3135
+3136
+3137
+3138
+3139
+3140
+3141
+3142
+3143
+3144
+3145
+3146
+3147
+3148
+3149
+3150
+3151
+3152
+3153
+3154
+3155
+3156
+3157
+3158
+3159
+3160
+3161
+3162
+3163
+3164
+3165
+3166
+3167
+3168
+3169
+3170
+3171
+3172
+3173
+3174
+3175
+3176
+3177
+3178
+3179
+3180
+3181
+3182
+3183
+3184
+3185
+3186
+3187
+3188
+3189
+3190
+3191
+3192
+3193
+3194
+3195
+3196
+3197
+3198
+3199
+3200
+3201
+3202
+3203
+3204
+3205
+3206
+3207
+3208
+3209
+3210
+3211
+3212
+3213
+3214
+3215
+3216
+3217
+3218
+3219
+3220
+3221
+3222
+3223
+3224
+3225
+3226
+3227
+3228
+3229
+3230
+3231
+3232
+3233
+3234
+3235
+3236
+3237
+3238
+3239
+3240
+3241
+3242
+3243
+3244
+3245
+3246
+3247
+3248
+3249
+3250
+3251
+3252
+3253
+3254
+3255
+3256
+3257
+3258
+3259
+3260
+3261
+3262
+3263
+3264
+3265
+3266
+3267
+3268
+3269
+3270
+3271
+3272
+3273
+3274
+3275
+3276
+3277
+3278
+3279
+3280
+3281
+3282
+3283
+3284
+3285
+3286
+3287
+3288
+3289
+3290
+3291
+3292
+3293
+3294
+3295
+3296
+3297
+3298
+3299
+3300
+3301
+3302
+3303
+3304
+3305
+3306
+3307
+3308
+3309
+3310
+3311
+3312
+3313
+3314
+3315
+3316
+3317
+3318
+3319
+3320
+3321
+3322
+3323
+3324
+3325
+3326
+3327
+3328
+3329
+3330
+3331
+3332
+3333
+3334
+3335
+3336
+3337
+3338
+3339
+3340
+3341
+3342
+3343
+3344
+3345
+3346
+3347
+3348
+3349
+3350
+3351
+3352
+3353
+3354
+3355
+3356
+3357
+3358
+3359
+3360
+3361
+3362
+3363
+3364
+3365
+3366
+3367
+3368
+3369
+3370
+3371
+3372
+3373
+3374
+3375
+3376
+3377
+3378
+3379
+3380
+3381
+3382
+3383
+3384
+3385
+3386
+3387
+3388
+3389
+3390
+3391
+3392
+3393
+3394
+3395
+3396
+3397
+3398
+3399
+3400
+3401
+3402
+3403
+3404
+3405
+3406
+3407
+3408
+3409
+3410
+3411
+3412
+3413
+3414
+3415
+3416
+3417
+3418
+3419
+3420
+3421
+3422
+3423
+3424
+3425
+3426
+3427
+3428
+3429
+3430
+3431
+3432
+3433
+3434
+3435
+3436
+3437
+3438
+3439
+3440
+3441
+3442
+3443
+3444
+3445
+3446
+3447
+3448
+3449
+3450
+3451
+3452
+3453
+3454
+3455
+3456
+3457
+3458
+3459
+3460
+3461
+3462
+3463
+3464
+3465
+3466
+3467
+3468
+3469
+3470
+3471
+3472
+3473
+3474
+3475
+3476
+3477
+3478
+3479
+3480
+3481
+3482
+3483
+3484
+3485
+3486
+3487
+3488
+3489
+3490
+3491
+3492
+3493
+3494
+3495
+3496
+3497
+3498
+3499
+3500
+3501
+3502
+3503
+3504
+3505
+3506
+3507
+3508
+3509
+3510
+3511
+3512
+3513
+3514
+3515
+3516
+3517
+3518
+3519
+3520
+3521
+3522
+3523
+3524
+3525
+3526
+3527
+3528
+3529
+3530
+3531
+3532
+3533
+3534
+3535
+3536
+3537
+3538
+3539
+3540
+3541
+3542
+3543
+3544
+3545
+3546
+3547
+3548
+3549
+3550
+3551
+3552
+3553
+3554
+3555
+3556
+3557
+3558
+3559
+3560
+3561
+3562
+3563
+3564
+3565
+3566
+3567
+3568
+3569
+3570
+3571
+3572
+3573
+3574
+3575
+3576
+3577
+3578
+3579
+3580
+3581
+3582
+3583
+3584
+3585
+3586
+3587
+3588
+3589
+3590
+3591
+3592
+3593
+3594
+3595
+3596
+3597
+3598
+3599
+3600
+3601
+3602
+3603
+3604
+3605
+3606
+3607
+3608
+3609
+3610
+3611
+3612
+3613
+3614
+3615
+3616
+3617
+3618
+3619
+3620
+3621
+3622
+3623
+3624
+3625
+3626
+3627
+3628
+3629
+3630
+3631
+3632
+3633
+3634
+3635
+3636
+3637
+3638
+3639
+3640
+3641
+3642
+3643
+3644
+3645
+3646
+3647
+3648
+3649
+3650
+3651
+3652
+3653
+3654
+3655
+3656
+3657
+3658
+3659
+3660
+3661
+3662
+3663
+3664
+3665
+3666
+3667
+3668
+3669
+3670
+3671
+3672
+3673
+3674
+3675
+3676
+3677
+3678
+3679
+3680
+3681
+3682
+3683
+3684
+3685
+3686
+3687
+3688
+3689
+3690
+3691
+3692
+3693
+3694
+3695
+3696
+3697
+3698
+3699
+3700
+3701
+3702
+3703
+3704
+3705
+3706
+3707
+3708
+3709
+3710
+3711
+3712
+3713
+3714
+3715
+3716
+3717
+3718
+3719
+3720
+3721
+3722
+3723
+3724
+3725
+3726
+3727
+3728
+3729
+3730
+3731
+3732
+3733
+3734
+3735
+3736
+3737
+3738
+3739
+3740
+3741
+3742
+3743
+3744
+3745
+3746
+3747
+3748
+3749
+3750
+3751
+3752
+3753
+3754
+3755
+3756
+3757
+3758
+3759
+3760
+3761
+3762
+3763
+3764
+3765
+3766
+3767
+3768
+3769
+3770
+3771
+3772
+3773
+3774
+3775
+3776
+3777
+3778
+3779
+3780
+3781
+3782
+3783
+3784
+3785
+3786
+3787
+3788
+3789
+3790
+3791
+3792
+3793
+3794
+3795
+3796
+3797
+3798
+3799
+3800
+3801
+3802
+3803
+3804
+3805
+3806
+3807
+3808
+3809
+3810
+3811
+3812
+3813
+3814
+3815
+3816
+3817
+3818
+3819
+3820
+3821
+3822
+3823
+3824
+3825
+3826
+3827
+3828
+3829
+3830
+3831
+3832
+3833
+3834
+3835
+3836
+3837
+3838
+3839
+3840
+3841
+3842
+3843
+3844
+3845
+3846
+3847
+3848
+3849
+3850
+3851
+3852
+3853
+3854
+3855
+3856
+3857
+3858
+3859
+3860
+3861
+3862
+3863
+3864
+3865
+3866
+3867
+3868
+3869
+3870
+3871
+3872
+3873
+3874
+3875
+3876
+3877
+3878
+3879
+3880
+3881
+3882
+3883
+3884
+3885
+3886
+3887
+3888
+3889
+3890
+3891
+3892
+3893
+3894
+3895
+3896
+3897
+3898
+3899
+3900
+3901
+3902
+3903
+3904
+3905
+3906
+3907
+3908
+3909
+3910
+3911
+3912
+3913
+3914
+3915
+3916
+3917
+3918
+3919
+3920
+3921
+3922
+3923
+3924
+3925
+3926
+3927
+3928
+3929
+3930
+3931
+3932
+3933
+3934
+3935
+3936
+3937
+3938
+3939
+3940
+3941
+3942
+3943
+3944
+3945
+3946
+3947
+3948
+3949
+3950
+3951
+3952
+3953
+3954
+3955
+3956
+3957
+3958
+3959
+3960
+3961
+3962
+3963
+3964
+3965
+3966
+3967
+3968
+3969
+3970
+3971
+3972
+3973
+3974
+3975
+3976
+3977
+3978
+3979
+3980
+3981
+3982
+3983
+3984
+3985
+3986
+3987
+3988
+3989
+3990
+3991
+3992
+3993
+3994
+3995
+3996
+3997
+3998
+3999
diff --git a/nashorn/test/script/basic/NASHORN-423a.js b/nashorn/test/script/basic/NASHORN-423a.js
new file mode 100644
index 0000000..bbab24f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-423a.js
@@ -0,0 +1,2030 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-423 - Large scripts don't fit into a single class file and need to be split.
+ *
+ * @test
+ * @run
+ */
+
+function a0(x, y) { print(0); }
+function a1(x, y) { print(1); }
+function a2(x, y) { print(2); }
+function a3(x, y) { print(3); }
+function a4(x, y) { print(4); }
+function a5(x, y) { print(5); }
+function a6(x, y) { print(6); }
+function a7(x, y) { print(7); }
+function a8(x, y) { print(8); }
+function a9(x, y) { print(9); }
+function a10(x, y) { print(10); }
+function a11(x, y) { print(11); }
+function a12(x, y) { print(12); }
+function a13(x, y) { print(13); }
+function a14(x, y) { print(14); }
+function a15(x, y) { print(15); }
+function a16(x, y) { print(16); }
+function a17(x, y) { print(17); }
+function a18(x, y) { print(18); }
+function a19(x, y) { print(19); }
+function a20(x, y) { print(20); }
+function a21(x, y) { print(21); }
+function a22(x, y) { print(22); }
+function a23(x, y) { print(23); }
+function a24(x, y) { print(24); }
+function a25(x, y) { print(25); }
+function a26(x, y) { print(26); }
+function a27(x, y) { print(27); }
+function a28(x, y) { print(28); }
+function a29(x, y) { print(29); }
+function a30(x, y) { print(30); }
+function a31(x, y) { print(31); }
+function a32(x, y) { print(32); }
+function a33(x, y) { print(33); }
+function a34(x, y) { print(34); }
+function a35(x, y) { print(35); }
+function a36(x, y) { print(36); }
+function a37(x, y) { print(37); }
+function a38(x, y) { print(38); }
+function a39(x, y) { print(39); }
+function a40(x, y) { print(40); }
+function a41(x, y) { print(41); }
+function a42(x, y) { print(42); }
+function a43(x, y) { print(43); }
+function a44(x, y) { print(44); }
+function a45(x, y) { print(45); }
+function a46(x, y) { print(46); }
+function a47(x, y) { print(47); }
+function a48(x, y) { print(48); }
+function a49(x, y) { print(49); }
+function a50(x, y) { print(50); }
+function a51(x, y) { print(51); }
+function a52(x, y) { print(52); }
+function a53(x, y) { print(53); }
+function a54(x, y) { print(54); }
+function a55(x, y) { print(55); }
+function a56(x, y) { print(56); }
+function a57(x, y) { print(57); }
+function a58(x, y) { print(58); }
+function a59(x, y) { print(59); }
+function a60(x, y) { print(60); }
+function a61(x, y) { print(61); }
+function a62(x, y) { print(62); }
+function a63(x, y) { print(63); }
+function a64(x, y) { print(64); }
+function a65(x, y) { print(65); }
+function a66(x, y) { print(66); }
+function a67(x, y) { print(67); }
+function a68(x, y) { print(68); }
+function a69(x, y) { print(69); }
+function a70(x, y) { print(70); }
+function a71(x, y) { print(71); }
+function a72(x, y) { print(72); }
+function a73(x, y) { print(73); }
+function a74(x, y) { print(74); }
+function a75(x, y) { print(75); }
+function a76(x, y) { print(76); }
+function a77(x, y) { print(77); }
+function a78(x, y) { print(78); }
+function a79(x, y) { print(79); }
+function a80(x, y) { print(80); }
+function a81(x, y) { print(81); }
+function a82(x, y) { print(82); }
+function a83(x, y) { print(83); }
+function a84(x, y) { print(84); }
+function a85(x, y) { print(85); }
+function a86(x, y) { print(86); }
+function a87(x, y) { print(87); }
+function a88(x, y) { print(88); }
+function a89(x, y) { print(89); }
+function a90(x, y) { print(90); }
+function a91(x, y) { print(91); }
+function a92(x, y) { print(92); }
+function a93(x, y) { print(93); }
+function a94(x, y) { print(94); }
+function a95(x, y) { print(95); }
+function a96(x, y) { print(96); }
+function a97(x, y) { print(97); }
+function a98(x, y) { print(98); }
+function a99(x, y) { print(99); }
+function a100(x, y) { print(100); }
+function a101(x, y) { print(101); }
+function a102(x, y) { print(102); }
+function a103(x, y) { print(103); }
+function a104(x, y) { print(104); }
+function a105(x, y) { print(105); }
+function a106(x, y) { print(106); }
+function a107(x, y) { print(107); }
+function a108(x, y) { print(108); }
+function a109(x, y) { print(109); }
+function a110(x, y) { print(110); }
+function a111(x, y) { print(111); }
+function a112(x, y) { print(112); }
+function a113(x, y) { print(113); }
+function a114(x, y) { print(114); }
+function a115(x, y) { print(115); }
+function a116(x, y) { print(116); }
+function a117(x, y) { print(117); }
+function a118(x, y) { print(118); }
+function a119(x, y) { print(119); }
+function a120(x, y) { print(120); }
+function a121(x, y) { print(121); }
+function a122(x, y) { print(122); }
+function a123(x, y) { print(123); }
+function a124(x, y) { print(124); }
+function a125(x, y) { print(125); }
+function a126(x, y) { print(126); }
+function a127(x, y) { print(127); }
+function a128(x, y) { print(128); }
+function a129(x, y) { print(129); }
+function a130(x, y) { print(130); }
+function a131(x, y) { print(131); }
+function a132(x, y) { print(132); }
+function a133(x, y) { print(133); }
+function a134(x, y) { print(134); }
+function a135(x, y) { print(135); }
+function a136(x, y) { print(136); }
+function a137(x, y) { print(137); }
+function a138(x, y) { print(138); }
+function a139(x, y) { print(139); }
+function a140(x, y) { print(140); }
+function a141(x, y) { print(141); }
+function a142(x, y) { print(142); }
+function a143(x, y) { print(143); }
+function a144(x, y) { print(144); }
+function a145(x, y) { print(145); }
+function a146(x, y) { print(146); }
+function a147(x, y) { print(147); }
+function a148(x, y) { print(148); }
+function a149(x, y) { print(149); }
+function a150(x, y) { print(150); }
+function a151(x, y) { print(151); }
+function a152(x, y) { print(152); }
+function a153(x, y) { print(153); }
+function a154(x, y) { print(154); }
+function a155(x, y) { print(155); }
+function a156(x, y) { print(156); }
+function a157(x, y) { print(157); }
+function a158(x, y) { print(158); }
+function a159(x, y) { print(159); }
+function a160(x, y) { print(160); }
+function a161(x, y) { print(161); }
+function a162(x, y) { print(162); }
+function a163(x, y) { print(163); }
+function a164(x, y) { print(164); }
+function a165(x, y) { print(165); }
+function a166(x, y) { print(166); }
+function a167(x, y) { print(167); }
+function a168(x, y) { print(168); }
+function a169(x, y) { print(169); }
+function a170(x, y) { print(170); }
+function a171(x, y) { print(171); }
+function a172(x, y) { print(172); }
+function a173(x, y) { print(173); }
+function a174(x, y) { print(174); }
+function a175(x, y) { print(175); }
+function a176(x, y) { print(176); }
+function a177(x, y) { print(177); }
+function a178(x, y) { print(178); }
+function a179(x, y) { print(179); }
+function a180(x, y) { print(180); }
+function a181(x, y) { print(181); }
+function a182(x, y) { print(182); }
+function a183(x, y) { print(183); }
+function a184(x, y) { print(184); }
+function a185(x, y) { print(185); }
+function a186(x, y) { print(186); }
+function a187(x, y) { print(187); }
+function a188(x, y) { print(188); }
+function a189(x, y) { print(189); }
+function a190(x, y) { print(190); }
+function a191(x, y) { print(191); }
+function a192(x, y) { print(192); }
+function a193(x, y) { print(193); }
+function a194(x, y) { print(194); }
+function a195(x, y) { print(195); }
+function a196(x, y) { print(196); }
+function a197(x, y) { print(197); }
+function a198(x, y) { print(198); }
+function a199(x, y) { print(199); }
+function a200(x, y) { print(200); }
+function a201(x, y) { print(201); }
+function a202(x, y) { print(202); }
+function a203(x, y) { print(203); }
+function a204(x, y) { print(204); }
+function a205(x, y) { print(205); }
+function a206(x, y) { print(206); }
+function a207(x, y) { print(207); }
+function a208(x, y) { print(208); }
+function a209(x, y) { print(209); }
+function a210(x, y) { print(210); }
+function a211(x, y) { print(211); }
+function a212(x, y) { print(212); }
+function a213(x, y) { print(213); }
+function a214(x, y) { print(214); }
+function a215(x, y) { print(215); }
+function a216(x, y) { print(216); }
+function a217(x, y) { print(217); }
+function a218(x, y) { print(218); }
+function a219(x, y) { print(219); }
+function a220(x, y) { print(220); }
+function a221(x, y) { print(221); }
+function a222(x, y) { print(222); }
+function a223(x, y) { print(223); }
+function a224(x, y) { print(224); }
+function a225(x, y) { print(225); }
+function a226(x, y) { print(226); }
+function a227(x, y) { print(227); }
+function a228(x, y) { print(228); }
+function a229(x, y) { print(229); }
+function a230(x, y) { print(230); }
+function a231(x, y) { print(231); }
+function a232(x, y) { print(232); }
+function a233(x, y) { print(233); }
+function a234(x, y) { print(234); }
+function a235(x, y) { print(235); }
+function a236(x, y) { print(236); }
+function a237(x, y) { print(237); }
+function a238(x, y) { print(238); }
+function a239(x, y) { print(239); }
+function a240(x, y) { print(240); }
+function a241(x, y) { print(241); }
+function a242(x, y) { print(242); }
+function a243(x, y) { print(243); }
+function a244(x, y) { print(244); }
+function a245(x, y) { print(245); }
+function a246(x, y) { print(246); }
+function a247(x, y) { print(247); }
+function a248(x, y) { print(248); }
+function a249(x, y) { print(249); }
+function a250(x, y) { print(250); }
+function a251(x, y) { print(251); }
+function a252(x, y) { print(252); }
+function a253(x, y) { print(253); }
+function a254(x, y) { print(254); }
+function a255(x, y) { print(255); }
+function a256(x, y) { print(256); }
+function a257(x, y) { print(257); }
+function a258(x, y) { print(258); }
+function a259(x, y) { print(259); }
+function a260(x, y) { print(260); }
+function a261(x, y) { print(261); }
+function a262(x, y) { print(262); }
+function a263(x, y) { print(263); }
+function a264(x, y) { print(264); }
+function a265(x, y) { print(265); }
+function a266(x, y) { print(266); }
+function a267(x, y) { print(267); }
+function a268(x, y) { print(268); }
+function a269(x, y) { print(269); }
+function a270(x, y) { print(270); }
+function a271(x, y) { print(271); }
+function a272(x, y) { print(272); }
+function a273(x, y) { print(273); }
+function a274(x, y) { print(274); }
+function a275(x, y) { print(275); }
+function a276(x, y) { print(276); }
+function a277(x, y) { print(277); }
+function a278(x, y) { print(278); }
+function a279(x, y) { print(279); }
+function a280(x, y) { print(280); }
+function a281(x, y) { print(281); }
+function a282(x, y) { print(282); }
+function a283(x, y) { print(283); }
+function a284(x, y) { print(284); }
+function a285(x, y) { print(285); }
+function a286(x, y) { print(286); }
+function a287(x, y) { print(287); }
+function a288(x, y) { print(288); }
+function a289(x, y) { print(289); }
+function a290(x, y) { print(290); }
+function a291(x, y) { print(291); }
+function a292(x, y) { print(292); }
+function a293(x, y) { print(293); }
+function a294(x, y) { print(294); }
+function a295(x, y) { print(295); }
+function a296(x, y) { print(296); }
+function a297(x, y) { print(297); }
+function a298(x, y) { print(298); }
+function a299(x, y) { print(299); }
+function a300(x, y) { print(300); }
+function a301(x, y) { print(301); }
+function a302(x, y) { print(302); }
+function a303(x, y) { print(303); }
+function a304(x, y) { print(304); }
+function a305(x, y) { print(305); }
+function a306(x, y) { print(306); }
+function a307(x, y) { print(307); }
+function a308(x, y) { print(308); }
+function a309(x, y) { print(309); }
+function a310(x, y) { print(310); }
+function a311(x, y) { print(311); }
+function a312(x, y) { print(312); }
+function a313(x, y) { print(313); }
+function a314(x, y) { print(314); }
+function a315(x, y) { print(315); }
+function a316(x, y) { print(316); }
+function a317(x, y) { print(317); }
+function a318(x, y) { print(318); }
+function a319(x, y) { print(319); }
+function a320(x, y) { print(320); }
+function a321(x, y) { print(321); }
+function a322(x, y) { print(322); }
+function a323(x, y) { print(323); }
+function a324(x, y) { print(324); }
+function a325(x, y) { print(325); }
+function a326(x, y) { print(326); }
+function a327(x, y) { print(327); }
+function a328(x, y) { print(328); }
+function a329(x, y) { print(329); }
+function a330(x, y) { print(330); }
+function a331(x, y) { print(331); }
+function a332(x, y) { print(332); }
+function a333(x, y) { print(333); }
+function a334(x, y) { print(334); }
+function a335(x, y) { print(335); }
+function a336(x, y) { print(336); }
+function a337(x, y) { print(337); }
+function a338(x, y) { print(338); }
+function a339(x, y) { print(339); }
+function a340(x, y) { print(340); }
+function a341(x, y) { print(341); }
+function a342(x, y) { print(342); }
+function a343(x, y) { print(343); }
+function a344(x, y) { print(344); }
+function a345(x, y) { print(345); }
+function a346(x, y) { print(346); }
+function a347(x, y) { print(347); }
+function a348(x, y) { print(348); }
+function a349(x, y) { print(349); }
+function a350(x, y) { print(350); }
+function a351(x, y) { print(351); }
+function a352(x, y) { print(352); }
+function a353(x, y) { print(353); }
+function a354(x, y) { print(354); }
+function a355(x, y) { print(355); }
+function a356(x, y) { print(356); }
+function a357(x, y) { print(357); }
+function a358(x, y) { print(358); }
+function a359(x, y) { print(359); }
+function a360(x, y) { print(360); }
+function a361(x, y) { print(361); }
+function a362(x, y) { print(362); }
+function a363(x, y) { print(363); }
+function a364(x, y) { print(364); }
+function a365(x, y) { print(365); }
+function a366(x, y) { print(366); }
+function a367(x, y) { print(367); }
+function a368(x, y) { print(368); }
+function a369(x, y) { print(369); }
+function a370(x, y) { print(370); }
+function a371(x, y) { print(371); }
+function a372(x, y) { print(372); }
+function a373(x, y) { print(373); }
+function a374(x, y) { print(374); }
+function a375(x, y) { print(375); }
+function a376(x, y) { print(376); }
+function a377(x, y) { print(377); }
+function a378(x, y) { print(378); }
+function a379(x, y) { print(379); }
+function a380(x, y) { print(380); }
+function a381(x, y) { print(381); }
+function a382(x, y) { print(382); }
+function a383(x, y) { print(383); }
+function a384(x, y) { print(384); }
+function a385(x, y) { print(385); }
+function a386(x, y) { print(386); }
+function a387(x, y) { print(387); }
+function a388(x, y) { print(388); }
+function a389(x, y) { print(389); }
+function a390(x, y) { print(390); }
+function a391(x, y) { print(391); }
+function a392(x, y) { print(392); }
+function a393(x, y) { print(393); }
+function a394(x, y) { print(394); }
+function a395(x, y) { print(395); }
+function a396(x, y) { print(396); }
+function a397(x, y) { print(397); }
+function a398(x, y) { print(398); }
+function a399(x, y) { print(399); }
+function a400(x, y) { print(400); }
+function a401(x, y) { print(401); }
+function a402(x, y) { print(402); }
+function a403(x, y) { print(403); }
+function a404(x, y) { print(404); }
+function a405(x, y) { print(405); }
+function a406(x, y) { print(406); }
+function a407(x, y) { print(407); }
+function a408(x, y) { print(408); }
+function a409(x, y) { print(409); }
+function a410(x, y) { print(410); }
+function a411(x, y) { print(411); }
+function a412(x, y) { print(412); }
+function a413(x, y) { print(413); }
+function a414(x, y) { print(414); }
+function a415(x, y) { print(415); }
+function a416(x, y) { print(416); }
+function a417(x, y) { print(417); }
+function a418(x, y) { print(418); }
+function a419(x, y) { print(419); }
+function a420(x, y) { print(420); }
+function a421(x, y) { print(421); }
+function a422(x, y) { print(422); }
+function a423(x, y) { print(423); }
+function a424(x, y) { print(424); }
+function a425(x, y) { print(425); }
+function a426(x, y) { print(426); }
+function a427(x, y) { print(427); }
+function a428(x, y) { print(428); }
+function a429(x, y) { print(429); }
+function a430(x, y) { print(430); }
+function a431(x, y) { print(431); }
+function a432(x, y) { print(432); }
+function a433(x, y) { print(433); }
+function a434(x, y) { print(434); }
+function a435(x, y) { print(435); }
+function a436(x, y) { print(436); }
+function a437(x, y) { print(437); }
+function a438(x, y) { print(438); }
+function a439(x, y) { print(439); }
+function a440(x, y) { print(440); }
+function a441(x, y) { print(441); }
+function a442(x, y) { print(442); }
+function a443(x, y) { print(443); }
+function a444(x, y) { print(444); }
+function a445(x, y) { print(445); }
+function a446(x, y) { print(446); }
+function a447(x, y) { print(447); }
+function a448(x, y) { print(448); }
+function a449(x, y) { print(449); }
+function a450(x, y) { print(450); }
+function a451(x, y) { print(451); }
+function a452(x, y) { print(452); }
+function a453(x, y) { print(453); }
+function a454(x, y) { print(454); }
+function a455(x, y) { print(455); }
+function a456(x, y) { print(456); }
+function a457(x, y) { print(457); }
+function a458(x, y) { print(458); }
+function a459(x, y) { print(459); }
+function a460(x, y) { print(460); }
+function a461(x, y) { print(461); }
+function a462(x, y) { print(462); }
+function a463(x, y) { print(463); }
+function a464(x, y) { print(464); }
+function a465(x, y) { print(465); }
+function a466(x, y) { print(466); }
+function a467(x, y) { print(467); }
+function a468(x, y) { print(468); }
+function a469(x, y) { print(469); }
+function a470(x, y) { print(470); }
+function a471(x, y) { print(471); }
+function a472(x, y) { print(472); }
+function a473(x, y) { print(473); }
+function a474(x, y) { print(474); }
+function a475(x, y) { print(475); }
+function a476(x, y) { print(476); }
+function a477(x, y) { print(477); }
+function a478(x, y) { print(478); }
+function a479(x, y) { print(479); }
+function a480(x, y) { print(480); }
+function a481(x, y) { print(481); }
+function a482(x, y) { print(482); }
+function a483(x, y) { print(483); }
+function a484(x, y) { print(484); }
+function a485(x, y) { print(485); }
+function a486(x, y) { print(486); }
+function a487(x, y) { print(487); }
+function a488(x, y) { print(488); }
+function a489(x, y) { print(489); }
+function a490(x, y) { print(490); }
+function a491(x, y) { print(491); }
+function a492(x, y) { print(492); }
+function a493(x, y) { print(493); }
+function a494(x, y) { print(494); }
+function a495(x, y) { print(495); }
+function a496(x, y) { print(496); }
+function a497(x, y) { print(497); }
+function a498(x, y) { print(498); }
+function a499(x, y) { print(499); }
+function a500(x, y) { print(500); }
+function a501(x, y) { print(501); }
+function a502(x, y) { print(502); }
+function a503(x, y) { print(503); }
+function a504(x, y) { print(504); }
+function a505(x, y) { print(505); }
+function a506(x, y) { print(506); }
+function a507(x, y) { print(507); }
+function a508(x, y) { print(508); }
+function a509(x, y) { print(509); }
+function a510(x, y) { print(510); }
+function a511(x, y) { print(511); }
+function a512(x, y) { print(512); }
+function a513(x, y) { print(513); }
+function a514(x, y) { print(514); }
+function a515(x, y) { print(515); }
+function a516(x, y) { print(516); }
+function a517(x, y) { print(517); }
+function a518(x, y) { print(518); }
+function a519(x, y) { print(519); }
+function a520(x, y) { print(520); }
+function a521(x, y) { print(521); }
+function a522(x, y) { print(522); }
+function a523(x, y) { print(523); }
+function a524(x, y) { print(524); }
+function a525(x, y) { print(525); }
+function a526(x, y) { print(526); }
+function a527(x, y) { print(527); }
+function a528(x, y) { print(528); }
+function a529(x, y) { print(529); }
+function a530(x, y) { print(530); }
+function a531(x, y) { print(531); }
+function a532(x, y) { print(532); }
+function a533(x, y) { print(533); }
+function a534(x, y) { print(534); }
+function a535(x, y) { print(535); }
+function a536(x, y) { print(536); }
+function a537(x, y) { print(537); }
+function a538(x, y) { print(538); }
+function a539(x, y) { print(539); }
+function a540(x, y) { print(540); }
+function a541(x, y) { print(541); }
+function a542(x, y) { print(542); }
+function a543(x, y) { print(543); }
+function a544(x, y) { print(544); }
+function a545(x, y) { print(545); }
+function a546(x, y) { print(546); }
+function a547(x, y) { print(547); }
+function a548(x, y) { print(548); }
+function a549(x, y) { print(549); }
+function a550(x, y) { print(550); }
+function a551(x, y) { print(551); }
+function a552(x, y) { print(552); }
+function a553(x, y) { print(553); }
+function a554(x, y) { print(554); }
+function a555(x, y) { print(555); }
+function a556(x, y) { print(556); }
+function a557(x, y) { print(557); }
+function a558(x, y) { print(558); }
+function a559(x, y) { print(559); }
+function a560(x, y) { print(560); }
+function a561(x, y) { print(561); }
+function a562(x, y) { print(562); }
+function a563(x, y) { print(563); }
+function a564(x, y) { print(564); }
+function a565(x, y) { print(565); }
+function a566(x, y) { print(566); }
+function a567(x, y) { print(567); }
+function a568(x, y) { print(568); }
+function a569(x, y) { print(569); }
+function a570(x, y) { print(570); }
+function a571(x, y) { print(571); }
+function a572(x, y) { print(572); }
+function a573(x, y) { print(573); }
+function a574(x, y) { print(574); }
+function a575(x, y) { print(575); }
+function a576(x, y) { print(576); }
+function a577(x, y) { print(577); }
+function a578(x, y) { print(578); }
+function a579(x, y) { print(579); }
+function a580(x, y) { print(580); }
+function a581(x, y) { print(581); }
+function a582(x, y) { print(582); }
+function a583(x, y) { print(583); }
+function a584(x, y) { print(584); }
+function a585(x, y) { print(585); }
+function a586(x, y) { print(586); }
+function a587(x, y) { print(587); }
+function a588(x, y) { print(588); }
+function a589(x, y) { print(589); }
+function a590(x, y) { print(590); }
+function a591(x, y) { print(591); }
+function a592(x, y) { print(592); }
+function a593(x, y) { print(593); }
+function a594(x, y) { print(594); }
+function a595(x, y) { print(595); }
+function a596(x, y) { print(596); }
+function a597(x, y) { print(597); }
+function a598(x, y) { print(598); }
+function a599(x, y) { print(599); }
+function a600(x, y) { print(600); }
+function a601(x, y) { print(601); }
+function a602(x, y) { print(602); }
+function a603(x, y) { print(603); }
+function a604(x, y) { print(604); }
+function a605(x, y) { print(605); }
+function a606(x, y) { print(606); }
+function a607(x, y) { print(607); }
+function a608(x, y) { print(608); }
+function a609(x, y) { print(609); }
+function a610(x, y) { print(610); }
+function a611(x, y) { print(611); }
+function a612(x, y) { print(612); }
+function a613(x, y) { print(613); }
+function a614(x, y) { print(614); }
+function a615(x, y) { print(615); }
+function a616(x, y) { print(616); }
+function a617(x, y) { print(617); }
+function a618(x, y) { print(618); }
+function a619(x, y) { print(619); }
+function a620(x, y) { print(620); }
+function a621(x, y) { print(621); }
+function a622(x, y) { print(622); }
+function a623(x, y) { print(623); }
+function a624(x, y) { print(624); }
+function a625(x, y) { print(625); }
+function a626(x, y) { print(626); }
+function a627(x, y) { print(627); }
+function a628(x, y) { print(628); }
+function a629(x, y) { print(629); }
+function a630(x, y) { print(630); }
+function a631(x, y) { print(631); }
+function a632(x, y) { print(632); }
+function a633(x, y) { print(633); }
+function a634(x, y) { print(634); }
+function a635(x, y) { print(635); }
+function a636(x, y) { print(636); }
+function a637(x, y) { print(637); }
+function a638(x, y) { print(638); }
+function a639(x, y) { print(639); }
+function a640(x, y) { print(640); }
+function a641(x, y) { print(641); }
+function a642(x, y) { print(642); }
+function a643(x, y) { print(643); }
+function a644(x, y) { print(644); }
+function a645(x, y) { print(645); }
+function a646(x, y) { print(646); }
+function a647(x, y) { print(647); }
+function a648(x, y) { print(648); }
+function a649(x, y) { print(649); }
+function a650(x, y) { print(650); }
+function a651(x, y) { print(651); }
+function a652(x, y) { print(652); }
+function a653(x, y) { print(653); }
+function a654(x, y) { print(654); }
+function a655(x, y) { print(655); }
+function a656(x, y) { print(656); }
+function a657(x, y) { print(657); }
+function a658(x, y) { print(658); }
+function a659(x, y) { print(659); }
+function a660(x, y) { print(660); }
+function a661(x, y) { print(661); }
+function a662(x, y) { print(662); }
+function a663(x, y) { print(663); }
+function a664(x, y) { print(664); }
+function a665(x, y) { print(665); }
+function a666(x, y) { print(666); }
+function a667(x, y) { print(667); }
+function a668(x, y) { print(668); }
+function a669(x, y) { print(669); }
+function a670(x, y) { print(670); }
+function a671(x, y) { print(671); }
+function a672(x, y) { print(672); }
+function a673(x, y) { print(673); }
+function a674(x, y) { print(674); }
+function a675(x, y) { print(675); }
+function a676(x, y) { print(676); }
+function a677(x, y) { print(677); }
+function a678(x, y) { print(678); }
+function a679(x, y) { print(679); }
+function a680(x, y) { print(680); }
+function a681(x, y) { print(681); }
+function a682(x, y) { print(682); }
+function a683(x, y) { print(683); }
+function a684(x, y) { print(684); }
+function a685(x, y) { print(685); }
+function a686(x, y) { print(686); }
+function a687(x, y) { print(687); }
+function a688(x, y) { print(688); }
+function a689(x, y) { print(689); }
+function a690(x, y) { print(690); }
+function a691(x, y) { print(691); }
+function a692(x, y) { print(692); }
+function a693(x, y) { print(693); }
+function a694(x, y) { print(694); }
+function a695(x, y) { print(695); }
+function a696(x, y) { print(696); }
+function a697(x, y) { print(697); }
+function a698(x, y) { print(698); }
+function a699(x, y) { print(699); }
+function a700(x, y) { print(700); }
+function a701(x, y) { print(701); }
+function a702(x, y) { print(702); }
+function a703(x, y) { print(703); }
+function a704(x, y) { print(704); }
+function a705(x, y) { print(705); }
+function a706(x, y) { print(706); }
+function a707(x, y) { print(707); }
+function a708(x, y) { print(708); }
+function a709(x, y) { print(709); }
+function a710(x, y) { print(710); }
+function a711(x, y) { print(711); }
+function a712(x, y) { print(712); }
+function a713(x, y) { print(713); }
+function a714(x, y) { print(714); }
+function a715(x, y) { print(715); }
+function a716(x, y) { print(716); }
+function a717(x, y) { print(717); }
+function a718(x, y) { print(718); }
+function a719(x, y) { print(719); }
+function a720(x, y) { print(720); }
+function a721(x, y) { print(721); }
+function a722(x, y) { print(722); }
+function a723(x, y) { print(723); }
+function a724(x, y) { print(724); }
+function a725(x, y) { print(725); }
+function a726(x, y) { print(726); }
+function a727(x, y) { print(727); }
+function a728(x, y) { print(728); }
+function a729(x, y) { print(729); }
+function a730(x, y) { print(730); }
+function a731(x, y) { print(731); }
+function a732(x, y) { print(732); }
+function a733(x, y) { print(733); }
+function a734(x, y) { print(734); }
+function a735(x, y) { print(735); }
+function a736(x, y) { print(736); }
+function a737(x, y) { print(737); }
+function a738(x, y) { print(738); }
+function a739(x, y) { print(739); }
+function a740(x, y) { print(740); }
+function a741(x, y) { print(741); }
+function a742(x, y) { print(742); }
+function a743(x, y) { print(743); }
+function a744(x, y) { print(744); }
+function a745(x, y) { print(745); }
+function a746(x, y) { print(746); }
+function a747(x, y) { print(747); }
+function a748(x, y) { print(748); }
+function a749(x, y) { print(749); }
+function a750(x, y) { print(750); }
+function a751(x, y) { print(751); }
+function a752(x, y) { print(752); }
+function a753(x, y) { print(753); }
+function a754(x, y) { print(754); }
+function a755(x, y) { print(755); }
+function a756(x, y) { print(756); }
+function a757(x, y) { print(757); }
+function a758(x, y) { print(758); }
+function a759(x, y) { print(759); }
+function a760(x, y) { print(760); }
+function a761(x, y) { print(761); }
+function a762(x, y) { print(762); }
+function a763(x, y) { print(763); }
+function a764(x, y) { print(764); }
+function a765(x, y) { print(765); }
+function a766(x, y) { print(766); }
+function a767(x, y) { print(767); }
+function a768(x, y) { print(768); }
+function a769(x, y) { print(769); }
+function a770(x, y) { print(770); }
+function a771(x, y) { print(771); }
+function a772(x, y) { print(772); }
+function a773(x, y) { print(773); }
+function a774(x, y) { print(774); }
+function a775(x, y) { print(775); }
+function a776(x, y) { print(776); }
+function a777(x, y) { print(777); }
+function a778(x, y) { print(778); }
+function a779(x, y) { print(779); }
+function a780(x, y) { print(780); }
+function a781(x, y) { print(781); }
+function a782(x, y) { print(782); }
+function a783(x, y) { print(783); }
+function a784(x, y) { print(784); }
+function a785(x, y) { print(785); }
+function a786(x, y) { print(786); }
+function a787(x, y) { print(787); }
+function a788(x, y) { print(788); }
+function a789(x, y) { print(789); }
+function a790(x, y) { print(790); }
+function a791(x, y) { print(791); }
+function a792(x, y) { print(792); }
+function a793(x, y) { print(793); }
+function a794(x, y) { print(794); }
+function a795(x, y) { print(795); }
+function a796(x, y) { print(796); }
+function a797(x, y) { print(797); }
+function a798(x, y) { print(798); }
+function a799(x, y) { print(799); }
+function a800(x, y) { print(800); }
+function a801(x, y) { print(801); }
+function a802(x, y) { print(802); }
+function a803(x, y) { print(803); }
+function a804(x, y) { print(804); }
+function a805(x, y) { print(805); }
+function a806(x, y) { print(806); }
+function a807(x, y) { print(807); }
+function a808(x, y) { print(808); }
+function a809(x, y) { print(809); }
+function a810(x, y) { print(810); }
+function a811(x, y) { print(811); }
+function a812(x, y) { print(812); }
+function a813(x, y) { print(813); }
+function a814(x, y) { print(814); }
+function a815(x, y) { print(815); }
+function a816(x, y) { print(816); }
+function a817(x, y) { print(817); }
+function a818(x, y) { print(818); }
+function a819(x, y) { print(819); }
+function a820(x, y) { print(820); }
+function a821(x, y) { print(821); }
+function a822(x, y) { print(822); }
+function a823(x, y) { print(823); }
+function a824(x, y) { print(824); }
+function a825(x, y) { print(825); }
+function a826(x, y) { print(826); }
+function a827(x, y) { print(827); }
+function a828(x, y) { print(828); }
+function a829(x, y) { print(829); }
+function a830(x, y) { print(830); }
+function a831(x, y) { print(831); }
+function a832(x, y) { print(832); }
+function a833(x, y) { print(833); }
+function a834(x, y) { print(834); }
+function a835(x, y) { print(835); }
+function a836(x, y) { print(836); }
+function a837(x, y) { print(837); }
+function a838(x, y) { print(838); }
+function a839(x, y) { print(839); }
+function a840(x, y) { print(840); }
+function a841(x, y) { print(841); }
+function a842(x, y) { print(842); }
+function a843(x, y) { print(843); }
+function a844(x, y) { print(844); }
+function a845(x, y) { print(845); }
+function a846(x, y) { print(846); }
+function a847(x, y) { print(847); }
+function a848(x, y) { print(848); }
+function a849(x, y) { print(849); }
+function a850(x, y) { print(850); }
+function a851(x, y) { print(851); }
+function a852(x, y) { print(852); }
+function a853(x, y) { print(853); }
+function a854(x, y) { print(854); }
+function a855(x, y) { print(855); }
+function a856(x, y) { print(856); }
+function a857(x, y) { print(857); }
+function a858(x, y) { print(858); }
+function a859(x, y) { print(859); }
+function a860(x, y) { print(860); }
+function a861(x, y) { print(861); }
+function a862(x, y) { print(862); }
+function a863(x, y) { print(863); }
+function a864(x, y) { print(864); }
+function a865(x, y) { print(865); }
+function a866(x, y) { print(866); }
+function a867(x, y) { print(867); }
+function a868(x, y) { print(868); }
+function a869(x, y) { print(869); }
+function a870(x, y) { print(870); }
+function a871(x, y) { print(871); }
+function a872(x, y) { print(872); }
+function a873(x, y) { print(873); }
+function a874(x, y) { print(874); }
+function a875(x, y) { print(875); }
+function a876(x, y) { print(876); }
+function a877(x, y) { print(877); }
+function a878(x, y) { print(878); }
+function a879(x, y) { print(879); }
+function a880(x, y) { print(880); }
+function a881(x, y) { print(881); }
+function a882(x, y) { print(882); }
+function a883(x, y) { print(883); }
+function a884(x, y) { print(884); }
+function a885(x, y) { print(885); }
+function a886(x, y) { print(886); }
+function a887(x, y) { print(887); }
+function a888(x, y) { print(888); }
+function a889(x, y) { print(889); }
+function a890(x, y) { print(890); }
+function a891(x, y) { print(891); }
+function a892(x, y) { print(892); }
+function a893(x, y) { print(893); }
+function a894(x, y) { print(894); }
+function a895(x, y) { print(895); }
+function a896(x, y) { print(896); }
+function a897(x, y) { print(897); }
+function a898(x, y) { print(898); }
+function a899(x, y) { print(899); }
+function a900(x, y) { print(900); }
+function a901(x, y) { print(901); }
+function a902(x, y) { print(902); }
+function a903(x, y) { print(903); }
+function a904(x, y) { print(904); }
+function a905(x, y) { print(905); }
+function a906(x, y) { print(906); }
+function a907(x, y) { print(907); }
+function a908(x, y) { print(908); }
+function a909(x, y) { print(909); }
+function a910(x, y) { print(910); }
+function a911(x, y) { print(911); }
+function a912(x, y) { print(912); }
+function a913(x, y) { print(913); }
+function a914(x, y) { print(914); }
+function a915(x, y) { print(915); }
+function a916(x, y) { print(916); }
+function a917(x, y) { print(917); }
+function a918(x, y) { print(918); }
+function a919(x, y) { print(919); }
+function a920(x, y) { print(920); }
+function a921(x, y) { print(921); }
+function a922(x, y) { print(922); }
+function a923(x, y) { print(923); }
+function a924(x, y) { print(924); }
+function a925(x, y) { print(925); }
+function a926(x, y) { print(926); }
+function a927(x, y) { print(927); }
+function a928(x, y) { print(928); }
+function a929(x, y) { print(929); }
+function a930(x, y) { print(930); }
+function a931(x, y) { print(931); }
+function a932(x, y) { print(932); }
+function a933(x, y) { print(933); }
+function a934(x, y) { print(934); }
+function a935(x, y) { print(935); }
+function a936(x, y) { print(936); }
+function a937(x, y) { print(937); }
+function a938(x, y) { print(938); }
+function a939(x, y) { print(939); }
+function a940(x, y) { print(940); }
+function a941(x, y) { print(941); }
+function a942(x, y) { print(942); }
+function a943(x, y) { print(943); }
+function a944(x, y) { print(944); }
+function a945(x, y) { print(945); }
+function a946(x, y) { print(946); }
+function a947(x, y) { print(947); }
+function a948(x, y) { print(948); }
+function a949(x, y) { print(949); }
+function a950(x, y) { print(950); }
+function a951(x, y) { print(951); }
+function a952(x, y) { print(952); }
+function a953(x, y) { print(953); }
+function a954(x, y) { print(954); }
+function a955(x, y) { print(955); }
+function a956(x, y) { print(956); }
+function a957(x, y) { print(957); }
+function a958(x, y) { print(958); }
+function a959(x, y) { print(959); }
+function a960(x, y) { print(960); }
+function a961(x, y) { print(961); }
+function a962(x, y) { print(962); }
+function a963(x, y) { print(963); }
+function a964(x, y) { print(964); }
+function a965(x, y) { print(965); }
+function a966(x, y) { print(966); }
+function a967(x, y) { print(967); }
+function a968(x, y) { print(968); }
+function a969(x, y) { print(969); }
+function a970(x, y) { print(970); }
+function a971(x, y) { print(971); }
+function a972(x, y) { print(972); }
+function a973(x, y) { print(973); }
+function a974(x, y) { print(974); }
+function a975(x, y) { print(975); }
+function a976(x, y) { print(976); }
+function a977(x, y) { print(977); }
+function a978(x, y) { print(978); }
+function a979(x, y) { print(979); }
+function a980(x, y) { print(980); }
+function a981(x, y) { print(981); }
+function a982(x, y) { print(982); }
+function a983(x, y) { print(983); }
+function a984(x, y) { print(984); }
+function a985(x, y) { print(985); }
+function a986(x, y) { print(986); }
+function a987(x, y) { print(987); }
+function a988(x, y) { print(988); }
+function a989(x, y) { print(989); }
+function a990(x, y) { print(990); }
+function a991(x, y) { print(991); }
+function a992(x, y) { print(992); }
+function a993(x, y) { print(993); }
+function a994(x, y) { print(994); }
+function a995(x, y) { print(995); }
+function a996(x, y) { print(996); }
+function a997(x, y) { print(997); }
+function a998(x, y) { print(998); }
+function a999(x, y) { print(999); }
+function a1000(x, y) { print(1000); }
+function a1001(x, y) { print(1001); }
+function a1002(x, y) { print(1002); }
+function a1003(x, y) { print(1003); }
+function a1004(x, y) { print(1004); }
+function a1005(x, y) { print(1005); }
+function a1006(x, y) { print(1006); }
+function a1007(x, y) { print(1007); }
+function a1008(x, y) { print(1008); }
+function a1009(x, y) { print(1009); }
+function a1010(x, y) { print(1010); }
+function a1011(x, y) { print(1011); }
+function a1012(x, y) { print(1012); }
+function a1013(x, y) { print(1013); }
+function a1014(x, y) { print(1014); }
+function a1015(x, y) { print(1015); }
+function a1016(x, y) { print(1016); }
+function a1017(x, y) { print(1017); }
+function a1018(x, y) { print(1018); }
+function a1019(x, y) { print(1019); }
+function a1020(x, y) { print(1020); }
+function a1021(x, y) { print(1021); }
+function a1022(x, y) { print(1022); }
+function a1023(x, y) { print(1023); }
+function a1024(x, y) { print(1024); }
+function a1025(x, y) { print(1025); }
+function a1026(x, y) { print(1026); }
+function a1027(x, y) { print(1027); }
+function a1028(x, y) { print(1028); }
+function a1029(x, y) { print(1029); }
+function a1030(x, y) { print(1030); }
+function a1031(x, y) { print(1031); }
+function a1032(x, y) { print(1032); }
+function a1033(x, y) { print(1033); }
+function a1034(x, y) { print(1034); }
+function a1035(x, y) { print(1035); }
+function a1036(x, y) { print(1036); }
+function a1037(x, y) { print(1037); }
+function a1038(x, y) { print(1038); }
+function a1039(x, y) { print(1039); }
+function a1040(x, y) { print(1040); }
+function a1041(x, y) { print(1041); }
+function a1042(x, y) { print(1042); }
+function a1043(x, y) { print(1043); }
+function a1044(x, y) { print(1044); }
+function a1045(x, y) { print(1045); }
+function a1046(x, y) { print(1046); }
+function a1047(x, y) { print(1047); }
+function a1048(x, y) { print(1048); }
+function a1049(x, y) { print(1049); }
+function a1050(x, y) { print(1050); }
+function a1051(x, y) { print(1051); }
+function a1052(x, y) { print(1052); }
+function a1053(x, y) { print(1053); }
+function a1054(x, y) { print(1054); }
+function a1055(x, y) { print(1055); }
+function a1056(x, y) { print(1056); }
+function a1057(x, y) { print(1057); }
+function a1058(x, y) { print(1058); }
+function a1059(x, y) { print(1059); }
+function a1060(x, y) { print(1060); }
+function a1061(x, y) { print(1061); }
+function a1062(x, y) { print(1062); }
+function a1063(x, y) { print(1063); }
+function a1064(x, y) { print(1064); }
+function a1065(x, y) { print(1065); }
+function a1066(x, y) { print(1066); }
+function a1067(x, y) { print(1067); }
+function a1068(x, y) { print(1068); }
+function a1069(x, y) { print(1069); }
+function a1070(x, y) { print(1070); }
+function a1071(x, y) { print(1071); }
+function a1072(x, y) { print(1072); }
+function a1073(x, y) { print(1073); }
+function a1074(x, y) { print(1074); }
+function a1075(x, y) { print(1075); }
+function a1076(x, y) { print(1076); }
+function a1077(x, y) { print(1077); }
+function a1078(x, y) { print(1078); }
+function a1079(x, y) { print(1079); }
+function a1080(x, y) { print(1080); }
+function a1081(x, y) { print(1081); }
+function a1082(x, y) { print(1082); }
+function a1083(x, y) { print(1083); }
+function a1084(x, y) { print(1084); }
+function a1085(x, y) { print(1085); }
+function a1086(x, y) { print(1086); }
+function a1087(x, y) { print(1087); }
+function a1088(x, y) { print(1088); }
+function a1089(x, y) { print(1089); }
+function a1090(x, y) { print(1090); }
+function a1091(x, y) { print(1091); }
+function a1092(x, y) { print(1092); }
+function a1093(x, y) { print(1093); }
+function a1094(x, y) { print(1094); }
+function a1095(x, y) { print(1095); }
+function a1096(x, y) { print(1096); }
+function a1097(x, y) { print(1097); }
+function a1098(x, y) { print(1098); }
+function a1099(x, y) { print(1099); }
+function a1100(x, y) { print(1100); }
+function a1101(x, y) { print(1101); }
+function a1102(x, y) { print(1102); }
+function a1103(x, y) { print(1103); }
+function a1104(x, y) { print(1104); }
+function a1105(x, y) { print(1105); }
+function a1106(x, y) { print(1106); }
+function a1107(x, y) { print(1107); }
+function a1108(x, y) { print(1108); }
+function a1109(x, y) { print(1109); }
+function a1110(x, y) { print(1110); }
+function a1111(x, y) { print(1111); }
+function a1112(x, y) { print(1112); }
+function a1113(x, y) { print(1113); }
+function a1114(x, y) { print(1114); }
+function a1115(x, y) { print(1115); }
+function a1116(x, y) { print(1116); }
+function a1117(x, y) { print(1117); }
+function a1118(x, y) { print(1118); }
+function a1119(x, y) { print(1119); }
+function a1120(x, y) { print(1120); }
+function a1121(x, y) { print(1121); }
+function a1122(x, y) { print(1122); }
+function a1123(x, y) { print(1123); }
+function a1124(x, y) { print(1124); }
+function a1125(x, y) { print(1125); }
+function a1126(x, y) { print(1126); }
+function a1127(x, y) { print(1127); }
+function a1128(x, y) { print(1128); }
+function a1129(x, y) { print(1129); }
+function a1130(x, y) { print(1130); }
+function a1131(x, y) { print(1131); }
+function a1132(x, y) { print(1132); }
+function a1133(x, y) { print(1133); }
+function a1134(x, y) { print(1134); }
+function a1135(x, y) { print(1135); }
+function a1136(x, y) { print(1136); }
+function a1137(x, y) { print(1137); }
+function a1138(x, y) { print(1138); }
+function a1139(x, y) { print(1139); }
+function a1140(x, y) { print(1140); }
+function a1141(x, y) { print(1141); }
+function a1142(x, y) { print(1142); }
+function a1143(x, y) { print(1143); }
+function a1144(x, y) { print(1144); }
+function a1145(x, y) { print(1145); }
+function a1146(x, y) { print(1146); }
+function a1147(x, y) { print(1147); }
+function a1148(x, y) { print(1148); }
+function a1149(x, y) { print(1149); }
+function a1150(x, y) { print(1150); }
+function a1151(x, y) { print(1151); }
+function a1152(x, y) { print(1152); }
+function a1153(x, y) { print(1153); }
+function a1154(x, y) { print(1154); }
+function a1155(x, y) { print(1155); }
+function a1156(x, y) { print(1156); }
+function a1157(x, y) { print(1157); }
+function a1158(x, y) { print(1158); }
+function a1159(x, y) { print(1159); }
+function a1160(x, y) { print(1160); }
+function a1161(x, y) { print(1161); }
+function a1162(x, y) { print(1162); }
+function a1163(x, y) { print(1163); }
+function a1164(x, y) { print(1164); }
+function a1165(x, y) { print(1165); }
+function a1166(x, y) { print(1166); }
+function a1167(x, y) { print(1167); }
+function a1168(x, y) { print(1168); }
+function a1169(x, y) { print(1169); }
+function a1170(x, y) { print(1170); }
+function a1171(x, y) { print(1171); }
+function a1172(x, y) { print(1172); }
+function a1173(x, y) { print(1173); }
+function a1174(x, y) { print(1174); }
+function a1175(x, y) { print(1175); }
+function a1176(x, y) { print(1176); }
+function a1177(x, y) { print(1177); }
+function a1178(x, y) { print(1178); }
+function a1179(x, y) { print(1179); }
+function a1180(x, y) { print(1180); }
+function a1181(x, y) { print(1181); }
+function a1182(x, y) { print(1182); }
+function a1183(x, y) { print(1183); }
+function a1184(x, y) { print(1184); }
+function a1185(x, y) { print(1185); }
+function a1186(x, y) { print(1186); }
+function a1187(x, y) { print(1187); }
+function a1188(x, y) { print(1188); }
+function a1189(x, y) { print(1189); }
+function a1190(x, y) { print(1190); }
+function a1191(x, y) { print(1191); }
+function a1192(x, y) { print(1192); }
+function a1193(x, y) { print(1193); }
+function a1194(x, y) { print(1194); }
+function a1195(x, y) { print(1195); }
+function a1196(x, y) { print(1196); }
+function a1197(x, y) { print(1197); }
+function a1198(x, y) { print(1198); }
+function a1199(x, y) { print(1199); }
+function a1200(x, y) { print(1200); }
+function a1201(x, y) { print(1201); }
+function a1202(x, y) { print(1202); }
+function a1203(x, y) { print(1203); }
+function a1204(x, y) { print(1204); }
+function a1205(x, y) { print(1205); }
+function a1206(x, y) { print(1206); }
+function a1207(x, y) { print(1207); }
+function a1208(x, y) { print(1208); }
+function a1209(x, y) { print(1209); }
+function a1210(x, y) { print(1210); }
+function a1211(x, y) { print(1211); }
+function a1212(x, y) { print(1212); }
+function a1213(x, y) { print(1213); }
+function a1214(x, y) { print(1214); }
+function a1215(x, y) { print(1215); }
+function a1216(x, y) { print(1216); }
+function a1217(x, y) { print(1217); }
+function a1218(x, y) { print(1218); }
+function a1219(x, y) { print(1219); }
+function a1220(x, y) { print(1220); }
+function a1221(x, y) { print(1221); }
+function a1222(x, y) { print(1222); }
+function a1223(x, y) { print(1223); }
+function a1224(x, y) { print(1224); }
+function a1225(x, y) { print(1225); }
+function a1226(x, y) { print(1226); }
+function a1227(x, y) { print(1227); }
+function a1228(x, y) { print(1228); }
+function a1229(x, y) { print(1229); }
+function a1230(x, y) { print(1230); }
+function a1231(x, y) { print(1231); }
+function a1232(x, y) { print(1232); }
+function a1233(x, y) { print(1233); }
+function a1234(x, y) { print(1234); }
+function a1235(x, y) { print(1235); }
+function a1236(x, y) { print(1236); }
+function a1237(x, y) { print(1237); }
+function a1238(x, y) { print(1238); }
+function a1239(x, y) { print(1239); }
+function a1240(x, y) { print(1240); }
+function a1241(x, y) { print(1241); }
+function a1242(x, y) { print(1242); }
+function a1243(x, y) { print(1243); }
+function a1244(x, y) { print(1244); }
+function a1245(x, y) { print(1245); }
+function a1246(x, y) { print(1246); }
+function a1247(x, y) { print(1247); }
+function a1248(x, y) { print(1248); }
+function a1249(x, y) { print(1249); }
+function a1250(x, y) { print(1250); }
+function a1251(x, y) { print(1251); }
+function a1252(x, y) { print(1252); }
+function a1253(x, y) { print(1253); }
+function a1254(x, y) { print(1254); }
+function a1255(x, y) { print(1255); }
+function a1256(x, y) { print(1256); }
+function a1257(x, y) { print(1257); }
+function a1258(x, y) { print(1258); }
+function a1259(x, y) { print(1259); }
+function a1260(x, y) { print(1260); }
+function a1261(x, y) { print(1261); }
+function a1262(x, y) { print(1262); }
+function a1263(x, y) { print(1263); }
+function a1264(x, y) { print(1264); }
+function a1265(x, y) { print(1265); }
+function a1266(x, y) { print(1266); }
+function a1267(x, y) { print(1267); }
+function a1268(x, y) { print(1268); }
+function a1269(x, y) { print(1269); }
+function a1270(x, y) { print(1270); }
+function a1271(x, y) { print(1271); }
+function a1272(x, y) { print(1272); }
+function a1273(x, y) { print(1273); }
+function a1274(x, y) { print(1274); }
+function a1275(x, y) { print(1275); }
+function a1276(x, y) { print(1276); }
+function a1277(x, y) { print(1277); }
+function a1278(x, y) { print(1278); }
+function a1279(x, y) { print(1279); }
+function a1280(x, y) { print(1280); }
+function a1281(x, y) { print(1281); }
+function a1282(x, y) { print(1282); }
+function a1283(x, y) { print(1283); }
+function a1284(x, y) { print(1284); }
+function a1285(x, y) { print(1285); }
+function a1286(x, y) { print(1286); }
+function a1287(x, y) { print(1287); }
+function a1288(x, y) { print(1288); }
+function a1289(x, y) { print(1289); }
+function a1290(x, y) { print(1290); }
+function a1291(x, y) { print(1291); }
+function a1292(x, y) { print(1292); }
+function a1293(x, y) { print(1293); }
+function a1294(x, y) { print(1294); }
+function a1295(x, y) { print(1295); }
+function a1296(x, y) { print(1296); }
+function a1297(x, y) { print(1297); }
+function a1298(x, y) { print(1298); }
+function a1299(x, y) { print(1299); }
+function a1300(x, y) { print(1300); }
+function a1301(x, y) { print(1301); }
+function a1302(x, y) { print(1302); }
+function a1303(x, y) { print(1303); }
+function a1304(x, y) { print(1304); }
+function a1305(x, y) { print(1305); }
+function a1306(x, y) { print(1306); }
+function a1307(x, y) { print(1307); }
+function a1308(x, y) { print(1308); }
+function a1309(x, y) { print(1309); }
+function a1310(x, y) { print(1310); }
+function a1311(x, y) { print(1311); }
+function a1312(x, y) { print(1312); }
+function a1313(x, y) { print(1313); }
+function a1314(x, y) { print(1314); }
+function a1315(x, y) { print(1315); }
+function a1316(x, y) { print(1316); }
+function a1317(x, y) { print(1317); }
+function a1318(x, y) { print(1318); }
+function a1319(x, y) { print(1319); }
+function a1320(x, y) { print(1320); }
+function a1321(x, y) { print(1321); }
+function a1322(x, y) { print(1322); }
+function a1323(x, y) { print(1323); }
+function a1324(x, y) { print(1324); }
+function a1325(x, y) { print(1325); }
+function a1326(x, y) { print(1326); }
+function a1327(x, y) { print(1327); }
+function a1328(x, y) { print(1328); }
+function a1329(x, y) { print(1329); }
+function a1330(x, y) { print(1330); }
+function a1331(x, y) { print(1331); }
+function a1332(x, y) { print(1332); }
+function a1333(x, y) { print(1333); }
+function a1334(x, y) { print(1334); }
+function a1335(x, y) { print(1335); }
+function a1336(x, y) { print(1336); }
+function a1337(x, y) { print(1337); }
+function a1338(x, y) { print(1338); }
+function a1339(x, y) { print(1339); }
+function a1340(x, y) { print(1340); }
+function a1341(x, y) { print(1341); }
+function a1342(x, y) { print(1342); }
+function a1343(x, y) { print(1343); }
+function a1344(x, y) { print(1344); }
+function a1345(x, y) { print(1345); }
+function a1346(x, y) { print(1346); }
+function a1347(x, y) { print(1347); }
+function a1348(x, y) { print(1348); }
+function a1349(x, y) { print(1349); }
+function a1350(x, y) { print(1350); }
+function a1351(x, y) { print(1351); }
+function a1352(x, y) { print(1352); }
+function a1353(x, y) { print(1353); }
+function a1354(x, y) { print(1354); }
+function a1355(x, y) { print(1355); }
+function a1356(x, y) { print(1356); }
+function a1357(x, y) { print(1357); }
+function a1358(x, y) { print(1358); }
+function a1359(x, y) { print(1359); }
+function a1360(x, y) { print(1360); }
+function a1361(x, y) { print(1361); }
+function a1362(x, y) { print(1362); }
+function a1363(x, y) { print(1363); }
+function a1364(x, y) { print(1364); }
+function a1365(x, y) { print(1365); }
+function a1366(x, y) { print(1366); }
+function a1367(x, y) { print(1367); }
+function a1368(x, y) { print(1368); }
+function a1369(x, y) { print(1369); }
+function a1370(x, y) { print(1370); }
+function a1371(x, y) { print(1371); }
+function a1372(x, y) { print(1372); }
+function a1373(x, y) { print(1373); }
+function a1374(x, y) { print(1374); }
+function a1375(x, y) { print(1375); }
+function a1376(x, y) { print(1376); }
+function a1377(x, y) { print(1377); }
+function a1378(x, y) { print(1378); }
+function a1379(x, y) { print(1379); }
+function a1380(x, y) { print(1380); }
+function a1381(x, y) { print(1381); }
+function a1382(x, y) { print(1382); }
+function a1383(x, y) { print(1383); }
+function a1384(x, y) { print(1384); }
+function a1385(x, y) { print(1385); }
+function a1386(x, y) { print(1386); }
+function a1387(x, y) { print(1387); }
+function a1388(x, y) { print(1388); }
+function a1389(x, y) { print(1389); }
+function a1390(x, y) { print(1390); }
+function a1391(x, y) { print(1391); }
+function a1392(x, y) { print(1392); }
+function a1393(x, y) { print(1393); }
+function a1394(x, y) { print(1394); }
+function a1395(x, y) { print(1395); }
+function a1396(x, y) { print(1396); }
+function a1397(x, y) { print(1397); }
+function a1398(x, y) { print(1398); }
+function a1399(x, y) { print(1399); }
+function a1400(x, y) { print(1400); }
+function a1401(x, y) { print(1401); }
+function a1402(x, y) { print(1402); }
+function a1403(x, y) { print(1403); }
+function a1404(x, y) { print(1404); }
+function a1405(x, y) { print(1405); }
+function a1406(x, y) { print(1406); }
+function a1407(x, y) { print(1407); }
+function a1408(x, y) { print(1408); }
+function a1409(x, y) { print(1409); }
+function a1410(x, y) { print(1410); }
+function a1411(x, y) { print(1411); }
+function a1412(x, y) { print(1412); }
+function a1413(x, y) { print(1413); }
+function a1414(x, y) { print(1414); }
+function a1415(x, y) { print(1415); }
+function a1416(x, y) { print(1416); }
+function a1417(x, y) { print(1417); }
+function a1418(x, y) { print(1418); }
+function a1419(x, y) { print(1419); }
+function a1420(x, y) { print(1420); }
+function a1421(x, y) { print(1421); }
+function a1422(x, y) { print(1422); }
+function a1423(x, y) { print(1423); }
+function a1424(x, y) { print(1424); }
+function a1425(x, y) { print(1425); }
+function a1426(x, y) { print(1426); }
+function a1427(x, y) { print(1427); }
+function a1428(x, y) { print(1428); }
+function a1429(x, y) { print(1429); }
+function a1430(x, y) { print(1430); }
+function a1431(x, y) { print(1431); }
+function a1432(x, y) { print(1432); }
+function a1433(x, y) { print(1433); }
+function a1434(x, y) { print(1434); }
+function a1435(x, y) { print(1435); }
+function a1436(x, y) { print(1436); }
+function a1437(x, y) { print(1437); }
+function a1438(x, y) { print(1438); }
+function a1439(x, y) { print(1439); }
+function a1440(x, y) { print(1440); }
+function a1441(x, y) { print(1441); }
+function a1442(x, y) { print(1442); }
+function a1443(x, y) { print(1443); }
+function a1444(x, y) { print(1444); }
+function a1445(x, y) { print(1445); }
+function a1446(x, y) { print(1446); }
+function a1447(x, y) { print(1447); }
+function a1448(x, y) { print(1448); }
+function a1449(x, y) { print(1449); }
+function a1450(x, y) { print(1450); }
+function a1451(x, y) { print(1451); }
+function a1452(x, y) { print(1452); }
+function a1453(x, y) { print(1453); }
+function a1454(x, y) { print(1454); }
+function a1455(x, y) { print(1455); }
+function a1456(x, y) { print(1456); }
+function a1457(x, y) { print(1457); }
+function a1458(x, y) { print(1458); }
+function a1459(x, y) { print(1459); }
+function a1460(x, y) { print(1460); }
+function a1461(x, y) { print(1461); }
+function a1462(x, y) { print(1462); }
+function a1463(x, y) { print(1463); }
+function a1464(x, y) { print(1464); }
+function a1465(x, y) { print(1465); }
+function a1466(x, y) { print(1466); }
+function a1467(x, y) { print(1467); }
+function a1468(x, y) { print(1468); }
+function a1469(x, y) { print(1469); }
+function a1470(x, y) { print(1470); }
+function a1471(x, y) { print(1471); }
+function a1472(x, y) { print(1472); }
+function a1473(x, y) { print(1473); }
+function a1474(x, y) { print(1474); }
+function a1475(x, y) { print(1475); }
+function a1476(x, y) { print(1476); }
+function a1477(x, y) { print(1477); }
+function a1478(x, y) { print(1478); }
+function a1479(x, y) { print(1479); }
+function a1480(x, y) { print(1480); }
+function a1481(x, y) { print(1481); }
+function a1482(x, y) { print(1482); }
+function a1483(x, y) { print(1483); }
+function a1484(x, y) { print(1484); }
+function a1485(x, y) { print(1485); }
+function a1486(x, y) { print(1486); }
+function a1487(x, y) { print(1487); }
+function a1488(x, y) { print(1488); }
+function a1489(x, y) { print(1489); }
+function a1490(x, y) { print(1490); }
+function a1491(x, y) { print(1491); }
+function a1492(x, y) { print(1492); }
+function a1493(x, y) { print(1493); }
+function a1494(x, y) { print(1494); }
+function a1495(x, y) { print(1495); }
+function a1496(x, y) { print(1496); }
+function a1497(x, y) { print(1497); }
+function a1498(x, y) { print(1498); }
+function a1499(x, y) { print(1499); }
+function a1500(x, y) { print(1500); }
+function a1501(x, y) { print(1501); }
+function a1502(x, y) { print(1502); }
+function a1503(x, y) { print(1503); }
+function a1504(x, y) { print(1504); }
+function a1505(x, y) { print(1505); }
+function a1506(x, y) { print(1506); }
+function a1507(x, y) { print(1507); }
+function a1508(x, y) { print(1508); }
+function a1509(x, y) { print(1509); }
+function a1510(x, y) { print(1510); }
+function a1511(x, y) { print(1511); }
+function a1512(x, y) { print(1512); }
+function a1513(x, y) { print(1513); }
+function a1514(x, y) { print(1514); }
+function a1515(x, y) { print(1515); }
+function a1516(x, y) { print(1516); }
+function a1517(x, y) { print(1517); }
+function a1518(x, y) { print(1518); }
+function a1519(x, y) { print(1519); }
+function a1520(x, y) { print(1520); }
+function a1521(x, y) { print(1521); }
+function a1522(x, y) { print(1522); }
+function a1523(x, y) { print(1523); }
+function a1524(x, y) { print(1524); }
+function a1525(x, y) { print(1525); }
+function a1526(x, y) { print(1526); }
+function a1527(x, y) { print(1527); }
+function a1528(x, y) { print(1528); }
+function a1529(x, y) { print(1529); }
+function a1530(x, y) { print(1530); }
+function a1531(x, y) { print(1531); }
+function a1532(x, y) { print(1532); }
+function a1533(x, y) { print(1533); }
+function a1534(x, y) { print(1534); }
+function a1535(x, y) { print(1535); }
+function a1536(x, y) { print(1536); }
+function a1537(x, y) { print(1537); }
+function a1538(x, y) { print(1538); }
+function a1539(x, y) { print(1539); }
+function a1540(x, y) { print(1540); }
+function a1541(x, y) { print(1541); }
+function a1542(x, y) { print(1542); }
+function a1543(x, y) { print(1543); }
+function a1544(x, y) { print(1544); }
+function a1545(x, y) { print(1545); }
+function a1546(x, y) { print(1546); }
+function a1547(x, y) { print(1547); }
+function a1548(x, y) { print(1548); }
+function a1549(x, y) { print(1549); }
+function a1550(x, y) { print(1550); }
+function a1551(x, y) { print(1551); }
+function a1552(x, y) { print(1552); }
+function a1553(x, y) { print(1553); }
+function a1554(x, y) { print(1554); }
+function a1555(x, y) { print(1555); }
+function a1556(x, y) { print(1556); }
+function a1557(x, y) { print(1557); }
+function a1558(x, y) { print(1558); }
+function a1559(x, y) { print(1559); }
+function a1560(x, y) { print(1560); }
+function a1561(x, y) { print(1561); }
+function a1562(x, y) { print(1562); }
+function a1563(x, y) { print(1563); }
+function a1564(x, y) { print(1564); }
+function a1565(x, y) { print(1565); }
+function a1566(x, y) { print(1566); }
+function a1567(x, y) { print(1567); }
+function a1568(x, y) { print(1568); }
+function a1569(x, y) { print(1569); }
+function a1570(x, y) { print(1570); }
+function a1571(x, y) { print(1571); }
+function a1572(x, y) { print(1572); }
+function a1573(x, y) { print(1573); }
+function a1574(x, y) { print(1574); }
+function a1575(x, y) { print(1575); }
+function a1576(x, y) { print(1576); }
+function a1577(x, y) { print(1577); }
+function a1578(x, y) { print(1578); }
+function a1579(x, y) { print(1579); }
+function a1580(x, y) { print(1580); }
+function a1581(x, y) { print(1581); }
+function a1582(x, y) { print(1582); }
+function a1583(x, y) { print(1583); }
+function a1584(x, y) { print(1584); }
+function a1585(x, y) { print(1585); }
+function a1586(x, y) { print(1586); }
+function a1587(x, y) { print(1587); }
+function a1588(x, y) { print(1588); }
+function a1589(x, y) { print(1589); }
+function a1590(x, y) { print(1590); }
+function a1591(x, y) { print(1591); }
+function a1592(x, y) { print(1592); }
+function a1593(x, y) { print(1593); }
+function a1594(x, y) { print(1594); }
+function a1595(x, y) { print(1595); }
+function a1596(x, y) { print(1596); }
+function a1597(x, y) { print(1597); }
+function a1598(x, y) { print(1598); }
+function a1599(x, y) { print(1599); }
+function a1600(x, y) { print(1600); }
+function a1601(x, y) { print(1601); }
+function a1602(x, y) { print(1602); }
+function a1603(x, y) { print(1603); }
+function a1604(x, y) { print(1604); }
+function a1605(x, y) { print(1605); }
+function a1606(x, y) { print(1606); }
+function a1607(x, y) { print(1607); }
+function a1608(x, y) { print(1608); }
+function a1609(x, y) { print(1609); }
+function a1610(x, y) { print(1610); }
+function a1611(x, y) { print(1611); }
+function a1612(x, y) { print(1612); }
+function a1613(x, y) { print(1613); }
+function a1614(x, y) { print(1614); }
+function a1615(x, y) { print(1615); }
+function a1616(x, y) { print(1616); }
+function a1617(x, y) { print(1617); }
+function a1618(x, y) { print(1618); }
+function a1619(x, y) { print(1619); }
+function a1620(x, y) { print(1620); }
+function a1621(x, y) { print(1621); }
+function a1622(x, y) { print(1622); }
+function a1623(x, y) { print(1623); }
+function a1624(x, y) { print(1624); }
+function a1625(x, y) { print(1625); }
+function a1626(x, y) { print(1626); }
+function a1627(x, y) { print(1627); }
+function a1628(x, y) { print(1628); }
+function a1629(x, y) { print(1629); }
+function a1630(x, y) { print(1630); }
+function a1631(x, y) { print(1631); }
+function a1632(x, y) { print(1632); }
+function a1633(x, y) { print(1633); }
+function a1634(x, y) { print(1634); }
+function a1635(x, y) { print(1635); }
+function a1636(x, y) { print(1636); }
+function a1637(x, y) { print(1637); }
+function a1638(x, y) { print(1638); }
+function a1639(x, y) { print(1639); }
+function a1640(x, y) { print(1640); }
+function a1641(x, y) { print(1641); }
+function a1642(x, y) { print(1642); }
+function a1643(x, y) { print(1643); }
+function a1644(x, y) { print(1644); }
+function a1645(x, y) { print(1645); }
+function a1646(x, y) { print(1646); }
+function a1647(x, y) { print(1647); }
+function a1648(x, y) { print(1648); }
+function a1649(x, y) { print(1649); }
+function a1650(x, y) { print(1650); }
+function a1651(x, y) { print(1651); }
+function a1652(x, y) { print(1652); }
+function a1653(x, y) { print(1653); }
+function a1654(x, y) { print(1654); }
+function a1655(x, y) { print(1655); }
+function a1656(x, y) { print(1656); }
+function a1657(x, y) { print(1657); }
+function a1658(x, y) { print(1658); }
+function a1659(x, y) { print(1659); }
+function a1660(x, y) { print(1660); }
+function a1661(x, y) { print(1661); }
+function a1662(x, y) { print(1662); }
+function a1663(x, y) { print(1663); }
+function a1664(x, y) { print(1664); }
+function a1665(x, y) { print(1665); }
+function a1666(x, y) { print(1666); }
+function a1667(x, y) { print(1667); }
+function a1668(x, y) { print(1668); }
+function a1669(x, y) { print(1669); }
+function a1670(x, y) { print(1670); }
+function a1671(x, y) { print(1671); }
+function a1672(x, y) { print(1672); }
+function a1673(x, y) { print(1673); }
+function a1674(x, y) { print(1674); }
+function a1675(x, y) { print(1675); }
+function a1676(x, y) { print(1676); }
+function a1677(x, y) { print(1677); }
+function a1678(x, y) { print(1678); }
+function a1679(x, y) { print(1679); }
+function a1680(x, y) { print(1680); }
+function a1681(x, y) { print(1681); }
+function a1682(x, y) { print(1682); }
+function a1683(x, y) { print(1683); }
+function a1684(x, y) { print(1684); }
+function a1685(x, y) { print(1685); }
+function a1686(x, y) { print(1686); }
+function a1687(x, y) { print(1687); }
+function a1688(x, y) { print(1688); }
+function a1689(x, y) { print(1689); }
+function a1690(x, y) { print(1690); }
+function a1691(x, y) { print(1691); }
+function a1692(x, y) { print(1692); }
+function a1693(x, y) { print(1693); }
+function a1694(x, y) { print(1694); }
+function a1695(x, y) { print(1695); }
+function a1696(x, y) { print(1696); }
+function a1697(x, y) { print(1697); }
+function a1698(x, y) { print(1698); }
+function a1699(x, y) { print(1699); }
+function a1700(x, y) { print(1700); }
+function a1701(x, y) { print(1701); }
+function a1702(x, y) { print(1702); }
+function a1703(x, y) { print(1703); }
+function a1704(x, y) { print(1704); }
+function a1705(x, y) { print(1705); }
+function a1706(x, y) { print(1706); }
+function a1707(x, y) { print(1707); }
+function a1708(x, y) { print(1708); }
+function a1709(x, y) { print(1709); }
+function a1710(x, y) { print(1710); }
+function a1711(x, y) { print(1711); }
+function a1712(x, y) { print(1712); }
+function a1713(x, y) { print(1713); }
+function a1714(x, y) { print(1714); }
+function a1715(x, y) { print(1715); }
+function a1716(x, y) { print(1716); }
+function a1717(x, y) { print(1717); }
+function a1718(x, y) { print(1718); }
+function a1719(x, y) { print(1719); }
+function a1720(x, y) { print(1720); }
+function a1721(x, y) { print(1721); }
+function a1722(x, y) { print(1722); }
+function a1723(x, y) { print(1723); }
+function a1724(x, y) { print(1724); }
+function a1725(x, y) { print(1725); }
+function a1726(x, y) { print(1726); }
+function a1727(x, y) { print(1727); }
+function a1728(x, y) { print(1728); }
+function a1729(x, y) { print(1729); }
+function a1730(x, y) { print(1730); }
+function a1731(x, y) { print(1731); }
+function a1732(x, y) { print(1732); }
+function a1733(x, y) { print(1733); }
+function a1734(x, y) { print(1734); }
+function a1735(x, y) { print(1735); }
+function a1736(x, y) { print(1736); }
+function a1737(x, y) { print(1737); }
+function a1738(x, y) { print(1738); }
+function a1739(x, y) { print(1739); }
+function a1740(x, y) { print(1740); }
+function a1741(x, y) { print(1741); }
+function a1742(x, y) { print(1742); }
+function a1743(x, y) { print(1743); }
+function a1744(x, y) { print(1744); }
+function a1745(x, y) { print(1745); }
+function a1746(x, y) { print(1746); }
+function a1747(x, y) { print(1747); }
+function a1748(x, y) { print(1748); }
+function a1749(x, y) { print(1749); }
+function a1750(x, y) { print(1750); }
+function a1751(x, y) { print(1751); }
+function a1752(x, y) { print(1752); }
+function a1753(x, y) { print(1753); }
+function a1754(x, y) { print(1754); }
+function a1755(x, y) { print(1755); }
+function a1756(x, y) { print(1756); }
+function a1757(x, y) { print(1757); }
+function a1758(x, y) { print(1758); }
+function a1759(x, y) { print(1759); }
+function a1760(x, y) { print(1760); }
+function a1761(x, y) { print(1761); }
+function a1762(x, y) { print(1762); }
+function a1763(x, y) { print(1763); }
+function a1764(x, y) { print(1764); }
+function a1765(x, y) { print(1765); }
+function a1766(x, y) { print(1766); }
+function a1767(x, y) { print(1767); }
+function a1768(x, y) { print(1768); }
+function a1769(x, y) { print(1769); }
+function a1770(x, y) { print(1770); }
+function a1771(x, y) { print(1771); }
+function a1772(x, y) { print(1772); }
+function a1773(x, y) { print(1773); }
+function a1774(x, y) { print(1774); }
+function a1775(x, y) { print(1775); }
+function a1776(x, y) { print(1776); }
+function a1777(x, y) { print(1777); }
+function a1778(x, y) { print(1778); }
+function a1779(x, y) { print(1779); }
+function a1780(x, y) { print(1780); }
+function a1781(x, y) { print(1781); }
+function a1782(x, y) { print(1782); }
+function a1783(x, y) { print(1783); }
+function a1784(x, y) { print(1784); }
+function a1785(x, y) { print(1785); }
+function a1786(x, y) { print(1786); }
+function a1787(x, y) { print(1787); }
+function a1788(x, y) { print(1788); }
+function a1789(x, y) { print(1789); }
+function a1790(x, y) { print(1790); }
+function a1791(x, y) { print(1791); }
+function a1792(x, y) { print(1792); }
+function a1793(x, y) { print(1793); }
+function a1794(x, y) { print(1794); }
+function a1795(x, y) { print(1795); }
+function a1796(x, y) { print(1796); }
+function a1797(x, y) { print(1797); }
+function a1798(x, y) { print(1798); }
+function a1799(x, y) { print(1799); }
+function a1800(x, y) { print(1800); }
+function a1801(x, y) { print(1801); }
+function a1802(x, y) { print(1802); }
+function a1803(x, y) { print(1803); }
+function a1804(x, y) { print(1804); }
+function a1805(x, y) { print(1805); }
+function a1806(x, y) { print(1806); }
+function a1807(x, y) { print(1807); }
+function a1808(x, y) { print(1808); }
+function a1809(x, y) { print(1809); }
+function a1810(x, y) { print(1810); }
+function a1811(x, y) { print(1811); }
+function a1812(x, y) { print(1812); }
+function a1813(x, y) { print(1813); }
+function a1814(x, y) { print(1814); }
+function a1815(x, y) { print(1815); }
+function a1816(x, y) { print(1816); }
+function a1817(x, y) { print(1817); }
+function a1818(x, y) { print(1818); }
+function a1819(x, y) { print(1819); }
+function a1820(x, y) { print(1820); }
+function a1821(x, y) { print(1821); }
+function a1822(x, y) { print(1822); }
+function a1823(x, y) { print(1823); }
+function a1824(x, y) { print(1824); }
+function a1825(x, y) { print(1825); }
+function a1826(x, y) { print(1826); }
+function a1827(x, y) { print(1827); }
+function a1828(x, y) { print(1828); }
+function a1829(x, y) { print(1829); }
+function a1830(x, y) { print(1830); }
+function a1831(x, y) { print(1831); }
+function a1832(x, y) { print(1832); }
+function a1833(x, y) { print(1833); }
+function a1834(x, y) { print(1834); }
+function a1835(x, y) { print(1835); }
+function a1836(x, y) { print(1836); }
+function a1837(x, y) { print(1837); }
+function a1838(x, y) { print(1838); }
+function a1839(x, y) { print(1839); }
+function a1840(x, y) { print(1840); }
+function a1841(x, y) { print(1841); }
+function a1842(x, y) { print(1842); }
+function a1843(x, y) { print(1843); }
+function a1844(x, y) { print(1844); }
+function a1845(x, y) { print(1845); }
+function a1846(x, y) { print(1846); }
+function a1847(x, y) { print(1847); }
+function a1848(x, y) { print(1848); }
+function a1849(x, y) { print(1849); }
+function a1850(x, y) { print(1850); }
+function a1851(x, y) { print(1851); }
+function a1852(x, y) { print(1852); }
+function a1853(x, y) { print(1853); }
+function a1854(x, y) { print(1854); }
+function a1855(x, y) { print(1855); }
+function a1856(x, y) { print(1856); }
+function a1857(x, y) { print(1857); }
+function a1858(x, y) { print(1858); }
+function a1859(x, y) { print(1859); }
+function a1860(x, y) { print(1860); }
+function a1861(x, y) { print(1861); }
+function a1862(x, y) { print(1862); }
+function a1863(x, y) { print(1863); }
+function a1864(x, y) { print(1864); }
+function a1865(x, y) { print(1865); }
+function a1866(x, y) { print(1866); }
+function a1867(x, y) { print(1867); }
+function a1868(x, y) { print(1868); }
+function a1869(x, y) { print(1869); }
+function a1870(x, y) { print(1870); }
+function a1871(x, y) { print(1871); }
+function a1872(x, y) { print(1872); }
+function a1873(x, y) { print(1873); }
+function a1874(x, y) { print(1874); }
+function a1875(x, y) { print(1875); }
+function a1876(x, y) { print(1876); }
+function a1877(x, y) { print(1877); }
+function a1878(x, y) { print(1878); }
+function a1879(x, y) { print(1879); }
+function a1880(x, y) { print(1880); }
+function a1881(x, y) { print(1881); }
+function a1882(x, y) { print(1882); }
+function a1883(x, y) { print(1883); }
+function a1884(x, y) { print(1884); }
+function a1885(x, y) { print(1885); }
+function a1886(x, y) { print(1886); }
+function a1887(x, y) { print(1887); }
+function a1888(x, y) { print(1888); }
+function a1889(x, y) { print(1889); }
+function a1890(x, y) { print(1890); }
+function a1891(x, y) { print(1891); }
+function a1892(x, y) { print(1892); }
+function a1893(x, y) { print(1893); }
+function a1894(x, y) { print(1894); }
+function a1895(x, y) { print(1895); }
+function a1896(x, y) { print(1896); }
+function a1897(x, y) { print(1897); }
+function a1898(x, y) { print(1898); }
+function a1899(x, y) { print(1899); }
+function a1900(x, y) { print(1900); }
+function a1901(x, y) { print(1901); }
+function a1902(x, y) { print(1902); }
+function a1903(x, y) { print(1903); }
+function a1904(x, y) { print(1904); }
+function a1905(x, y) { print(1905); }
+function a1906(x, y) { print(1906); }
+function a1907(x, y) { print(1907); }
+function a1908(x, y) { print(1908); }
+function a1909(x, y) { print(1909); }
+function a1910(x, y) { print(1910); }
+function a1911(x, y) { print(1911); }
+function a1912(x, y) { print(1912); }
+function a1913(x, y) { print(1913); }
+function a1914(x, y) { print(1914); }
+function a1915(x, y) { print(1915); }
+function a1916(x, y) { print(1916); }
+function a1917(x, y) { print(1917); }
+function a1918(x, y) { print(1918); }
+function a1919(x, y) { print(1919); }
+function a1920(x, y) { print(1920); }
+function a1921(x, y) { print(1921); }
+function a1922(x, y) { print(1922); }
+function a1923(x, y) { print(1923); }
+function a1924(x, y) { print(1924); }
+function a1925(x, y) { print(1925); }
+function a1926(x, y) { print(1926); }
+function a1927(x, y) { print(1927); }
+function a1928(x, y) { print(1928); }
+function a1929(x, y) { print(1929); }
+function a1930(x, y) { print(1930); }
+function a1931(x, y) { print(1931); }
+function a1932(x, y) { print(1932); }
+function a1933(x, y) { print(1933); }
+function a1934(x, y) { print(1934); }
+function a1935(x, y) { print(1935); }
+function a1936(x, y) { print(1936); }
+function a1937(x, y) { print(1937); }
+function a1938(x, y) { print(1938); }
+function a1939(x, y) { print(1939); }
+function a1940(x, y) { print(1940); }
+function a1941(x, y) { print(1941); }
+function a1942(x, y) { print(1942); }
+function a1943(x, y) { print(1943); }
+function a1944(x, y) { print(1944); }
+function a1945(x, y) { print(1945); }
+function a1946(x, y) { print(1946); }
+function a1947(x, y) { print(1947); }
+function a1948(x, y) { print(1948); }
+function a1949(x, y) { print(1949); }
+function a1950(x, y) { print(1950); }
+function a1951(x, y) { print(1951); }
+function a1952(x, y) { print(1952); }
+function a1953(x, y) { print(1953); }
+function a1954(x, y) { print(1954); }
+function a1955(x, y) { print(1955); }
+function a1956(x, y) { print(1956); }
+function a1957(x, y) { print(1957); }
+function a1958(x, y) { print(1958); }
+function a1959(x, y) { print(1959); }
+function a1960(x, y) { print(1960); }
+function a1961(x, y) { print(1961); }
+function a1962(x, y) { print(1962); }
+function a1963(x, y) { print(1963); }
+function a1964(x, y) { print(1964); }
+function a1965(x, y) { print(1965); }
+function a1966(x, y) { print(1966); }
+function a1967(x, y) { print(1967); }
+function a1968(x, y) { print(1968); }
+function a1969(x, y) { print(1969); }
+function a1970(x, y) { print(1970); }
+function a1971(x, y) { print(1971); }
+function a1972(x, y) { print(1972); }
+function a1973(x, y) { print(1973); }
+function a1974(x, y) { print(1974); }
+function a1975(x, y) { print(1975); }
+function a1976(x, y) { print(1976); }
+function a1977(x, y) { print(1977); }
+function a1978(x, y) { print(1978); }
+function a1979(x, y) { print(1979); }
+function a1980(x, y) { print(1980); }
+function a1981(x, y) { print(1981); }
+function a1982(x, y) { print(1982); }
+function a1983(x, y) { print(1983); }
+function a1984(x, y) { print(1984); }
+function a1985(x, y) { print(1985); }
+function a1986(x, y) { print(1986); }
+function a1987(x, y) { print(1987); }
+function a1988(x, y) { print(1988); }
+function a1989(x, y) { print(1989); }
+function a1990(x, y) { print(1990); }
+function a1991(x, y) { print(1991); }
+function a1992(x, y) { print(1992); }
+function a1993(x, y) { print(1993); }
+function a1994(x, y) { print(1994); }
+function a1995(x, y) { print(1995); }
+function a1996(x, y) { print(1996); }
+function a1997(x, y) { print(1997); }
+function a1998(x, y) { print(1998); }
+function a1999(x, y) { print(1999); }
diff --git a/nashorn/test/script/basic/NASHORN-424.js b/nashorn/test/script/basic/NASHORN-424.js
new file mode 100644
index 0000000..1bcbe19
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-424.js
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-424: Sparse array cause OutOfMemory exception.
+ *
+ * @test
+ * @run
+ */
+
+if (typeof print === 'undefined') {
+    print = console.log;
+}
+
+var l = -1
+  , LEVEL = { silly   : l++
+            , verbose : l++
+            , info    : l++
+            , "http"  : l++
+            , WARN    : l++
+            , "ERR!"  : l++
+            , ERROR   : "ERR!"
+            , ERR     : "ERR!"
+            , win     : 0x15AAC5
+            , paused  : 0x19790701
+            , silent  : 0xDECAFBAD
+            }
+
+Object.keys(LEVEL).forEach(function (l) {
+  if (typeof LEVEL[l] === "string") LEVEL[l] = LEVEL[LEVEL[l]]
+  else LEVEL[LEVEL[l]] = l
+  LEVEL[l.toLowerCase()] = LEVEL[l]
+  if (l === "silent" || l === "paused") return
+  log[l] = log[l.toLowerCase()] =
+    function (msg, pref, cb) { return log(msg, pref, l, cb) }
+})
+
+function log(msg, pref, level, cb) {
+    print("[" +level + "] " + msg);
+}
+
+Object.keys(LEVEL).forEach(function(l) {
+    log("has value " + LEVEL[l], null, l, null);
+});
+
+
+
+var ar = [ "Hello", "World", 0xDECAFBAD ]
+
+Object.keys(ar).forEach(function(e) {
+    print("ar[" + e + "] = " + ar[e]);
+});
+
+ar[34254236] = 17;
+ar[-1] = "boom";
+ar[0xDECAFBAD] = "ka-boom";
+
+ar[ar[2]] = "bye";
+
+Object.keys(ar).forEach(function(e) {
+    print("ar[" + e + "] = " + ar[e]);
+});
+
diff --git a/nashorn/test/script/basic/NASHORN-424.js.EXPECTED b/nashorn/test/script/basic/NASHORN-424.js.EXPECTED
new file mode 100644
index 0000000..deb69af
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-424.js.EXPECTED
@@ -0,0 +1,33 @@
+[0] has value verbose
+[1] has value info
+[2] has value http
+[3] has value WARN
+[4] has value ERR!
+[1419973] has value win
+[427362049] has value paused
+[3737844653] has value silent
+[silly] has value -1
+[verbose] has value 0
+[info] has value 1
+[http] has value 2
+[WARN] has value 3
+[ERR!] has value 4
+[ERROR] has value 4
+[ERR] has value 4
+[win] has value 1419973
+[paused] has value 427362049
+[silent] has value 3737844653
+[-1] has value silly
+[warn] has value 3
+[err!] has value 4
+[error] has value 4
+[err] has value 4
+ar[0] = Hello
+ar[1] = World
+ar[2] = 3737844653
+ar[0] = Hello
+ar[1] = World
+ar[2] = 3737844653
+ar[34254236] = 17
+ar[3737844653] = bye
+ar[-1] = boom
diff --git a/nashorn/test/script/basic/NASHORN-425.js b/nashorn/test/script/basic/NASHORN-425.js
new file mode 100644
index 0000000..c81aea2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-425.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-425 : can't asynchronously call an immediately-executed function.
+ *
+ * @test
+ * @run
+ */
+
+function callback(cb) {
+  cb()
+}
+
+(function E (ii, ll) {
+  print(ii + "," + ll);
+  if (ii === ll) {
+    return;
+  }
+  callback(function() {
+    return E(ii + 1, ll)
+  });
+})(0, 2)
+
diff --git a/nashorn/test/script/basic/NASHORN-425.js.EXPECTED b/nashorn/test/script/basic/NASHORN-425.js.EXPECTED
new file mode 100644
index 0000000..e0bd006
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-425.js.EXPECTED
@@ -0,0 +1,3 @@
+0,2
+1,2
+2,2
diff --git a/nashorn/test/script/basic/NASHORN-426.js b/nashorn/test/script/basic/NASHORN-426.js
new file mode 100644
index 0000000..2d4ee7e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-426.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-426 : User accessor property modification does not work as expected
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+
+function getter() {
+   return 12;
+}
+
+var setterCalled = false;
+function setter(value) {
+    setterCalled = true;
+}
+
+Object.defineProperty(obj, "foo", {
+    get: getter,
+    configurable: true
+});
+
+Object.defineProperty(obj, "foo", {
+    set: setter
+});
+
+obj.foo = 44;
+if (! setterCalled) {
+    fail("setter not called");
+}
diff --git a/nashorn/test/script/basic/NASHORN-427.js b/nashorn/test/script/basic/NASHORN-427.js
new file mode 100644
index 0000000..0169ce8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-427.js
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-427 : Object.seal and Object.freeze do not work for array objects as expected
+ *
+ * @test
+ * @run
+ */
+
+function checkSeal(arr) {
+    'use strict';
+
+    try {
+        delete arr[0];
+        fail("#1 can delete sealed array element");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#2 TypeError expected, got " + e);
+        }
+    }
+
+    try {
+        arr[arr.length] = 334;
+        fail("#3 can extend sealed array");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#4 TypeError expected, got " + e);
+        }
+    }
+}
+
+function checkFreeze(arr) {
+    'use strict';
+    checkSeal(arr);
+
+    try {
+        arr[arr.length - 1] = 34;
+        fail("#5 can assign to frozen array element");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("#6 TypeError expected, got " + e);
+        }
+    }
+}
+
+
+var arr = [ 24 ];
+Object.seal(arr);
+checkSeal(arr);
+
+var arr2 = [ 42 ];
+Object.freeze(arr2);
+checkFreeze(arr2);
+
diff --git a/nashorn/test/script/basic/NASHORN-428.js b/nashorn/test/script/basic/NASHORN-428.js
new file mode 100644
index 0000000..3d692d1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-428.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-428 : Redefining a non-configurable property with the "same value" is permitted, but -0.0 and +0.0 are not "same value"
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+
+Object.defineProperty(obj, "0", {
+    value: -0,
+    configurable: false
+});
+
+try {
+    Object.defineProperties(obj, {
+        "0": { value: +0 }
+    });
+    fail("#1 expected TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#2 expected TypeError, got " + e);
+    }
+}
+
+// -0 should be fine.. should not throw any TypeError
+Object.defineProperties(obj, {
+    "0": { value: -0 }
+});
+
diff --git a/nashorn/test/script/basic/NASHORN-429.js b/nashorn/test/script/basic/NASHORN-429.js
new file mode 100644
index 0000000..4591705
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-429.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-429 : boolean array element is wrongly converted to number
+ *
+ * @test
+ * @run
+ */
+
+var x = [true];
+
+if (typeof x[0] != 'boolean') {
+    fail("typeof [x] is not boolean it is " + (typeof(x[0])));
+}
+
+if (x[0] !== true) {
+    fail("x[0] !== true, it is " + x[0]);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-432.js b/nashorn/test/script/basic/NASHORN-432.js
new file mode 100644
index 0000000..d14ee73
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-432.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-432 : Array iteration for methods like Array.prototype.forEach should not include elements created by callback
+ *
+ * @test
+ * @run
+ */
+
+var arr = [ 5, 55 ];
+
+arr.forEach(function(kVal, k, O) {
+    if (k == 0) { arr[arr.length] = 10; }
+    if (k === 2) {
+        fail("k === 2 with kVal " + kVal);
+    }
+});
+
diff --git a/nashorn/test/script/basic/NASHORN-433.js b/nashorn/test/script/basic/NASHORN-433.js
new file mode 100644
index 0000000..99b88a8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-433.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-433 : Array iteration for methods like Array.prototype.forEach should compute length before checking whether the callback is a function
+ *
+ * @test
+ * @run
+ */
+
+var obj = { "0": 33, "1": 2 };
+Object.defineProperty(obj, "length", {
+    get: function() { throw new ReferenceError(); }
+});
+
+try {
+    Array.prototype.forEach.call(obj, undefined);
+    fail("should have thrown error");
+} catch (e) {
+    // length should be obtained before checking if callback
+    // is really a function or not. So, we should get error
+    // from length getter rather than TypeError for callback.
+    if (! (e instanceof ReferenceError)) {
+        fail("ReferenceError expected, got " + e);
+    }
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-434.js b/nashorn/test/script/basic/NASHORN-434.js
new file mode 100644
index 0000000..413746905
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-434.js
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-434 : Callbacks to array iterator functions like forEach do not receive proper 'this' object
+ *
+ * @test
+ * @run
+ */
+
+var global = this;
+
+function func(val, idx, obj) {
+    if (this !== global) {
+        fail("#1 callback got 'this' different from global");
+    }
+} 
+
+function strictFunc(val, idx, obj) {
+    'use strict';
+
+    if (this === global) {
+        fail("#2 callback got global as 'this'");
+    }
+
+    if (this !== undefined) {
+        fail("#3 callback 'this' is not undefined");
+    }
+}
+
+var arr = [1];
+arr.forEach(func); 
+arr.forEach(strictFunc);
+
+var callbackThis = {};
+arr.forEach(function() {
+    if (this !== callbackThis) {
+        fail("#4 this !== callbackThis");
+    }
+}, callbackThis);
+
diff --git a/nashorn/test/script/basic/NASHORN-435.js b/nashorn/test/script/basic/NASHORN-435.js
new file mode 100644
index 0000000..15d7bf0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-435.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-435 : Array iterator callback is not called for elements with undefined as value
+ *
+ * @test
+ * @run
+ */
+
+var arr = [ undefined ];
+var reachedCallback = false;
+arr.forEach(function(kVal, k, obj) {
+    reachedCallback = true;
+});
+
+if (! reachedCallback) {
+    fail("callback not called for element of 'undefined' value");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-437.js b/nashorn/test/script/basic/NASHORN-437.js
new file mode 100644
index 0000000..cf23361
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-437.js
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-437 : Array.prototype.map should return an array whose length should be same as input array length
+ *
+ * @test
+ * @run
+ */
+
+var callbackCount = 0;
+
+function func(kVal, k, arr) {
+    arr.length = 2;
+    callbackCount++;
+    return 42;
+}
+
+var arr = [ 1, 2, 3, 4];
+var res = arr.map(func);
+if (res.length !== 4) {
+   fail("map's result does not have 4 elements");
+}
+
+if (callbackCount !== 2) {
+    fail("callback should be called only twice");
+}
+
+if (res[2] !== undefined || res[3] !== undefined) {
+    fail("last two elements are not undefined");
+}
diff --git a/nashorn/test/script/basic/NASHORN-44.js b/nashorn/test/script/basic/NASHORN-44.js
new file mode 100644
index 0000000..10b58c2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-44.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-44: Various loop termination criteria didn't include the for modifier
+ *
+ * @test
+ * @run
+ */
+function loop1() {
+    print("loop1");
+    for (var i = 0; i < 5; i++) { 
+	print(i); 
+	continue;
+    }
+    print(i);
+    print("done1");
+}
+
+function loop2() {
+    print("loop2");
+    for (var i = 0; i < 5; i++) {
+	print(i);
+	break;
+    }
+    print(i);
+    print("done2");
+}
+
+loop1();
+loop2();
+
diff --git a/nashorn/test/script/basic/NASHORN-44.js.EXPECTED b/nashorn/test/script/basic/NASHORN-44.js.EXPECTED
new file mode 100644
index 0000000..00b915f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-44.js.EXPECTED
@@ -0,0 +1,12 @@
+loop1
+0
+1
+2
+3
+4
+5
+done1
+loop2
+0
+0
+done2
diff --git a/nashorn/test/script/basic/NASHORN-441.js b/nashorn/test/script/basic/NASHORN-441.js
new file mode 100644
index 0000000..8c51ea9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-441.js
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-441 : Line numbers are incorrect in exceptions thrown from within a try block
+ *
+ * @test
+ * @run
+ */
+
+try {
+    print("try 1");
+    throw new Error("try 1");
+} catch (e) {
+    print(e, "thrown in line", e.lineNumber);
+} finally {
+    print("finally 1");
+}
+
+try {
+    try {
+        print("try 2");
+        throw new Error("try 2");
+    } finally {
+        print("finally 2");
+    }
+} catch (e) {
+    print(e, "thrown in line", e.lineNumber);
+}
+
+try {
+    print("try 3");
+} finally {
+    print("finally 3");
+}
+
+try {
+    print("try 4");
+    throw new Error("try 4");
+} catch (e if e instanceof String) {
+    print("wrong");
+}catch (e) {
+    print(e, "thrown in line", e.lineNumber);
+} finally {
+    print("finally 4");
+}
+
+try {
+    try {
+        print("try 5");
+        throw new Error("try 5");
+    } catch (e) {
+        print("rethrow 5");
+        throw e;
+    } finally {
+        print("finally 5");
+    }
+} catch (e if e instanceof Error) {
+    print(e, "thrown in line", e.lineNumber);
+}
+
+while (true) {
+    try {
+        print("try 6");
+        break;
+    } finally {
+        print("finally 6");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-441.js.EXPECTED b/nashorn/test/script/basic/NASHORN-441.js.EXPECTED
new file mode 100644
index 0000000..de9ea22
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-441.js.EXPECTED
@@ -0,0 +1,17 @@
+try 1
+Error: try 1 thrown in line 33
+finally 1
+try 2
+finally 2
+Error: try 2 thrown in line 43
+try 3
+finally 3
+try 4
+Error: try 4 thrown in line 59
+finally 4
+try 5
+rethrow 5
+finally 5
+Error: try 5 thrown in line 71
+try 6
+finally 6
diff --git a/nashorn/test/script/basic/NASHORN-442.js b/nashorn/test/script/basic/NASHORN-442.js
new file mode 100644
index 0000000..9a5128a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-442.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-442 : for loop for object properties repeats property names.
+ *
+ * @test
+ * @run
+ */
+
+var proto = { foo : 33 };
+var obj = Object.create(proto);
+obj.foo = 'hello';
+
+var fooSeen = false;
+var count = 0;
+for (i in obj) {
+    count++;
+    if (i === "foo") {
+        if (fooSeen) {
+            fail("foo repeated in for loop");
+        }
+        fooSeen = true;
+    }
+}
+
+if (count !== 1) {
+    fail("only one property expected in for loop");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-443.js b/nashorn/test/script/basic/NASHORN-443.js
new file mode 100644
index 0000000..ab91820
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-443.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-443 : Array.prototype.lastIndexOf does not handle the cases where 'fromIndex' is undefined
+ *
+ * @test
+ * @run
+ */
+
+var arr = [ 'hello', 'world', 'hello', undefined ];
+
+if (arr.lastIndexOf('hello') !== 2) {
+    fail("#1 lastIndexOf fails when fromIndex is not passed");
+}
+
+if (arr.lastIndexOf('world', undefined) !== -1) {
+    fail("#2 lastIndexOf fails when fromIndex is undefined");
+}
+
+if (arr.lastIndexOf('hello', undefined) !== 0) {
+    fail("#3 lastIndexOf fails when fromIndex is undefined");
+}
+
+if (arr.lastIndexOf() !== 3) {
+    fail("#4 lastIndexOf fails when searchElement is not passed");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-444.js b/nashorn/test/script/basic/NASHORN-444.js
new file mode 100644
index 0000000..27811af
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-444.js
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-444 : regex returns different result on second invocation.
+ *
+ * @test
+ * @run
+ */
+
+var formatRegExp = /%[sdj%]/g;
+var format = function(f) {
+  if (typeof f !== 'string') {
+    var objects = [];
+    for (var i = 0; i < arguments.length; i++) {
+      objects.push(inspect(arguments[i]));
+    }
+    return objects.join(' ');
+  }
+
+  var i = 1;
+  var args = arguments;
+  var len = args.length;
+  if (formatRegExp.lastIndex !== 0) throw "expected lastIndex === 0, actual: " + formatRegExp.lastIndex;
+  var str = String(f).replace(formatRegExp, function(x) {
+    if (x === '%%') return '%';
+    if (i >= len) return x;
+    switch (x) {
+      case '%s': return String(args[i++]);
+      case '%d': return Number(args[i++]);
+      case '%j': return JSON.stringify(args[i++]);
+      default:
+        return x;
+    }
+  });
+  print(i + ' '+len);
+  if (formatRegExp.lastIndex !== 0) throw "expected lastIndex === 0, actual: " + formatRegExp.lastIndex;
+  return str;
+};
+
+var obj = function() {
+    return {
+        a: 1,
+        b: 2
+    };
+};
+
+var o = obj();
+print(format('obj %j', o));
+print(format('obj %j', o));
+
diff --git a/nashorn/test/script/basic/NASHORN-444.js.EXPECTED b/nashorn/test/script/basic/NASHORN-444.js.EXPECTED
new file mode 100644
index 0000000..7025f66
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-444.js.EXPECTED
@@ -0,0 +1,4 @@
+2 2
+obj {"a":1,"b":2}
+2 2
+obj {"a":1,"b":2}
diff --git a/nashorn/test/script/basic/NASHORN-445.js b/nashorn/test/script/basic/NASHORN-445.js
new file mode 100644
index 0000000..89a1b72
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-445.js
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-445 : Array.prototype.map gets confused by index user accessor properties inherited from Array.prototype
+ *
+ * @test
+ * @run
+ */
+
+var arr = [1, 2, 3];
+
+Object.defineProperty(Array.prototype, "0", {
+    get: function () {
+        return "hello"
+    },
+    set: function(x) {
+        print("setter for '0' called with " + x);
+    },
+    enumerable: true
+});
+
+var res = arr.map(function(kVal, k, arr) {
+    return kVal*2;
+});
+
+if (res.length !== arr.length) {
+    fail("map result array is not of right length");
+}
+
+for (var i in res) {
+    if (res[i] !== 2*arr[i]) {
+        fail("map res[" + i + "] does not have right value");
+    }
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-446.js b/nashorn/test/script/basic/NASHORN-446.js
new file mode 100644
index 0000000..f8ba093
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-446.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-446 : Should be able to set full year using Date.prototype.setFullYear on invalid Date objects
+ *
+ * @test
+ * @run
+ */
+
+var oldFullYear = Date.prototype.getFullYear();
+try {
+    Date.prototype.setFullYear(2012);
+    if (Date.prototype.getFullYear() !== 2012) {
+        fail("Can't set full year on Date.prototype");
+    }
+} finally {
+    Date.prototype.setFullYear(oldFullYear);
+}
+
+var d = new Date(NaN);
+d.setFullYear(1972);
+if (d.getFullYear() !== 1972) {
+    fail("Can't set full year on an invalid date");
+}
diff --git a/nashorn/test/script/basic/NASHORN-447.js b/nashorn/test/script/basic/NASHORN-447.js
new file mode 100644
index 0000000..e817c7f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-447.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-447 : Arity of bound function is wrong when more than required number of arguments are passed
+ *
+ * @test
+ * @run
+ */
+
+function func(x, y) {
+    return x + y;
+}
+
+var s = func.bind(this, 23, 44);
+if (s.length !== 0) {
+    fail("#1 bound function has wrong arity: " + s.length);
+}
+
+// supply additional arguments
+var s = func.bind(this, 23, 44, 55);
+// arity should still be zero..
+if (s.length !== 0) {
+    fail("#2 bound function has wrong arity: " + s.length);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-448.js b/nashorn/test/script/basic/NASHORN-448.js
new file mode 100644
index 0000000..a79adf9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-448.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-448 : VerifyError with uninitialized variable.
+ *
+ * @test
+ * @run
+ */
+
+function a() { var x = x; }
+function b() { var i = 0; return i + 1; }
+function c() { var y = (function(){ return y;})(); }
+
+function test(m) {
+  var msg = typeof m.msg === "string" ? m.msg
+            : msg ? msg.stack || msg.message
+            : util.inspect(m.msg, 0, 4)
+}
+
+var f = function() {
+    var g = g || 0;
+};
+
diff --git a/nashorn/test/script/basic/NASHORN-449.js b/nashorn/test/script/basic/NASHORN-449.js
new file mode 100644
index 0000000..ef7171a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-449.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-449 :  defineProperty on arguments object does not work element in question was deleted earlier
+ * 
+ * @test
+ * @run
+ */
+
+
+function func() {
+    delete arguments[0];
+    return arguments;
+}
+
+var a = func(334, 55, 33);
+var getterCalled = false;
+Object.defineProperty(a, "0", {
+  get: function() { getterCalled = true; return 22; }
+});
+
+if (a[0] === undefined) {
+    fail("a[0] is undefined");
+}
+
+if (! getterCalled) {
+    fail("getter not called");
+}
+
+if (a[0] !== 22) {
+    fail("a[0] !== 22");
+}
diff --git a/nashorn/test/script/basic/NASHORN-449.js.EXPECTED b/nashorn/test/script/basic/NASHORN-449.js.EXPECTED
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-449.js.EXPECTED
diff --git a/nashorn/test/script/basic/NASHORN-45.js b/nashorn/test/script/basic/NASHORN-45.js
new file mode 100644
index 0000000..29105b7
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-45.js
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-45 :  StackOverflowError when toString of Number.prototype is assigned to a Date object
+ *
+ * @test
+ * @run
+ */
+
+var d  = new Date(0);
+d.toString = Number.prototype.toString;
+try {
+    print(d.toString());
+} catch (e) {
+    print(e);
+}
+
+var s = new String("hello");
+s.toString = Number.prototype.toString;
+try {
+    print(s.toString());
+} catch (e) {
+    print(e);
+}
+
+var b = new Boolean(false);
+b.toString = Number.prototype.toString;
+try {
+    print(b.toString());
+} catch (e) {
+    print(e);
+}
+
+var obj = {};
+obj.toString = Number.prototype.toString;
+try {
+    print(obj.toString());
+} catch (e) {
+    print(e);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-45.js.EXPECTED b/nashorn/test/script/basic/NASHORN-45.js.EXPECTED
new file mode 100644
index 0000000..7dba10a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-45.js.EXPECTED
@@ -0,0 +1,4 @@
+TypeError: [Date 1970-01-01T00:00:00.000Z] is not a Number
+TypeError: [String hello] is not a Number
+TypeError: [Boolean false] is not a Number
+TypeError: [object Object] is not a Number
diff --git a/nashorn/test/script/basic/NASHORN-450.js b/nashorn/test/script/basic/NASHORN-450.js
new file mode 100644
index 0000000..eb3776d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-450.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-450 : User setter for arguments element does not work when an element in question was deleted earlier
+ *
+ * @test
+ * @run
+ */
+
+(function() {
+    var setterCalled = false;
+    delete arguments[0];
+
+    Object.defineProperty(arguments, "0",
+        { get: function() { return 32; },
+          set: function(x) { setterCalled = true; }
+        }
+    );
+
+    arguments[0] = 33;
+
+    if (! setterCalled) {
+        fail("setter not called for arguments[0]");
+    }
+
+})(33);
diff --git a/nashorn/test/script/basic/NASHORN-452.js b/nashorn/test/script/basic/NASHORN-452.js
new file mode 100644
index 0000000..aa2ef5c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-452.js
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-452 : nashorn is able to redefine a global declared variable
+ *
+ * @test
+ * @run
+ */
+
+var env = {};
+try {
+    Object.defineProperty(this, 'env', {
+        get: function() {}
+    });
+    fail("#1 should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#2 TypeError expected, got " + e);
+    }
+}
+
+var desc = Object.getOwnPropertyDescriptor(this, 'env');
+if (desc.configurable) {
+    fail("#3 global var 'env' is configurable");
+}
+
+(function (x) {
+    if (delete x) {
+        fail("#4 can delete function argument");
+    }
+})(3);
+
+(function (x) {
+    // use of 'with'
+    with ({ foo: 2 }) {
+        if (delete x) {
+            fail("#5 can delete function argument");
+        }
+    }
+})(4);
+
+(function (x, y) {
+    // use of 'arguments'
+    var arg = arguments;
+    if (delete x || delete y) {
+        fail("#6 can delete function argument");
+    }
+})(5);
+
+(function (x) {
+    // use of 'eval'
+    eval("x");
+
+    if (delete x) {
+        fail("#7 can delete function argument");
+    }
+})('hello');
+
diff --git a/nashorn/test/script/basic/NASHORN-459.js b/nashorn/test/script/basic/NASHORN-459.js
new file mode 100644
index 0000000..6d9258e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-459.js
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-459 : Cannot delete configurable accessor properties of global object
+ *
+ * @test
+ * @run
+ */
+
+var global = this;
+Object.defineProperty(global, "0", {
+    get: function() { return 43; },
+    set: function(x) { print('in setter ' + x); },
+    configurable: true
+});
+
+if ((delete global[0]) !== true) {
+    fail("can not delete configurable property '0' of global");
+}
+
+Object.defineProperty(global, "foo", {
+    get: function() { return 33; },
+    set: function(x) { print('setter foo'); },
+    configurable: true
+});
+
+if ((delete global.foo) !== true) {
+    fail("can not delete configurable property 'foo' of global");
+}
+
+Object.defineProperty(global, "1", {
+    get: function() { return 1 },
+    set: undefined,
+    configurable: true
+});
+
+Object.defineProperty(global, "1", {
+    get: function() { return 11 },
+    set: undefined
+});
+
+if ((delete global[1]) !== true) {
+    fail("can not delete configurable property '1' of global");
+}
+
+
diff --git a/nashorn/test/script/basic/NASHORN-46.js b/nashorn/test/script/basic/NASHORN-46.js
new file mode 100644
index 0000000..a23a2a0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-46.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-46 :  'with' statement can not have 'null' as scope object.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    with(null) {
+        print("TypeError expected!!");
+    }
+} catch (e) {
+    print(e);
+}
+
+try {
+    with(undefined) {
+        print("TypeError expected!!");
+    }
+} catch (e) {
+    print(e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-46.js.EXPECTED b/nashorn/test/script/basic/NASHORN-46.js.EXPECTED
new file mode 100644
index 0000000..386f260
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-46.js.EXPECTED
@@ -0,0 +1,2 @@
+TypeError: Cannot apply "with" to null
+TypeError: Cannot apply "with" to undefined
diff --git a/nashorn/test/script/basic/NASHORN-462.js b/nashorn/test/script/basic/NASHORN-462.js
new file mode 100644
index 0000000..6cfbb83
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-462.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-462 : inherited non-writable properties cannot be overriden.
+ *
+ * @test
+ * @run
+ */
+
+function Foo() {};
+Object.defineProperty(Foo.prototype, "bar", { value: 19 });
+
+var fooObj = new Foo(); 
+fooObj.bar = "overridden"; 
+if (fooObj.hasOwnProperty("bar")) {
+    fail("inherited non-writable property can be overridden");
+}
+
+if (fooObj.bar !== 19) {
+    fail("inherited non-writable property value changed");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-463.js b/nashorn/test/script/basic/NASHORN-463.js
new file mode 100644
index 0000000..41ca3fb
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-463.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-463 : array length property is incorrect when an element is set at large index.
+ *
+ * @test
+ * @run
+ */
+
+var arr = [];
+//length is the max value of Uint type
+arr[Math.pow(2, 32) - 2] = true;
+if (arr.length !== 4294967295) {
+    fail("wrong array length : " + arr.length);
+}
diff --git a/nashorn/test/script/basic/NASHORN-468.js b/nashorn/test/script/basic/NASHORN-468.js
new file mode 100644
index 0000000..10a36f9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-468.js
@@ -0,0 +1,3035 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-468 : "Class file too large" error with dojo library
+ *
+ * @test
+ * @run
+ */
+
+// simple machine generated script with 3000 global vars.
+// results about 40000 constant pool entries.
+
+var var0 = 0
+var var1 = 1
+var var2 = 2
+var var3 = 3
+var var4 = 4
+var var5 = 5
+var var6 = 6
+var var7 = 7
+var var8 = 8
+var var9 = 9
+var var10 = 10
+var var11 = 11
+var var12 = 12
+var var13 = 13
+var var14 = 14
+var var15 = 15
+var var16 = 16
+var var17 = 17
+var var18 = 18
+var var19 = 19
+var var20 = 20
+var var21 = 21
+var var22 = 22
+var var23 = 23
+var var24 = 24
+var var25 = 25
+var var26 = 26
+var var27 = 27
+var var28 = 28
+var var29 = 29
+var var30 = 30
+var var31 = 31
+var var32 = 32
+var var33 = 33
+var var34 = 34
+var var35 = 35
+var var36 = 36
+var var37 = 37
+var var38 = 38
+var var39 = 39
+var var40 = 40
+var var41 = 41
+var var42 = 42
+var var43 = 43
+var var44 = 44
+var var45 = 45
+var var46 = 46
+var var47 = 47
+var var48 = 48
+var var49 = 49
+var var50 = 50
+var var51 = 51
+var var52 = 52
+var var53 = 53
+var var54 = 54
+var var55 = 55
+var var56 = 56
+var var57 = 57
+var var58 = 58
+var var59 = 59
+var var60 = 60
+var var61 = 61
+var var62 = 62
+var var63 = 63
+var var64 = 64
+var var65 = 65
+var var66 = 66
+var var67 = 67
+var var68 = 68
+var var69 = 69
+var var70 = 70
+var var71 = 71
+var var72 = 72
+var var73 = 73
+var var74 = 74
+var var75 = 75
+var var76 = 76
+var var77 = 77
+var var78 = 78
+var var79 = 79
+var var80 = 80
+var var81 = 81
+var var82 = 82
+var var83 = 83
+var var84 = 84
+var var85 = 85
+var var86 = 86
+var var87 = 87
+var var88 = 88
+var var89 = 89
+var var90 = 90
+var var91 = 91
+var var92 = 92
+var var93 = 93
+var var94 = 94
+var var95 = 95
+var var96 = 96
+var var97 = 97
+var var98 = 98
+var var99 = 99
+var var100 = 100
+var var101 = 101
+var var102 = 102
+var var103 = 103
+var var104 = 104
+var var105 = 105
+var var106 = 106
+var var107 = 107
+var var108 = 108
+var var109 = 109
+var var110 = 110
+var var111 = 111
+var var112 = 112
+var var113 = 113
+var var114 = 114
+var var115 = 115
+var var116 = 116
+var var117 = 117
+var var118 = 118
+var var119 = 119
+var var120 = 120
+var var121 = 121
+var var122 = 122
+var var123 = 123
+var var124 = 124
+var var125 = 125
+var var126 = 126
+var var127 = 127
+var var128 = 128
+var var129 = 129
+var var130 = 130
+var var131 = 131
+var var132 = 132
+var var133 = 133
+var var134 = 134
+var var135 = 135
+var var136 = 136
+var var137 = 137
+var var138 = 138
+var var139 = 139
+var var140 = 140
+var var141 = 141
+var var142 = 142
+var var143 = 143
+var var144 = 144
+var var145 = 145
+var var146 = 146
+var var147 = 147
+var var148 = 148
+var var149 = 149
+var var150 = 150
+var var151 = 151
+var var152 = 152
+var var153 = 153
+var var154 = 154
+var var155 = 155
+var var156 = 156
+var var157 = 157
+var var158 = 158
+var var159 = 159
+var var160 = 160
+var var161 = 161
+var var162 = 162
+var var163 = 163
+var var164 = 164
+var var165 = 165
+var var166 = 166
+var var167 = 167
+var var168 = 168
+var var169 = 169
+var var170 = 170
+var var171 = 171
+var var172 = 172
+var var173 = 173
+var var174 = 174
+var var175 = 175
+var var176 = 176
+var var177 = 177
+var var178 = 178
+var var179 = 179
+var var180 = 180
+var var181 = 181
+var var182 = 182
+var var183 = 183
+var var184 = 184
+var var185 = 185
+var var186 = 186
+var var187 = 187
+var var188 = 188
+var var189 = 189
+var var190 = 190
+var var191 = 191
+var var192 = 192
+var var193 = 193
+var var194 = 194
+var var195 = 195
+var var196 = 196
+var var197 = 197
+var var198 = 198
+var var199 = 199
+var var200 = 200
+var var201 = 201
+var var202 = 202
+var var203 = 203
+var var204 = 204
+var var205 = 205
+var var206 = 206
+var var207 = 207
+var var208 = 208
+var var209 = 209
+var var210 = 210
+var var211 = 211
+var var212 = 212
+var var213 = 213
+var var214 = 214
+var var215 = 215
+var var216 = 216
+var var217 = 217
+var var218 = 218
+var var219 = 219
+var var220 = 220
+var var221 = 221
+var var222 = 222
+var var223 = 223
+var var224 = 224
+var var225 = 225
+var var226 = 226
+var var227 = 227
+var var228 = 228
+var var229 = 229
+var var230 = 230
+var var231 = 231
+var var232 = 232
+var var233 = 233
+var var234 = 234
+var var235 = 235
+var var236 = 236
+var var237 = 237
+var var238 = 238
+var var239 = 239
+var var240 = 240
+var var241 = 241
+var var242 = 242
+var var243 = 243
+var var244 = 244
+var var245 = 245
+var var246 = 246
+var var247 = 247
+var var248 = 248
+var var249 = 249
+var var250 = 250
+var var251 = 251
+var var252 = 252
+var var253 = 253
+var var254 = 254
+var var255 = 255
+var var256 = 256
+var var257 = 257
+var var258 = 258
+var var259 = 259
+var var260 = 260
+var var261 = 261
+var var262 = 262
+var var263 = 263
+var var264 = 264
+var var265 = 265
+var var266 = 266
+var var267 = 267
+var var268 = 268
+var var269 = 269
+var var270 = 270
+var var271 = 271
+var var272 = 272
+var var273 = 273
+var var274 = 274
+var var275 = 275
+var var276 = 276
+var var277 = 277
+var var278 = 278
+var var279 = 279
+var var280 = 280
+var var281 = 281
+var var282 = 282
+var var283 = 283
+var var284 = 284
+var var285 = 285
+var var286 = 286
+var var287 = 287
+var var288 = 288
+var var289 = 289
+var var290 = 290
+var var291 = 291
+var var292 = 292
+var var293 = 293
+var var294 = 294
+var var295 = 295
+var var296 = 296
+var var297 = 297
+var var298 = 298
+var var299 = 299
+var var300 = 300
+var var301 = 301
+var var302 = 302
+var var303 = 303
+var var304 = 304
+var var305 = 305
+var var306 = 306
+var var307 = 307
+var var308 = 308
+var var309 = 309
+var var310 = 310
+var var311 = 311
+var var312 = 312
+var var313 = 313
+var var314 = 314
+var var315 = 315
+var var316 = 316
+var var317 = 317
+var var318 = 318
+var var319 = 319
+var var320 = 320
+var var321 = 321
+var var322 = 322
+var var323 = 323
+var var324 = 324
+var var325 = 325
+var var326 = 326
+var var327 = 327
+var var328 = 328
+var var329 = 329
+var var330 = 330
+var var331 = 331
+var var332 = 332
+var var333 = 333
+var var334 = 334
+var var335 = 335
+var var336 = 336
+var var337 = 337
+var var338 = 338
+var var339 = 339
+var var340 = 340
+var var341 = 341
+var var342 = 342
+var var343 = 343
+var var344 = 344
+var var345 = 345
+var var346 = 346
+var var347 = 347
+var var348 = 348
+var var349 = 349
+var var350 = 350
+var var351 = 351
+var var352 = 352
+var var353 = 353
+var var354 = 354
+var var355 = 355
+var var356 = 356
+var var357 = 357
+var var358 = 358
+var var359 = 359
+var var360 = 360
+var var361 = 361
+var var362 = 362
+var var363 = 363
+var var364 = 364
+var var365 = 365
+var var366 = 366
+var var367 = 367
+var var368 = 368
+var var369 = 369
+var var370 = 370
+var var371 = 371
+var var372 = 372
+var var373 = 373
+var var374 = 374
+var var375 = 375
+var var376 = 376
+var var377 = 377
+var var378 = 378
+var var379 = 379
+var var380 = 380
+var var381 = 381
+var var382 = 382
+var var383 = 383
+var var384 = 384
+var var385 = 385
+var var386 = 386
+var var387 = 387
+var var388 = 388
+var var389 = 389
+var var390 = 390
+var var391 = 391
+var var392 = 392
+var var393 = 393
+var var394 = 394
+var var395 = 395
+var var396 = 396
+var var397 = 397
+var var398 = 398
+var var399 = 399
+var var400 = 400
+var var401 = 401
+var var402 = 402
+var var403 = 403
+var var404 = 404
+var var405 = 405
+var var406 = 406
+var var407 = 407
+var var408 = 408
+var var409 = 409
+var var410 = 410
+var var411 = 411
+var var412 = 412
+var var413 = 413
+var var414 = 414
+var var415 = 415
+var var416 = 416
+var var417 = 417
+var var418 = 418
+var var419 = 419
+var var420 = 420
+var var421 = 421
+var var422 = 422
+var var423 = 423
+var var424 = 424
+var var425 = 425
+var var426 = 426
+var var427 = 427
+var var428 = 428
+var var429 = 429
+var var430 = 430
+var var431 = 431
+var var432 = 432
+var var433 = 433
+var var434 = 434
+var var435 = 435
+var var436 = 436
+var var437 = 437
+var var438 = 438
+var var439 = 439
+var var440 = 440
+var var441 = 441
+var var442 = 442
+var var443 = 443
+var var444 = 444
+var var445 = 445
+var var446 = 446
+var var447 = 447
+var var448 = 448
+var var449 = 449
+var var450 = 450
+var var451 = 451
+var var452 = 452
+var var453 = 453
+var var454 = 454
+var var455 = 455
+var var456 = 456
+var var457 = 457
+var var458 = 458
+var var459 = 459
+var var460 = 460
+var var461 = 461
+var var462 = 462
+var var463 = 463
+var var464 = 464
+var var465 = 465
+var var466 = 466
+var var467 = 467
+var var468 = 468
+var var469 = 469
+var var470 = 470
+var var471 = 471
+var var472 = 472
+var var473 = 473
+var var474 = 474
+var var475 = 475
+var var476 = 476
+var var477 = 477
+var var478 = 478
+var var479 = 479
+var var480 = 480
+var var481 = 481
+var var482 = 482
+var var483 = 483
+var var484 = 484
+var var485 = 485
+var var486 = 486
+var var487 = 487
+var var488 = 488
+var var489 = 489
+var var490 = 490
+var var491 = 491
+var var492 = 492
+var var493 = 493
+var var494 = 494
+var var495 = 495
+var var496 = 496
+var var497 = 497
+var var498 = 498
+var var499 = 499
+var var500 = 500
+var var501 = 501
+var var502 = 502
+var var503 = 503
+var var504 = 504
+var var505 = 505
+var var506 = 506
+var var507 = 507
+var var508 = 508
+var var509 = 509
+var var510 = 510
+var var511 = 511
+var var512 = 512
+var var513 = 513
+var var514 = 514
+var var515 = 515
+var var516 = 516
+var var517 = 517
+var var518 = 518
+var var519 = 519
+var var520 = 520
+var var521 = 521
+var var522 = 522
+var var523 = 523
+var var524 = 524
+var var525 = 525
+var var526 = 526
+var var527 = 527
+var var528 = 528
+var var529 = 529
+var var530 = 530
+var var531 = 531
+var var532 = 532
+var var533 = 533
+var var534 = 534
+var var535 = 535
+var var536 = 536
+var var537 = 537
+var var538 = 538
+var var539 = 539
+var var540 = 540
+var var541 = 541
+var var542 = 542
+var var543 = 543
+var var544 = 544
+var var545 = 545
+var var546 = 546
+var var547 = 547
+var var548 = 548
+var var549 = 549
+var var550 = 550
+var var551 = 551
+var var552 = 552
+var var553 = 553
+var var554 = 554
+var var555 = 555
+var var556 = 556
+var var557 = 557
+var var558 = 558
+var var559 = 559
+var var560 = 560
+var var561 = 561
+var var562 = 562
+var var563 = 563
+var var564 = 564
+var var565 = 565
+var var566 = 566
+var var567 = 567
+var var568 = 568
+var var569 = 569
+var var570 = 570
+var var571 = 571
+var var572 = 572
+var var573 = 573
+var var574 = 574
+var var575 = 575
+var var576 = 576
+var var577 = 577
+var var578 = 578
+var var579 = 579
+var var580 = 580
+var var581 = 581
+var var582 = 582
+var var583 = 583
+var var584 = 584
+var var585 = 585
+var var586 = 586
+var var587 = 587
+var var588 = 588
+var var589 = 589
+var var590 = 590
+var var591 = 591
+var var592 = 592
+var var593 = 593
+var var594 = 594
+var var595 = 595
+var var596 = 596
+var var597 = 597
+var var598 = 598
+var var599 = 599
+var var600 = 600
+var var601 = 601
+var var602 = 602
+var var603 = 603
+var var604 = 604
+var var605 = 605
+var var606 = 606
+var var607 = 607
+var var608 = 608
+var var609 = 609
+var var610 = 610
+var var611 = 611
+var var612 = 612
+var var613 = 613
+var var614 = 614
+var var615 = 615
+var var616 = 616
+var var617 = 617
+var var618 = 618
+var var619 = 619
+var var620 = 620
+var var621 = 621
+var var622 = 622
+var var623 = 623
+var var624 = 624
+var var625 = 625
+var var626 = 626
+var var627 = 627
+var var628 = 628
+var var629 = 629
+var var630 = 630
+var var631 = 631
+var var632 = 632
+var var633 = 633
+var var634 = 634
+var var635 = 635
+var var636 = 636
+var var637 = 637
+var var638 = 638
+var var639 = 639
+var var640 = 640
+var var641 = 641
+var var642 = 642
+var var643 = 643
+var var644 = 644
+var var645 = 645
+var var646 = 646
+var var647 = 647
+var var648 = 648
+var var649 = 649
+var var650 = 650
+var var651 = 651
+var var652 = 652
+var var653 = 653
+var var654 = 654
+var var655 = 655
+var var656 = 656
+var var657 = 657
+var var658 = 658
+var var659 = 659
+var var660 = 660
+var var661 = 661
+var var662 = 662
+var var663 = 663
+var var664 = 664
+var var665 = 665
+var var666 = 666
+var var667 = 667
+var var668 = 668
+var var669 = 669
+var var670 = 670
+var var671 = 671
+var var672 = 672
+var var673 = 673
+var var674 = 674
+var var675 = 675
+var var676 = 676
+var var677 = 677
+var var678 = 678
+var var679 = 679
+var var680 = 680
+var var681 = 681
+var var682 = 682
+var var683 = 683
+var var684 = 684
+var var685 = 685
+var var686 = 686
+var var687 = 687
+var var688 = 688
+var var689 = 689
+var var690 = 690
+var var691 = 691
+var var692 = 692
+var var693 = 693
+var var694 = 694
+var var695 = 695
+var var696 = 696
+var var697 = 697
+var var698 = 698
+var var699 = 699
+var var700 = 700
+var var701 = 701
+var var702 = 702
+var var703 = 703
+var var704 = 704
+var var705 = 705
+var var706 = 706
+var var707 = 707
+var var708 = 708
+var var709 = 709
+var var710 = 710
+var var711 = 711
+var var712 = 712
+var var713 = 713
+var var714 = 714
+var var715 = 715
+var var716 = 716
+var var717 = 717
+var var718 = 718
+var var719 = 719
+var var720 = 720
+var var721 = 721
+var var722 = 722
+var var723 = 723
+var var724 = 724
+var var725 = 725
+var var726 = 726
+var var727 = 727
+var var728 = 728
+var var729 = 729
+var var730 = 730
+var var731 = 731
+var var732 = 732
+var var733 = 733
+var var734 = 734
+var var735 = 735
+var var736 = 736
+var var737 = 737
+var var738 = 738
+var var739 = 739
+var var740 = 740
+var var741 = 741
+var var742 = 742
+var var743 = 743
+var var744 = 744
+var var745 = 745
+var var746 = 746
+var var747 = 747
+var var748 = 748
+var var749 = 749
+var var750 = 750
+var var751 = 751
+var var752 = 752
+var var753 = 753
+var var754 = 754
+var var755 = 755
+var var756 = 756
+var var757 = 757
+var var758 = 758
+var var759 = 759
+var var760 = 760
+var var761 = 761
+var var762 = 762
+var var763 = 763
+var var764 = 764
+var var765 = 765
+var var766 = 766
+var var767 = 767
+var var768 = 768
+var var769 = 769
+var var770 = 770
+var var771 = 771
+var var772 = 772
+var var773 = 773
+var var774 = 774
+var var775 = 775
+var var776 = 776
+var var777 = 777
+var var778 = 778
+var var779 = 779
+var var780 = 780
+var var781 = 781
+var var782 = 782
+var var783 = 783
+var var784 = 784
+var var785 = 785
+var var786 = 786
+var var787 = 787
+var var788 = 788
+var var789 = 789
+var var790 = 790
+var var791 = 791
+var var792 = 792
+var var793 = 793
+var var794 = 794
+var var795 = 795
+var var796 = 796
+var var797 = 797
+var var798 = 798
+var var799 = 799
+var var800 = 800
+var var801 = 801
+var var802 = 802
+var var803 = 803
+var var804 = 804
+var var805 = 805
+var var806 = 806
+var var807 = 807
+var var808 = 808
+var var809 = 809
+var var810 = 810
+var var811 = 811
+var var812 = 812
+var var813 = 813
+var var814 = 814
+var var815 = 815
+var var816 = 816
+var var817 = 817
+var var818 = 818
+var var819 = 819
+var var820 = 820
+var var821 = 821
+var var822 = 822
+var var823 = 823
+var var824 = 824
+var var825 = 825
+var var826 = 826
+var var827 = 827
+var var828 = 828
+var var829 = 829
+var var830 = 830
+var var831 = 831
+var var832 = 832
+var var833 = 833
+var var834 = 834
+var var835 = 835
+var var836 = 836
+var var837 = 837
+var var838 = 838
+var var839 = 839
+var var840 = 840
+var var841 = 841
+var var842 = 842
+var var843 = 843
+var var844 = 844
+var var845 = 845
+var var846 = 846
+var var847 = 847
+var var848 = 848
+var var849 = 849
+var var850 = 850
+var var851 = 851
+var var852 = 852
+var var853 = 853
+var var854 = 854
+var var855 = 855
+var var856 = 856
+var var857 = 857
+var var858 = 858
+var var859 = 859
+var var860 = 860
+var var861 = 861
+var var862 = 862
+var var863 = 863
+var var864 = 864
+var var865 = 865
+var var866 = 866
+var var867 = 867
+var var868 = 868
+var var869 = 869
+var var870 = 870
+var var871 = 871
+var var872 = 872
+var var873 = 873
+var var874 = 874
+var var875 = 875
+var var876 = 876
+var var877 = 877
+var var878 = 878
+var var879 = 879
+var var880 = 880
+var var881 = 881
+var var882 = 882
+var var883 = 883
+var var884 = 884
+var var885 = 885
+var var886 = 886
+var var887 = 887
+var var888 = 888
+var var889 = 889
+var var890 = 890
+var var891 = 891
+var var892 = 892
+var var893 = 893
+var var894 = 894
+var var895 = 895
+var var896 = 896
+var var897 = 897
+var var898 = 898
+var var899 = 899
+var var900 = 900
+var var901 = 901
+var var902 = 902
+var var903 = 903
+var var904 = 904
+var var905 = 905
+var var906 = 906
+var var907 = 907
+var var908 = 908
+var var909 = 909
+var var910 = 910
+var var911 = 911
+var var912 = 912
+var var913 = 913
+var var914 = 914
+var var915 = 915
+var var916 = 916
+var var917 = 917
+var var918 = 918
+var var919 = 919
+var var920 = 920
+var var921 = 921
+var var922 = 922
+var var923 = 923
+var var924 = 924
+var var925 = 925
+var var926 = 926
+var var927 = 927
+var var928 = 928
+var var929 = 929
+var var930 = 930
+var var931 = 931
+var var932 = 932
+var var933 = 933
+var var934 = 934
+var var935 = 935
+var var936 = 936
+var var937 = 937
+var var938 = 938
+var var939 = 939
+var var940 = 940
+var var941 = 941
+var var942 = 942
+var var943 = 943
+var var944 = 944
+var var945 = 945
+var var946 = 946
+var var947 = 947
+var var948 = 948
+var var949 = 949
+var var950 = 950
+var var951 = 951
+var var952 = 952
+var var953 = 953
+var var954 = 954
+var var955 = 955
+var var956 = 956
+var var957 = 957
+var var958 = 958
+var var959 = 959
+var var960 = 960
+var var961 = 961
+var var962 = 962
+var var963 = 963
+var var964 = 964
+var var965 = 965
+var var966 = 966
+var var967 = 967
+var var968 = 968
+var var969 = 969
+var var970 = 970
+var var971 = 971
+var var972 = 972
+var var973 = 973
+var var974 = 974
+var var975 = 975
+var var976 = 976
+var var977 = 977
+var var978 = 978
+var var979 = 979
+var var980 = 980
+var var981 = 981
+var var982 = 982
+var var983 = 983
+var var984 = 984
+var var985 = 985
+var var986 = 986
+var var987 = 987
+var var988 = 988
+var var989 = 989
+var var990 = 990
+var var991 = 991
+var var992 = 992
+var var993 = 993
+var var994 = 994
+var var995 = 995
+var var996 = 996
+var var997 = 997
+var var998 = 998
+var var999 = 999
+var var1000 = 1000
+var var1001 = 1001
+var var1002 = 1002
+var var1003 = 1003
+var var1004 = 1004
+var var1005 = 1005
+var var1006 = 1006
+var var1007 = 1007
+var var1008 = 1008
+var var1009 = 1009
+var var1010 = 1010
+var var1011 = 1011
+var var1012 = 1012
+var var1013 = 1013
+var var1014 = 1014
+var var1015 = 1015
+var var1016 = 1016
+var var1017 = 1017
+var var1018 = 1018
+var var1019 = 1019
+var var1020 = 1020
+var var1021 = 1021
+var var1022 = 1022
+var var1023 = 1023
+var var1024 = 1024
+var var1025 = 1025
+var var1026 = 1026
+var var1027 = 1027
+var var1028 = 1028
+var var1029 = 1029
+var var1030 = 1030
+var var1031 = 1031
+var var1032 = 1032
+var var1033 = 1033
+var var1034 = 1034
+var var1035 = 1035
+var var1036 = 1036
+var var1037 = 1037
+var var1038 = 1038
+var var1039 = 1039
+var var1040 = 1040
+var var1041 = 1041
+var var1042 = 1042
+var var1043 = 1043
+var var1044 = 1044
+var var1045 = 1045
+var var1046 = 1046
+var var1047 = 1047
+var var1048 = 1048
+var var1049 = 1049
+var var1050 = 1050
+var var1051 = 1051
+var var1052 = 1052
+var var1053 = 1053
+var var1054 = 1054
+var var1055 = 1055
+var var1056 = 1056
+var var1057 = 1057
+var var1058 = 1058
+var var1059 = 1059
+var var1060 = 1060
+var var1061 = 1061
+var var1062 = 1062
+var var1063 = 1063
+var var1064 = 1064
+var var1065 = 1065
+var var1066 = 1066
+var var1067 = 1067
+var var1068 = 1068
+var var1069 = 1069
+var var1070 = 1070
+var var1071 = 1071
+var var1072 = 1072
+var var1073 = 1073
+var var1074 = 1074
+var var1075 = 1075
+var var1076 = 1076
+var var1077 = 1077
+var var1078 = 1078
+var var1079 = 1079
+var var1080 = 1080
+var var1081 = 1081
+var var1082 = 1082
+var var1083 = 1083
+var var1084 = 1084
+var var1085 = 1085
+var var1086 = 1086
+var var1087 = 1087
+var var1088 = 1088
+var var1089 = 1089
+var var1090 = 1090
+var var1091 = 1091
+var var1092 = 1092
+var var1093 = 1093
+var var1094 = 1094
+var var1095 = 1095
+var var1096 = 1096
+var var1097 = 1097
+var var1098 = 1098
+var var1099 = 1099
+var var1100 = 1100
+var var1101 = 1101
+var var1102 = 1102
+var var1103 = 1103
+var var1104 = 1104
+var var1105 = 1105
+var var1106 = 1106
+var var1107 = 1107
+var var1108 = 1108
+var var1109 = 1109
+var var1110 = 1110
+var var1111 = 1111
+var var1112 = 1112
+var var1113 = 1113
+var var1114 = 1114
+var var1115 = 1115
+var var1116 = 1116
+var var1117 = 1117
+var var1118 = 1118
+var var1119 = 1119
+var var1120 = 1120
+var var1121 = 1121
+var var1122 = 1122
+var var1123 = 1123
+var var1124 = 1124
+var var1125 = 1125
+var var1126 = 1126
+var var1127 = 1127
+var var1128 = 1128
+var var1129 = 1129
+var var1130 = 1130
+var var1131 = 1131
+var var1132 = 1132
+var var1133 = 1133
+var var1134 = 1134
+var var1135 = 1135
+var var1136 = 1136
+var var1137 = 1137
+var var1138 = 1138
+var var1139 = 1139
+var var1140 = 1140
+var var1141 = 1141
+var var1142 = 1142
+var var1143 = 1143
+var var1144 = 1144
+var var1145 = 1145
+var var1146 = 1146
+var var1147 = 1147
+var var1148 = 1148
+var var1149 = 1149
+var var1150 = 1150
+var var1151 = 1151
+var var1152 = 1152
+var var1153 = 1153
+var var1154 = 1154
+var var1155 = 1155
+var var1156 = 1156
+var var1157 = 1157
+var var1158 = 1158
+var var1159 = 1159
+var var1160 = 1160
+var var1161 = 1161
+var var1162 = 1162
+var var1163 = 1163
+var var1164 = 1164
+var var1165 = 1165
+var var1166 = 1166
+var var1167 = 1167
+var var1168 = 1168
+var var1169 = 1169
+var var1170 = 1170
+var var1171 = 1171
+var var1172 = 1172
+var var1173 = 1173
+var var1174 = 1174
+var var1175 = 1175
+var var1176 = 1176
+var var1177 = 1177
+var var1178 = 1178
+var var1179 = 1179
+var var1180 = 1180
+var var1181 = 1181
+var var1182 = 1182
+var var1183 = 1183
+var var1184 = 1184
+var var1185 = 1185
+var var1186 = 1186
+var var1187 = 1187
+var var1188 = 1188
+var var1189 = 1189
+var var1190 = 1190
+var var1191 = 1191
+var var1192 = 1192
+var var1193 = 1193
+var var1194 = 1194
+var var1195 = 1195
+var var1196 = 1196
+var var1197 = 1197
+var var1198 = 1198
+var var1199 = 1199
+var var1200 = 1200
+var var1201 = 1201
+var var1202 = 1202
+var var1203 = 1203
+var var1204 = 1204
+var var1205 = 1205
+var var1206 = 1206
+var var1207 = 1207
+var var1208 = 1208
+var var1209 = 1209
+var var1210 = 1210
+var var1211 = 1211
+var var1212 = 1212
+var var1213 = 1213
+var var1214 = 1214
+var var1215 = 1215
+var var1216 = 1216
+var var1217 = 1217
+var var1218 = 1218
+var var1219 = 1219
+var var1220 = 1220
+var var1221 = 1221
+var var1222 = 1222
+var var1223 = 1223
+var var1224 = 1224
+var var1225 = 1225
+var var1226 = 1226
+var var1227 = 1227
+var var1228 = 1228
+var var1229 = 1229
+var var1230 = 1230
+var var1231 = 1231
+var var1232 = 1232
+var var1233 = 1233
+var var1234 = 1234
+var var1235 = 1235
+var var1236 = 1236
+var var1237 = 1237
+var var1238 = 1238
+var var1239 = 1239
+var var1240 = 1240
+var var1241 = 1241
+var var1242 = 1242
+var var1243 = 1243
+var var1244 = 1244
+var var1245 = 1245
+var var1246 = 1246
+var var1247 = 1247
+var var1248 = 1248
+var var1249 = 1249
+var var1250 = 1250
+var var1251 = 1251
+var var1252 = 1252
+var var1253 = 1253
+var var1254 = 1254
+var var1255 = 1255
+var var1256 = 1256
+var var1257 = 1257
+var var1258 = 1258
+var var1259 = 1259
+var var1260 = 1260
+var var1261 = 1261
+var var1262 = 1262
+var var1263 = 1263
+var var1264 = 1264
+var var1265 = 1265
+var var1266 = 1266
+var var1267 = 1267
+var var1268 = 1268
+var var1269 = 1269
+var var1270 = 1270
+var var1271 = 1271
+var var1272 = 1272
+var var1273 = 1273
+var var1274 = 1274
+var var1275 = 1275
+var var1276 = 1276
+var var1277 = 1277
+var var1278 = 1278
+var var1279 = 1279
+var var1280 = 1280
+var var1281 = 1281
+var var1282 = 1282
+var var1283 = 1283
+var var1284 = 1284
+var var1285 = 1285
+var var1286 = 1286
+var var1287 = 1287
+var var1288 = 1288
+var var1289 = 1289
+var var1290 = 1290
+var var1291 = 1291
+var var1292 = 1292
+var var1293 = 1293
+var var1294 = 1294
+var var1295 = 1295
+var var1296 = 1296
+var var1297 = 1297
+var var1298 = 1298
+var var1299 = 1299
+var var1300 = 1300
+var var1301 = 1301
+var var1302 = 1302
+var var1303 = 1303
+var var1304 = 1304
+var var1305 = 1305
+var var1306 = 1306
+var var1307 = 1307
+var var1308 = 1308
+var var1309 = 1309
+var var1310 = 1310
+var var1311 = 1311
+var var1312 = 1312
+var var1313 = 1313
+var var1314 = 1314
+var var1315 = 1315
+var var1316 = 1316
+var var1317 = 1317
+var var1318 = 1318
+var var1319 = 1319
+var var1320 = 1320
+var var1321 = 1321
+var var1322 = 1322
+var var1323 = 1323
+var var1324 = 1324
+var var1325 = 1325
+var var1326 = 1326
+var var1327 = 1327
+var var1328 = 1328
+var var1329 = 1329
+var var1330 = 1330
+var var1331 = 1331
+var var1332 = 1332
+var var1333 = 1333
+var var1334 = 1334
+var var1335 = 1335
+var var1336 = 1336
+var var1337 = 1337
+var var1338 = 1338
+var var1339 = 1339
+var var1340 = 1340
+var var1341 = 1341
+var var1342 = 1342
+var var1343 = 1343
+var var1344 = 1344
+var var1345 = 1345
+var var1346 = 1346
+var var1347 = 1347
+var var1348 = 1348
+var var1349 = 1349
+var var1350 = 1350
+var var1351 = 1351
+var var1352 = 1352
+var var1353 = 1353
+var var1354 = 1354
+var var1355 = 1355
+var var1356 = 1356
+var var1357 = 1357
+var var1358 = 1358
+var var1359 = 1359
+var var1360 = 1360
+var var1361 = 1361
+var var1362 = 1362
+var var1363 = 1363
+var var1364 = 1364
+var var1365 = 1365
+var var1366 = 1366
+var var1367 = 1367
+var var1368 = 1368
+var var1369 = 1369
+var var1370 = 1370
+var var1371 = 1371
+var var1372 = 1372
+var var1373 = 1373
+var var1374 = 1374
+var var1375 = 1375
+var var1376 = 1376
+var var1377 = 1377
+var var1378 = 1378
+var var1379 = 1379
+var var1380 = 1380
+var var1381 = 1381
+var var1382 = 1382
+var var1383 = 1383
+var var1384 = 1384
+var var1385 = 1385
+var var1386 = 1386
+var var1387 = 1387
+var var1388 = 1388
+var var1389 = 1389
+var var1390 = 1390
+var var1391 = 1391
+var var1392 = 1392
+var var1393 = 1393
+var var1394 = 1394
+var var1395 = 1395
+var var1396 = 1396
+var var1397 = 1397
+var var1398 = 1398
+var var1399 = 1399
+var var1400 = 1400
+var var1401 = 1401
+var var1402 = 1402
+var var1403 = 1403
+var var1404 = 1404
+var var1405 = 1405
+var var1406 = 1406
+var var1407 = 1407
+var var1408 = 1408
+var var1409 = 1409
+var var1410 = 1410
+var var1411 = 1411
+var var1412 = 1412
+var var1413 = 1413
+var var1414 = 1414
+var var1415 = 1415
+var var1416 = 1416
+var var1417 = 1417
+var var1418 = 1418
+var var1419 = 1419
+var var1420 = 1420
+var var1421 = 1421
+var var1422 = 1422
+var var1423 = 1423
+var var1424 = 1424
+var var1425 = 1425
+var var1426 = 1426
+var var1427 = 1427
+var var1428 = 1428
+var var1429 = 1429
+var var1430 = 1430
+var var1431 = 1431
+var var1432 = 1432
+var var1433 = 1433
+var var1434 = 1434
+var var1435 = 1435
+var var1436 = 1436
+var var1437 = 1437
+var var1438 = 1438
+var var1439 = 1439
+var var1440 = 1440
+var var1441 = 1441
+var var1442 = 1442
+var var1443 = 1443
+var var1444 = 1444
+var var1445 = 1445
+var var1446 = 1446
+var var1447 = 1447
+var var1448 = 1448
+var var1449 = 1449
+var var1450 = 1450
+var var1451 = 1451
+var var1452 = 1452
+var var1453 = 1453
+var var1454 = 1454
+var var1455 = 1455
+var var1456 = 1456
+var var1457 = 1457
+var var1458 = 1458
+var var1459 = 1459
+var var1460 = 1460
+var var1461 = 1461
+var var1462 = 1462
+var var1463 = 1463
+var var1464 = 1464
+var var1465 = 1465
+var var1466 = 1466
+var var1467 = 1467
+var var1468 = 1468
+var var1469 = 1469
+var var1470 = 1470
+var var1471 = 1471
+var var1472 = 1472
+var var1473 = 1473
+var var1474 = 1474
+var var1475 = 1475
+var var1476 = 1476
+var var1477 = 1477
+var var1478 = 1478
+var var1479 = 1479
+var var1480 = 1480
+var var1481 = 1481
+var var1482 = 1482
+var var1483 = 1483
+var var1484 = 1484
+var var1485 = 1485
+var var1486 = 1486
+var var1487 = 1487
+var var1488 = 1488
+var var1489 = 1489
+var var1490 = 1490
+var var1491 = 1491
+var var1492 = 1492
+var var1493 = 1493
+var var1494 = 1494
+var var1495 = 1495
+var var1496 = 1496
+var var1497 = 1497
+var var1498 = 1498
+var var1499 = 1499
+var var1500 = 1500
+var var1501 = 1501
+var var1502 = 1502
+var var1503 = 1503
+var var1504 = 1504
+var var1505 = 1505
+var var1506 = 1506
+var var1507 = 1507
+var var1508 = 1508
+var var1509 = 1509
+var var1510 = 1510
+var var1511 = 1511
+var var1512 = 1512
+var var1513 = 1513
+var var1514 = 1514
+var var1515 = 1515
+var var1516 = 1516
+var var1517 = 1517
+var var1518 = 1518
+var var1519 = 1519
+var var1520 = 1520
+var var1521 = 1521
+var var1522 = 1522
+var var1523 = 1523
+var var1524 = 1524
+var var1525 = 1525
+var var1526 = 1526
+var var1527 = 1527
+var var1528 = 1528
+var var1529 = 1529
+var var1530 = 1530
+var var1531 = 1531
+var var1532 = 1532
+var var1533 = 1533
+var var1534 = 1534
+var var1535 = 1535
+var var1536 = 1536
+var var1537 = 1537
+var var1538 = 1538
+var var1539 = 1539
+var var1540 = 1540
+var var1541 = 1541
+var var1542 = 1542
+var var1543 = 1543
+var var1544 = 1544
+var var1545 = 1545
+var var1546 = 1546
+var var1547 = 1547
+var var1548 = 1548
+var var1549 = 1549
+var var1550 = 1550
+var var1551 = 1551
+var var1552 = 1552
+var var1553 = 1553
+var var1554 = 1554
+var var1555 = 1555
+var var1556 = 1556
+var var1557 = 1557
+var var1558 = 1558
+var var1559 = 1559
+var var1560 = 1560
+var var1561 = 1561
+var var1562 = 1562
+var var1563 = 1563
+var var1564 = 1564
+var var1565 = 1565
+var var1566 = 1566
+var var1567 = 1567
+var var1568 = 1568
+var var1569 = 1569
+var var1570 = 1570
+var var1571 = 1571
+var var1572 = 1572
+var var1573 = 1573
+var var1574 = 1574
+var var1575 = 1575
+var var1576 = 1576
+var var1577 = 1577
+var var1578 = 1578
+var var1579 = 1579
+var var1580 = 1580
+var var1581 = 1581
+var var1582 = 1582
+var var1583 = 1583
+var var1584 = 1584
+var var1585 = 1585
+var var1586 = 1586
+var var1587 = 1587
+var var1588 = 1588
+var var1589 = 1589
+var var1590 = 1590
+var var1591 = 1591
+var var1592 = 1592
+var var1593 = 1593
+var var1594 = 1594
+var var1595 = 1595
+var var1596 = 1596
+var var1597 = 1597
+var var1598 = 1598
+var var1599 = 1599
+var var1600 = 1600
+var var1601 = 1601
+var var1602 = 1602
+var var1603 = 1603
+var var1604 = 1604
+var var1605 = 1605
+var var1606 = 1606
+var var1607 = 1607
+var var1608 = 1608
+var var1609 = 1609
+var var1610 = 1610
+var var1611 = 1611
+var var1612 = 1612
+var var1613 = 1613
+var var1614 = 1614
+var var1615 = 1615
+var var1616 = 1616
+var var1617 = 1617
+var var1618 = 1618
+var var1619 = 1619
+var var1620 = 1620
+var var1621 = 1621
+var var1622 = 1622
+var var1623 = 1623
+var var1624 = 1624
+var var1625 = 1625
+var var1626 = 1626
+var var1627 = 1627
+var var1628 = 1628
+var var1629 = 1629
+var var1630 = 1630
+var var1631 = 1631
+var var1632 = 1632
+var var1633 = 1633
+var var1634 = 1634
+var var1635 = 1635
+var var1636 = 1636
+var var1637 = 1637
+var var1638 = 1638
+var var1639 = 1639
+var var1640 = 1640
+var var1641 = 1641
+var var1642 = 1642
+var var1643 = 1643
+var var1644 = 1644
+var var1645 = 1645
+var var1646 = 1646
+var var1647 = 1647
+var var1648 = 1648
+var var1649 = 1649
+var var1650 = 1650
+var var1651 = 1651
+var var1652 = 1652
+var var1653 = 1653
+var var1654 = 1654
+var var1655 = 1655
+var var1656 = 1656
+var var1657 = 1657
+var var1658 = 1658
+var var1659 = 1659
+var var1660 = 1660
+var var1661 = 1661
+var var1662 = 1662
+var var1663 = 1663
+var var1664 = 1664
+var var1665 = 1665
+var var1666 = 1666
+var var1667 = 1667
+var var1668 = 1668
+var var1669 = 1669
+var var1670 = 1670
+var var1671 = 1671
+var var1672 = 1672
+var var1673 = 1673
+var var1674 = 1674
+var var1675 = 1675
+var var1676 = 1676
+var var1677 = 1677
+var var1678 = 1678
+var var1679 = 1679
+var var1680 = 1680
+var var1681 = 1681
+var var1682 = 1682
+var var1683 = 1683
+var var1684 = 1684
+var var1685 = 1685
+var var1686 = 1686
+var var1687 = 1687
+var var1688 = 1688
+var var1689 = 1689
+var var1690 = 1690
+var var1691 = 1691
+var var1692 = 1692
+var var1693 = 1693
+var var1694 = 1694
+var var1695 = 1695
+var var1696 = 1696
+var var1697 = 1697
+var var1698 = 1698
+var var1699 = 1699
+var var1700 = 1700
+var var1701 = 1701
+var var1702 = 1702
+var var1703 = 1703
+var var1704 = 1704
+var var1705 = 1705
+var var1706 = 1706
+var var1707 = 1707
+var var1708 = 1708
+var var1709 = 1709
+var var1710 = 1710
+var var1711 = 1711
+var var1712 = 1712
+var var1713 = 1713
+var var1714 = 1714
+var var1715 = 1715
+var var1716 = 1716
+var var1717 = 1717
+var var1718 = 1718
+var var1719 = 1719
+var var1720 = 1720
+var var1721 = 1721
+var var1722 = 1722
+var var1723 = 1723
+var var1724 = 1724
+var var1725 = 1725
+var var1726 = 1726
+var var1727 = 1727
+var var1728 = 1728
+var var1729 = 1729
+var var1730 = 1730
+var var1731 = 1731
+var var1732 = 1732
+var var1733 = 1733
+var var1734 = 1734
+var var1735 = 1735
+var var1736 = 1736
+var var1737 = 1737
+var var1738 = 1738
+var var1739 = 1739
+var var1740 = 1740
+var var1741 = 1741
+var var1742 = 1742
+var var1743 = 1743
+var var1744 = 1744
+var var1745 = 1745
+var var1746 = 1746
+var var1747 = 1747
+var var1748 = 1748
+var var1749 = 1749
+var var1750 = 1750
+var var1751 = 1751
+var var1752 = 1752
+var var1753 = 1753
+var var1754 = 1754
+var var1755 = 1755
+var var1756 = 1756
+var var1757 = 1757
+var var1758 = 1758
+var var1759 = 1759
+var var1760 = 1760
+var var1761 = 1761
+var var1762 = 1762
+var var1763 = 1763
+var var1764 = 1764
+var var1765 = 1765
+var var1766 = 1766
+var var1767 = 1767
+var var1768 = 1768
+var var1769 = 1769
+var var1770 = 1770
+var var1771 = 1771
+var var1772 = 1772
+var var1773 = 1773
+var var1774 = 1774
+var var1775 = 1775
+var var1776 = 1776
+var var1777 = 1777
+var var1778 = 1778
+var var1779 = 1779
+var var1780 = 1780
+var var1781 = 1781
+var var1782 = 1782
+var var1783 = 1783
+var var1784 = 1784
+var var1785 = 1785
+var var1786 = 1786
+var var1787 = 1787
+var var1788 = 1788
+var var1789 = 1789
+var var1790 = 1790
+var var1791 = 1791
+var var1792 = 1792
+var var1793 = 1793
+var var1794 = 1794
+var var1795 = 1795
+var var1796 = 1796
+var var1797 = 1797
+var var1798 = 1798
+var var1799 = 1799
+var var1800 = 1800
+var var1801 = 1801
+var var1802 = 1802
+var var1803 = 1803
+var var1804 = 1804
+var var1805 = 1805
+var var1806 = 1806
+var var1807 = 1807
+var var1808 = 1808
+var var1809 = 1809
+var var1810 = 1810
+var var1811 = 1811
+var var1812 = 1812
+var var1813 = 1813
+var var1814 = 1814
+var var1815 = 1815
+var var1816 = 1816
+var var1817 = 1817
+var var1818 = 1818
+var var1819 = 1819
+var var1820 = 1820
+var var1821 = 1821
+var var1822 = 1822
+var var1823 = 1823
+var var1824 = 1824
+var var1825 = 1825
+var var1826 = 1826
+var var1827 = 1827
+var var1828 = 1828
+var var1829 = 1829
+var var1830 = 1830
+var var1831 = 1831
+var var1832 = 1832
+var var1833 = 1833
+var var1834 = 1834
+var var1835 = 1835
+var var1836 = 1836
+var var1837 = 1837
+var var1838 = 1838
+var var1839 = 1839
+var var1840 = 1840
+var var1841 = 1841
+var var1842 = 1842
+var var1843 = 1843
+var var1844 = 1844
+var var1845 = 1845
+var var1846 = 1846
+var var1847 = 1847
+var var1848 = 1848
+var var1849 = 1849
+var var1850 = 1850
+var var1851 = 1851
+var var1852 = 1852
+var var1853 = 1853
+var var1854 = 1854
+var var1855 = 1855
+var var1856 = 1856
+var var1857 = 1857
+var var1858 = 1858
+var var1859 = 1859
+var var1860 = 1860
+var var1861 = 1861
+var var1862 = 1862
+var var1863 = 1863
+var var1864 = 1864
+var var1865 = 1865
+var var1866 = 1866
+var var1867 = 1867
+var var1868 = 1868
+var var1869 = 1869
+var var1870 = 1870
+var var1871 = 1871
+var var1872 = 1872
+var var1873 = 1873
+var var1874 = 1874
+var var1875 = 1875
+var var1876 = 1876
+var var1877 = 1877
+var var1878 = 1878
+var var1879 = 1879
+var var1880 = 1880
+var var1881 = 1881
+var var1882 = 1882
+var var1883 = 1883
+var var1884 = 1884
+var var1885 = 1885
+var var1886 = 1886
+var var1887 = 1887
+var var1888 = 1888
+var var1889 = 1889
+var var1890 = 1890
+var var1891 = 1891
+var var1892 = 1892
+var var1893 = 1893
+var var1894 = 1894
+var var1895 = 1895
+var var1896 = 1896
+var var1897 = 1897
+var var1898 = 1898
+var var1899 = 1899
+var var1900 = 1900
+var var1901 = 1901
+var var1902 = 1902
+var var1903 = 1903
+var var1904 = 1904
+var var1905 = 1905
+var var1906 = 1906
+var var1907 = 1907
+var var1908 = 1908
+var var1909 = 1909
+var var1910 = 1910
+var var1911 = 1911
+var var1912 = 1912
+var var1913 = 1913
+var var1914 = 1914
+var var1915 = 1915
+var var1916 = 1916
+var var1917 = 1917
+var var1918 = 1918
+var var1919 = 1919
+var var1920 = 1920
+var var1921 = 1921
+var var1922 = 1922
+var var1923 = 1923
+var var1924 = 1924
+var var1925 = 1925
+var var1926 = 1926
+var var1927 = 1927
+var var1928 = 1928
+var var1929 = 1929
+var var1930 = 1930
+var var1931 = 1931
+var var1932 = 1932
+var var1933 = 1933
+var var1934 = 1934
+var var1935 = 1935
+var var1936 = 1936
+var var1937 = 1937
+var var1938 = 1938
+var var1939 = 1939
+var var1940 = 1940
+var var1941 = 1941
+var var1942 = 1942
+var var1943 = 1943
+var var1944 = 1944
+var var1945 = 1945
+var var1946 = 1946
+var var1947 = 1947
+var var1948 = 1948
+var var1949 = 1949
+var var1950 = 1950
+var var1951 = 1951
+var var1952 = 1952
+var var1953 = 1953
+var var1954 = 1954
+var var1955 = 1955
+var var1956 = 1956
+var var1957 = 1957
+var var1958 = 1958
+var var1959 = 1959
+var var1960 = 1960
+var var1961 = 1961
+var var1962 = 1962
+var var1963 = 1963
+var var1964 = 1964
+var var1965 = 1965
+var var1966 = 1966
+var var1967 = 1967
+var var1968 = 1968
+var var1969 = 1969
+var var1970 = 1970
+var var1971 = 1971
+var var1972 = 1972
+var var1973 = 1973
+var var1974 = 1974
+var var1975 = 1975
+var var1976 = 1976
+var var1977 = 1977
+var var1978 = 1978
+var var1979 = 1979
+var var1980 = 1980
+var var1981 = 1981
+var var1982 = 1982
+var var1983 = 1983
+var var1984 = 1984
+var var1985 = 1985
+var var1986 = 1986
+var var1987 = 1987
+var var1988 = 1988
+var var1989 = 1989
+var var1990 = 1990
+var var1991 = 1991
+var var1992 = 1992
+var var1993 = 1993
+var var1994 = 1994
+var var1995 = 1995
+var var1996 = 1996
+var var1997 = 1997
+var var1998 = 1998
+var var1999 = 1999
+var var2000 = 2000
+var var2001 = 2001
+var var2002 = 2002
+var var2003 = 2003
+var var2004 = 2004
+var var2005 = 2005
+var var2006 = 2006
+var var2007 = 2007
+var var2008 = 2008
+var var2009 = 2009
+var var2010 = 2010
+var var2011 = 2011
+var var2012 = 2012
+var var2013 = 2013
+var var2014 = 2014
+var var2015 = 2015
+var var2016 = 2016
+var var2017 = 2017
+var var2018 = 2018
+var var2019 = 2019
+var var2020 = 2020
+var var2021 = 2021
+var var2022 = 2022
+var var2023 = 2023
+var var2024 = 2024
+var var2025 = 2025
+var var2026 = 2026
+var var2027 = 2027
+var var2028 = 2028
+var var2029 = 2029
+var var2030 = 2030
+var var2031 = 2031
+var var2032 = 2032
+var var2033 = 2033
+var var2034 = 2034
+var var2035 = 2035
+var var2036 = 2036
+var var2037 = 2037
+var var2038 = 2038
+var var2039 = 2039
+var var2040 = 2040
+var var2041 = 2041
+var var2042 = 2042
+var var2043 = 2043
+var var2044 = 2044
+var var2045 = 2045
+var var2046 = 2046
+var var2047 = 2047
+var var2048 = 2048
+var var2049 = 2049
+var var2050 = 2050
+var var2051 = 2051
+var var2052 = 2052
+var var2053 = 2053
+var var2054 = 2054
+var var2055 = 2055
+var var2056 = 2056
+var var2057 = 2057
+var var2058 = 2058
+var var2059 = 2059
+var var2060 = 2060
+var var2061 = 2061
+var var2062 = 2062
+var var2063 = 2063
+var var2064 = 2064
+var var2065 = 2065
+var var2066 = 2066
+var var2067 = 2067
+var var2068 = 2068
+var var2069 = 2069
+var var2070 = 2070
+var var2071 = 2071
+var var2072 = 2072
+var var2073 = 2073
+var var2074 = 2074
+var var2075 = 2075
+var var2076 = 2076
+var var2077 = 2077
+var var2078 = 2078
+var var2079 = 2079
+var var2080 = 2080
+var var2081 = 2081
+var var2082 = 2082
+var var2083 = 2083
+var var2084 = 2084
+var var2085 = 2085
+var var2086 = 2086
+var var2087 = 2087
+var var2088 = 2088
+var var2089 = 2089
+var var2090 = 2090
+var var2091 = 2091
+var var2092 = 2092
+var var2093 = 2093
+var var2094 = 2094
+var var2095 = 2095
+var var2096 = 2096
+var var2097 = 2097
+var var2098 = 2098
+var var2099 = 2099
+var var2100 = 2100
+var var2101 = 2101
+var var2102 = 2102
+var var2103 = 2103
+var var2104 = 2104
+var var2105 = 2105
+var var2106 = 2106
+var var2107 = 2107
+var var2108 = 2108
+var var2109 = 2109
+var var2110 = 2110
+var var2111 = 2111
+var var2112 = 2112
+var var2113 = 2113
+var var2114 = 2114
+var var2115 = 2115
+var var2116 = 2116
+var var2117 = 2117
+var var2118 = 2118
+var var2119 = 2119
+var var2120 = 2120
+var var2121 = 2121
+var var2122 = 2122
+var var2123 = 2123
+var var2124 = 2124
+var var2125 = 2125
+var var2126 = 2126
+var var2127 = 2127
+var var2128 = 2128
+var var2129 = 2129
+var var2130 = 2130
+var var2131 = 2131
+var var2132 = 2132
+var var2133 = 2133
+var var2134 = 2134
+var var2135 = 2135
+var var2136 = 2136
+var var2137 = 2137
+var var2138 = 2138
+var var2139 = 2139
+var var2140 = 2140
+var var2141 = 2141
+var var2142 = 2142
+var var2143 = 2143
+var var2144 = 2144
+var var2145 = 2145
+var var2146 = 2146
+var var2147 = 2147
+var var2148 = 2148
+var var2149 = 2149
+var var2150 = 2150
+var var2151 = 2151
+var var2152 = 2152
+var var2153 = 2153
+var var2154 = 2154
+var var2155 = 2155
+var var2156 = 2156
+var var2157 = 2157
+var var2158 = 2158
+var var2159 = 2159
+var var2160 = 2160
+var var2161 = 2161
+var var2162 = 2162
+var var2163 = 2163
+var var2164 = 2164
+var var2165 = 2165
+var var2166 = 2166
+var var2167 = 2167
+var var2168 = 2168
+var var2169 = 2169
+var var2170 = 2170
+var var2171 = 2171
+var var2172 = 2172
+var var2173 = 2173
+var var2174 = 2174
+var var2175 = 2175
+var var2176 = 2176
+var var2177 = 2177
+var var2178 = 2178
+var var2179 = 2179
+var var2180 = 2180
+var var2181 = 2181
+var var2182 = 2182
+var var2183 = 2183
+var var2184 = 2184
+var var2185 = 2185
+var var2186 = 2186
+var var2187 = 2187
+var var2188 = 2188
+var var2189 = 2189
+var var2190 = 2190
+var var2191 = 2191
+var var2192 = 2192
+var var2193 = 2193
+var var2194 = 2194
+var var2195 = 2195
+var var2196 = 2196
+var var2197 = 2197
+var var2198 = 2198
+var var2199 = 2199
+var var2200 = 2200
+var var2201 = 2201
+var var2202 = 2202
+var var2203 = 2203
+var var2204 = 2204
+var var2205 = 2205
+var var2206 = 2206
+var var2207 = 2207
+var var2208 = 2208
+var var2209 = 2209
+var var2210 = 2210
+var var2211 = 2211
+var var2212 = 2212
+var var2213 = 2213
+var var2214 = 2214
+var var2215 = 2215
+var var2216 = 2216
+var var2217 = 2217
+var var2218 = 2218
+var var2219 = 2219
+var var2220 = 2220
+var var2221 = 2221
+var var2222 = 2222
+var var2223 = 2223
+var var2224 = 2224
+var var2225 = 2225
+var var2226 = 2226
+var var2227 = 2227
+var var2228 = 2228
+var var2229 = 2229
+var var2230 = 2230
+var var2231 = 2231
+var var2232 = 2232
+var var2233 = 2233
+var var2234 = 2234
+var var2235 = 2235
+var var2236 = 2236
+var var2237 = 2237
+var var2238 = 2238
+var var2239 = 2239
+var var2240 = 2240
+var var2241 = 2241
+var var2242 = 2242
+var var2243 = 2243
+var var2244 = 2244
+var var2245 = 2245
+var var2246 = 2246
+var var2247 = 2247
+var var2248 = 2248
+var var2249 = 2249
+var var2250 = 2250
+var var2251 = 2251
+var var2252 = 2252
+var var2253 = 2253
+var var2254 = 2254
+var var2255 = 2255
+var var2256 = 2256
+var var2257 = 2257
+var var2258 = 2258
+var var2259 = 2259
+var var2260 = 2260
+var var2261 = 2261
+var var2262 = 2262
+var var2263 = 2263
+var var2264 = 2264
+var var2265 = 2265
+var var2266 = 2266
+var var2267 = 2267
+var var2268 = 2268
+var var2269 = 2269
+var var2270 = 2270
+var var2271 = 2271
+var var2272 = 2272
+var var2273 = 2273
+var var2274 = 2274
+var var2275 = 2275
+var var2276 = 2276
+var var2277 = 2277
+var var2278 = 2278
+var var2279 = 2279
+var var2280 = 2280
+var var2281 = 2281
+var var2282 = 2282
+var var2283 = 2283
+var var2284 = 2284
+var var2285 = 2285
+var var2286 = 2286
+var var2287 = 2287
+var var2288 = 2288
+var var2289 = 2289
+var var2290 = 2290
+var var2291 = 2291
+var var2292 = 2292
+var var2293 = 2293
+var var2294 = 2294
+var var2295 = 2295
+var var2296 = 2296
+var var2297 = 2297
+var var2298 = 2298
+var var2299 = 2299
+var var2300 = 2300
+var var2301 = 2301
+var var2302 = 2302
+var var2303 = 2303
+var var2304 = 2304
+var var2305 = 2305
+var var2306 = 2306
+var var2307 = 2307
+var var2308 = 2308
+var var2309 = 2309
+var var2310 = 2310
+var var2311 = 2311
+var var2312 = 2312
+var var2313 = 2313
+var var2314 = 2314
+var var2315 = 2315
+var var2316 = 2316
+var var2317 = 2317
+var var2318 = 2318
+var var2319 = 2319
+var var2320 = 2320
+var var2321 = 2321
+var var2322 = 2322
+var var2323 = 2323
+var var2324 = 2324
+var var2325 = 2325
+var var2326 = 2326
+var var2327 = 2327
+var var2328 = 2328
+var var2329 = 2329
+var var2330 = 2330
+var var2331 = 2331
+var var2332 = 2332
+var var2333 = 2333
+var var2334 = 2334
+var var2335 = 2335
+var var2336 = 2336
+var var2337 = 2337
+var var2338 = 2338
+var var2339 = 2339
+var var2340 = 2340
+var var2341 = 2341
+var var2342 = 2342
+var var2343 = 2343
+var var2344 = 2344
+var var2345 = 2345
+var var2346 = 2346
+var var2347 = 2347
+var var2348 = 2348
+var var2349 = 2349
+var var2350 = 2350
+var var2351 = 2351
+var var2352 = 2352
+var var2353 = 2353
+var var2354 = 2354
+var var2355 = 2355
+var var2356 = 2356
+var var2357 = 2357
+var var2358 = 2358
+var var2359 = 2359
+var var2360 = 2360
+var var2361 = 2361
+var var2362 = 2362
+var var2363 = 2363
+var var2364 = 2364
+var var2365 = 2365
+var var2366 = 2366
+var var2367 = 2367
+var var2368 = 2368
+var var2369 = 2369
+var var2370 = 2370
+var var2371 = 2371
+var var2372 = 2372
+var var2373 = 2373
+var var2374 = 2374
+var var2375 = 2375
+var var2376 = 2376
+var var2377 = 2377
+var var2378 = 2378
+var var2379 = 2379
+var var2380 = 2380
+var var2381 = 2381
+var var2382 = 2382
+var var2383 = 2383
+var var2384 = 2384
+var var2385 = 2385
+var var2386 = 2386
+var var2387 = 2387
+var var2388 = 2388
+var var2389 = 2389
+var var2390 = 2390
+var var2391 = 2391
+var var2392 = 2392
+var var2393 = 2393
+var var2394 = 2394
+var var2395 = 2395
+var var2396 = 2396
+var var2397 = 2397
+var var2398 = 2398
+var var2399 = 2399
+var var2400 = 2400
+var var2401 = 2401
+var var2402 = 2402
+var var2403 = 2403
+var var2404 = 2404
+var var2405 = 2405
+var var2406 = 2406
+var var2407 = 2407
+var var2408 = 2408
+var var2409 = 2409
+var var2410 = 2410
+var var2411 = 2411
+var var2412 = 2412
+var var2413 = 2413
+var var2414 = 2414
+var var2415 = 2415
+var var2416 = 2416
+var var2417 = 2417
+var var2418 = 2418
+var var2419 = 2419
+var var2420 = 2420
+var var2421 = 2421
+var var2422 = 2422
+var var2423 = 2423
+var var2424 = 2424
+var var2425 = 2425
+var var2426 = 2426
+var var2427 = 2427
+var var2428 = 2428
+var var2429 = 2429
+var var2430 = 2430
+var var2431 = 2431
+var var2432 = 2432
+var var2433 = 2433
+var var2434 = 2434
+var var2435 = 2435
+var var2436 = 2436
+var var2437 = 2437
+var var2438 = 2438
+var var2439 = 2439
+var var2440 = 2440
+var var2441 = 2441
+var var2442 = 2442
+var var2443 = 2443
+var var2444 = 2444
+var var2445 = 2445
+var var2446 = 2446
+var var2447 = 2447
+var var2448 = 2448
+var var2449 = 2449
+var var2450 = 2450
+var var2451 = 2451
+var var2452 = 2452
+var var2453 = 2453
+var var2454 = 2454
+var var2455 = 2455
+var var2456 = 2456
+var var2457 = 2457
+var var2458 = 2458
+var var2459 = 2459
+var var2460 = 2460
+var var2461 = 2461
+var var2462 = 2462
+var var2463 = 2463
+var var2464 = 2464
+var var2465 = 2465
+var var2466 = 2466
+var var2467 = 2467
+var var2468 = 2468
+var var2469 = 2469
+var var2470 = 2470
+var var2471 = 2471
+var var2472 = 2472
+var var2473 = 2473
+var var2474 = 2474
+var var2475 = 2475
+var var2476 = 2476
+var var2477 = 2477
+var var2478 = 2478
+var var2479 = 2479
+var var2480 = 2480
+var var2481 = 2481
+var var2482 = 2482
+var var2483 = 2483
+var var2484 = 2484
+var var2485 = 2485
+var var2486 = 2486
+var var2487 = 2487
+var var2488 = 2488
+var var2489 = 2489
+var var2490 = 2490
+var var2491 = 2491
+var var2492 = 2492
+var var2493 = 2493
+var var2494 = 2494
+var var2495 = 2495
+var var2496 = 2496
+var var2497 = 2497
+var var2498 = 2498
+var var2499 = 2499
+var var2500 = 2500
+var var2501 = 2501
+var var2502 = 2502
+var var2503 = 2503
+var var2504 = 2504
+var var2505 = 2505
+var var2506 = 2506
+var var2507 = 2507
+var var2508 = 2508
+var var2509 = 2509
+var var2510 = 2510
+var var2511 = 2511
+var var2512 = 2512
+var var2513 = 2513
+var var2514 = 2514
+var var2515 = 2515
+var var2516 = 2516
+var var2517 = 2517
+var var2518 = 2518
+var var2519 = 2519
+var var2520 = 2520
+var var2521 = 2521
+var var2522 = 2522
+var var2523 = 2523
+var var2524 = 2524
+var var2525 = 2525
+var var2526 = 2526
+var var2527 = 2527
+var var2528 = 2528
+var var2529 = 2529
+var var2530 = 2530
+var var2531 = 2531
+var var2532 = 2532
+var var2533 = 2533
+var var2534 = 2534
+var var2535 = 2535
+var var2536 = 2536
+var var2537 = 2537
+var var2538 = 2538
+var var2539 = 2539
+var var2540 = 2540
+var var2541 = 2541
+var var2542 = 2542
+var var2543 = 2543
+var var2544 = 2544
+var var2545 = 2545
+var var2546 = 2546
+var var2547 = 2547
+var var2548 = 2548
+var var2549 = 2549
+var var2550 = 2550
+var var2551 = 2551
+var var2552 = 2552
+var var2553 = 2553
+var var2554 = 2554
+var var2555 = 2555
+var var2556 = 2556
+var var2557 = 2557
+var var2558 = 2558
+var var2559 = 2559
+var var2560 = 2560
+var var2561 = 2561
+var var2562 = 2562
+var var2563 = 2563
+var var2564 = 2564
+var var2565 = 2565
+var var2566 = 2566
+var var2567 = 2567
+var var2568 = 2568
+var var2569 = 2569
+var var2570 = 2570
+var var2571 = 2571
+var var2572 = 2572
+var var2573 = 2573
+var var2574 = 2574
+var var2575 = 2575
+var var2576 = 2576
+var var2577 = 2577
+var var2578 = 2578
+var var2579 = 2579
+var var2580 = 2580
+var var2581 = 2581
+var var2582 = 2582
+var var2583 = 2583
+var var2584 = 2584
+var var2585 = 2585
+var var2586 = 2586
+var var2587 = 2587
+var var2588 = 2588
+var var2589 = 2589
+var var2590 = 2590
+var var2591 = 2591
+var var2592 = 2592
+var var2593 = 2593
+var var2594 = 2594
+var var2595 = 2595
+var var2596 = 2596
+var var2597 = 2597
+var var2598 = 2598
+var var2599 = 2599
+var var2600 = 2600
+var var2601 = 2601
+var var2602 = 2602
+var var2603 = 2603
+var var2604 = 2604
+var var2605 = 2605
+var var2606 = 2606
+var var2607 = 2607
+var var2608 = 2608
+var var2609 = 2609
+var var2610 = 2610
+var var2611 = 2611
+var var2612 = 2612
+var var2613 = 2613
+var var2614 = 2614
+var var2615 = 2615
+var var2616 = 2616
+var var2617 = 2617
+var var2618 = 2618
+var var2619 = 2619
+var var2620 = 2620
+var var2621 = 2621
+var var2622 = 2622
+var var2623 = 2623
+var var2624 = 2624
+var var2625 = 2625
+var var2626 = 2626
+var var2627 = 2627
+var var2628 = 2628
+var var2629 = 2629
+var var2630 = 2630
+var var2631 = 2631
+var var2632 = 2632
+var var2633 = 2633
+var var2634 = 2634
+var var2635 = 2635
+var var2636 = 2636
+var var2637 = 2637
+var var2638 = 2638
+var var2639 = 2639
+var var2640 = 2640
+var var2641 = 2641
+var var2642 = 2642
+var var2643 = 2643
+var var2644 = 2644
+var var2645 = 2645
+var var2646 = 2646
+var var2647 = 2647
+var var2648 = 2648
+var var2649 = 2649
+var var2650 = 2650
+var var2651 = 2651
+var var2652 = 2652
+var var2653 = 2653
+var var2654 = 2654
+var var2655 = 2655
+var var2656 = 2656
+var var2657 = 2657
+var var2658 = 2658
+var var2659 = 2659
+var var2660 = 2660
+var var2661 = 2661
+var var2662 = 2662
+var var2663 = 2663
+var var2664 = 2664
+var var2665 = 2665
+var var2666 = 2666
+var var2667 = 2667
+var var2668 = 2668
+var var2669 = 2669
+var var2670 = 2670
+var var2671 = 2671
+var var2672 = 2672
+var var2673 = 2673
+var var2674 = 2674
+var var2675 = 2675
+var var2676 = 2676
+var var2677 = 2677
+var var2678 = 2678
+var var2679 = 2679
+var var2680 = 2680
+var var2681 = 2681
+var var2682 = 2682
+var var2683 = 2683
+var var2684 = 2684
+var var2685 = 2685
+var var2686 = 2686
+var var2687 = 2687
+var var2688 = 2688
+var var2689 = 2689
+var var2690 = 2690
+var var2691 = 2691
+var var2692 = 2692
+var var2693 = 2693
+var var2694 = 2694
+var var2695 = 2695
+var var2696 = 2696
+var var2697 = 2697
+var var2698 = 2698
+var var2699 = 2699
+var var2700 = 2700
+var var2701 = 2701
+var var2702 = 2702
+var var2703 = 2703
+var var2704 = 2704
+var var2705 = 2705
+var var2706 = 2706
+var var2707 = 2707
+var var2708 = 2708
+var var2709 = 2709
+var var2710 = 2710
+var var2711 = 2711
+var var2712 = 2712
+var var2713 = 2713
+var var2714 = 2714
+var var2715 = 2715
+var var2716 = 2716
+var var2717 = 2717
+var var2718 = 2718
+var var2719 = 2719
+var var2720 = 2720
+var var2721 = 2721
+var var2722 = 2722
+var var2723 = 2723
+var var2724 = 2724
+var var2725 = 2725
+var var2726 = 2726
+var var2727 = 2727
+var var2728 = 2728
+var var2729 = 2729
+var var2730 = 2730
+var var2731 = 2731
+var var2732 = 2732
+var var2733 = 2733
+var var2734 = 2734
+var var2735 = 2735
+var var2736 = 2736
+var var2737 = 2737
+var var2738 = 2738
+var var2739 = 2739
+var var2740 = 2740
+var var2741 = 2741
+var var2742 = 2742
+var var2743 = 2743
+var var2744 = 2744
+var var2745 = 2745
+var var2746 = 2746
+var var2747 = 2747
+var var2748 = 2748
+var var2749 = 2749
+var var2750 = 2750
+var var2751 = 2751
+var var2752 = 2752
+var var2753 = 2753
+var var2754 = 2754
+var var2755 = 2755
+var var2756 = 2756
+var var2757 = 2757
+var var2758 = 2758
+var var2759 = 2759
+var var2760 = 2760
+var var2761 = 2761
+var var2762 = 2762
+var var2763 = 2763
+var var2764 = 2764
+var var2765 = 2765
+var var2766 = 2766
+var var2767 = 2767
+var var2768 = 2768
+var var2769 = 2769
+var var2770 = 2770
+var var2771 = 2771
+var var2772 = 2772
+var var2773 = 2773
+var var2774 = 2774
+var var2775 = 2775
+var var2776 = 2776
+var var2777 = 2777
+var var2778 = 2778
+var var2779 = 2779
+var var2780 = 2780
+var var2781 = 2781
+var var2782 = 2782
+var var2783 = 2783
+var var2784 = 2784
+var var2785 = 2785
+var var2786 = 2786
+var var2787 = 2787
+var var2788 = 2788
+var var2789 = 2789
+var var2790 = 2790
+var var2791 = 2791
+var var2792 = 2792
+var var2793 = 2793
+var var2794 = 2794
+var var2795 = 2795
+var var2796 = 2796
+var var2797 = 2797
+var var2798 = 2798
+var var2799 = 2799
+/*
+var var2800 = 2800
+var var2801 = 2801
+var var2802 = 2802
+var var2803 = 2803
+var var2804 = 2804
+var var2805 = 2805
+var var2806 = 2806
+var var2807 = 2807
+var var2808 = 2808
+var var2809 = 2809
+var var2810 = 2810
+var var2811 = 2811
+var var2812 = 2812
+var var2813 = 2813
+var var2814 = 2814
+var var2815 = 2815
+var var2816 = 2816
+var var2817 = 2817
+var var2818 = 2818
+var var2819 = 2819
+var var2820 = 2820
+var var2821 = 2821
+var var2822 = 2822
+var var2823 = 2823
+var var2824 = 2824
+var var2825 = 2825
+var var2826 = 2826
+var var2827 = 2827
+var var2828 = 2828
+var var2829 = 2829
+var var2830 = 2830
+var var2831 = 2831
+var var2832 = 2832
+var var2833 = 2833
+var var2834 = 2834
+var var2835 = 2835
+var var2836 = 2836
+var var2837 = 2837
+var var2838 = 2838
+var var2839 = 2839
+var var2840 = 2840
+var var2841 = 2841
+var var2842 = 2842
+var var2843 = 2843
+var var2844 = 2844
+var var2845 = 2845
+var var2846 = 2846
+var var2847 = 2847
+var var2848 = 2848
+var var2849 = 2849
+var var2850 = 2850
+var var2851 = 2851
+var var2852 = 2852
+var var2853 = 2853
+var var2854 = 2854
+var var2855 = 2855
+var var2856 = 2856
+var var2857 = 2857
+var var2858 = 2858
+var var2859 = 2859
+var var2860 = 2860
+var var2861 = 2861
+var var2862 = 2862
+var var2863 = 2863
+var var2864 = 2864
+var var2865 = 2865
+var var2866 = 2866
+var var2867 = 2867
+var var2868 = 2868
+var var2869 = 2869
+var var2870 = 2870
+var var2871 = 2871
+var var2872 = 2872
+var var2873 = 2873
+var var2874 = 2874
+var var2875 = 2875
+var var2876 = 2876
+var var2877 = 2877
+var var2878 = 2878
+var var2879 = 2879
+var var2880 = 2880
+var var2881 = 2881
+var var2882 = 2882
+var var2883 = 2883
+var var2884 = 2884
+var var2885 = 2885
+var var2886 = 2886
+var var2887 = 2887
+var var2888 = 2888
+var var2889 = 2889
+var var2890 = 2890
+var var2891 = 2891
+var var2892 = 2892
+var var2893 = 2893
+var var2894 = 2894
+var var2895 = 2895
+var var2896 = 2896
+var var2897 = 2897
+var var2898 = 2898
+var var2899 = 2899
+var var2900 = 2900
+var var2901 = 2901
+var var2902 = 2902
+var var2903 = 2903
+var var2904 = 2904
+var var2905 = 2905
+var var2906 = 2906
+var var2907 = 2907
+var var2908 = 2908
+var var2909 = 2909
+var var2910 = 2910
+var var2911 = 2911
+var var2912 = 2912
+var var2913 = 2913
+var var2914 = 2914
+var var2915 = 2915
+var var2916 = 2916
+var var2917 = 2917
+var var2918 = 2918
+var var2919 = 2919
+var var2920 = 2920
+var var2921 = 2921
+var var2922 = 2922
+var var2923 = 2923
+var var2924 = 2924
+var var2925 = 2925
+var var2926 = 2926
+var var2927 = 2927
+var var2928 = 2928
+var var2929 = 2929
+var var2930 = 2930
+var var2931 = 2931
+var var2932 = 2932
+var var2933 = 2933
+var var2934 = 2934
+var var2935 = 2935
+var var2936 = 2936
+var var2937 = 2937
+var var2938 = 2938
+var var2939 = 2939
+var var2940 = 2940
+var var2941 = 2941
+var var2942 = 2942
+var var2943 = 2943
+var var2944 = 2944
+var var2945 = 2945
+var var2946 = 2946
+var var2947 = 2947
+var var2948 = 2948
+var var2949 = 2949
+var var2950 = 2950
+var var2951 = 2951
+var var2952 = 2952
+var var2953 = 2953
+var var2954 = 2954
+var var2955 = 2955
+var var2956 = 2956
+var var2957 = 2957
+var var2958 = 2958
+var var2959 = 2959
+var var2960 = 2960
+var var2961 = 2961
+var var2962 = 2962
+var var2963 = 2963
+var var2964 = 2964
+var var2965 = 2965
+var var2966 = 2966
+var var2967 = 2967
+var var2968 = 2968
+var var2969 = 2969
+var var2970 = 2970
+var var2971 = 2971
+var var2972 = 2972
+var var2973 = 2973
+var var2974 = 2974
+var var2975 = 2975
+var var2976 = 2976
+var var2977 = 2977
+var var2978 = 2978
+var var2979 = 2979
+var var2980 = 2980
+var var2981 = 2981
+var var2982 = 2982
+var var2983 = 2983
+var var2984 = 2984
+var var2985 = 2985
+var var2986 = 2986
+var var2987 = 2987
+var var2988 = 2988
+var var2989 = 2989
+var var2990 = 2990
+var var2991 = 2991
+var var2992 = 2992
+var var2993 = 2993
+var var2994 = 2994
+var var2995 = 2995
+var var2996 = 2996
+var var2997 = 2997
+var var2998 = 2998
+var var2999 = 2999
+*/
diff --git a/nashorn/test/script/basic/NASHORN-47.js b/nashorn/test/script/basic/NASHORN-47.js
new file mode 100644
index 0000000..1454db0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-47.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-47 :  for .. in, for each.. in with "null" or undefined as iterated object should be no-ops.
+ *
+ * @test
+ * @run
+ * @un
+ */
+
+for (var i in null) {
+    print(i);
+}
+
+for (var j in undefined) {
+    print(j);
+}
+
+for each (var k in null) {
+    print(k);
+}
+
+for each (var l in null) {
+    print(l);
+}
diff --git a/nashorn/test/script/basic/NASHORN-473.js b/nashorn/test/script/basic/NASHORN-473.js
new file mode 100644
index 0000000..3819d15
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-473.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-473 : Java primitive arrays can not be iterated with for.. in and for each .. in constructs
+ *
+ * @test
+ * @run
+ */
+
+var boolArr = java.lang.reflect.Array.newInstance(java.lang.Boolean.TYPE, 2);
+boolArr[0] = true;
+boolArr[1] = false;
+
+for (i in boolArr) {
+    print(i + " -> " + boolArr[i]);
+}
+
+for each (i in boolArr) {
+    print(i);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-473.js.EXPECTED b/nashorn/test/script/basic/NASHORN-473.js.EXPECTED
new file mode 100644
index 0000000..2beb990
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-473.js.EXPECTED
@@ -0,0 +1,4 @@
+0 -> true
+1 -> false
+true
+false
diff --git a/nashorn/test/script/basic/NASHORN-474.js b/nashorn/test/script/basic/NASHORN-474.js
new file mode 100644
index 0000000..3df4aa4d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-474.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * NASHORN-474 : long index support for sparse arrays.
+ *
+ * @test
+ * @run
+ */
+
+var a = [];
+a[1] = 2;
+a[420000000] = 42;
+a[-1] = 13;
+
+print([a[420000000], a[1], a[-1]]);
+print(a.length);
+
+var b = [];
+b[0xfffffffe] = 0xfe;
+b[0xffffffff] = 0xff;
+b[-1] = -13;
+print([b[4294967294], b[4294967295], b[-1]]);
+print(b.length);
+
+var c = [,1];
+c[0x8ffffff0] = 2;
+c[0x8ffffff1] = 3;
+c[0x8fffffef] = 4;
+c[0] = 5;
+c[2] = 6;
+c[0x8ffffff3] = 7;
+print([c[0],c[1],c[2]] + ";" + [c[0x8fffffef],c[0x8ffffff0],c[0x8ffffff1],c[0x8ffffff2],c[0x8ffffff3]]);
+print(c.length);
diff --git a/nashorn/test/script/basic/NASHORN-474.js.EXPECTED b/nashorn/test/script/basic/NASHORN-474.js.EXPECTED
new file mode 100644
index 0000000..d89898b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-474.js.EXPECTED
@@ -0,0 +1,6 @@
+42,2,13
+420000001
+254,255,-13
+4294967295
+5,1,6;4,2,3,,7
+2415919092
diff --git a/nashorn/test/script/basic/NASHORN-478.js b/nashorn/test/script/basic/NASHORN-478.js
new file mode 100644
index 0000000..945d2b5
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-478.js
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-478 : Provide mozilla compatibility script for nashorn
+ *
+ * @test
+ * @run
+ */
+
+// compatibility script is loaded using "nashorn:" pseudo URL scheme
+try {
+    load('nashorn:mozilla_compat.js');
+} catch(e) {
+}
+
+var obj = {};
+if (obj.__proto__ !== Object.prototype) {
+    fail("#1 obj.__proto__ read not supported");
+}
+
+function fooGetter() { return 3.14; }
+function fooSetter(x) {}
+
+Object.defineProperty(obj, "foo", { set: fooSetter, get: fooGetter });
+if (!obj.__lookupGetter__ || obj.__lookupGetter__('foo') !== fooGetter) {
+    fail("#2 Object.prototype.__lookupGetter__ not supported");
+}
+
+if (!obj.__lookupSetter__ || obj.__lookupSetter__('foo') !== fooSetter) {
+    fail("#3 Object.prototype.__lookupSetter__ not supported");
+}
+
+function barGetter() { return 42; }
+
+if (obj.__defineGetter__) {
+    obj.__defineGetter__("bar", barGetter);
+}
+
+if (obj.bar !== 42) {
+    fail("#4 Object.prototype.__defineGetter__ not supported");
+}
+
+var barSetterCalled = false;
+function barSetter(x) {
+    barSetterCalled = true;
+}
+
+if (obj.__defineSetter__) {
+    obj.__defineSetter__("bar", barSetter);
+}
+
+obj.bar = 'hello';
+if (! barSetterCalled) {
+    fail("#5 Object.prototype.__defineSetter__ not supported");
+}
+
+var obj = { bar: 343, foo : new Boolean(true) };
+obj.self = obj;
+if (!obj.toSource ||
+    obj.toSource() !== '({bar:343, foo:(new Boolean(true)), self:{}})') {
+    fail("#6 Object.prototype.toSource method failed");
+}
+
+// check String html generation methods
+if (!'sss'.anchor || "sss".anchor("foo") !== '<a name="foo">sss</a>') {
+    fail("#7 String.prototype.anchor method failed");
+}
+
+if (!'hello'.blink || "hello".blink() !== '<blink>hello</blink>') {
+    fail("#8 String.prototype.blink method failed");
+}
+
+if (!'hello'.fixed || "hello".fixed() !== '<tt>hello</tt>') {
+    fail("#9 String.prototype.fixed method failed");
+}
+
+if (!'ss'.link || "ss".link('foo') !== '<a href="foo">ss</a>') {
+    fail("#10 String.prototype.link method failed");
+}
+
+if (typeof importClass != 'function') {
+    fail("#11 importClass function not defined");
+}
+
+importClass(java.util.HashMap);
+if (typeof HashMap != 'function') {
+    fail("#12 global.importClass method failed");
+}
+var m = new HashMap();
+m.put('foo', 'bar');
+if (m.toString() != '{foo=bar}') {
+    fail("#13 global.importClass failed to work");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-48.js b/nashorn/test/script/basic/NASHORN-48.js
new file mode 100644
index 0000000..1bbba13
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-48.js
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-48
+ *
+ * @test
+ * @run
+ */
+
+function loop3() {
+    for (var i = 0; i < 5; i++) { 
+	print(i);
+	throw "ERROR";
+    }
+    print("dead");
+}
+
+try {
+    loop3();
+} catch (e) {
+    print(e);
+}
+ 
+function loop4() {
+    var i = 0;
+    while (i++ < 5) {
+	print(i);
+	throw "ERROR";
+    }
+    print("dead");
+}
+
+try {    
+    loop4();
+} catch (e) {
+    print(e);
+}
+
+function loop5() {
+    var i = 0;
+    do {
+	print(i);
+	throw "ERROR";
+    } while (i++ < 5);
+    print("dead");
+}
+
+try {    
+    loop5();
+} catch (e) {
+    print(e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-48.js.EXPECTED b/nashorn/test/script/basic/NASHORN-48.js.EXPECTED
new file mode 100644
index 0000000..0ebc6f8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-48.js.EXPECTED
@@ -0,0 +1,6 @@
+0
+ERROR
+1
+ERROR
+0
+ERROR
diff --git a/nashorn/test/script/basic/NASHORN-481.js b/nashorn/test/script/basic/NASHORN-481.js
new file mode 100644
index 0000000..42295fa
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-481.js
@@ -0,0 +1,10035 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-481 : Array too large to initialize in a single method.
+ *
+ * @test
+ * @run
+ */
+
+var largeTable = [
+  {
+    "tag": "titillation",
+    "popularity": 4294967296
+  },
+  {
+    "tag": "foamless",
+    "popularity": 1257718401
+  },
+  {
+    "tag": "snarler",
+    "popularity": 613166183
+  },
+  {
+    "tag": "multangularness",
+    "popularity": 368304452
+  },
+  {
+    "tag": "Fesapo unventurous",
+    "popularity": 248026512
+  },
+  {
+    "tag": "esthesioblast",
+    "popularity": 179556755
+  },
+  {
+    "tag": "echeneidoid",
+    "popularity": 136641578
+  },
+  {
+    "tag": "embryoctony",
+    "popularity": 107852576
+  },
+  {
+    "tag": "undilatory",
+    "popularity": 87537981
+  },
+  {
+    "tag": "predisregard",
+    "popularity": 72630939
+  },
+  {
+    "tag": "allergenic",
+    "popularity": 61345190
+  },
+  {
+    "tag": "uncloudy",
+    "popularity": 52580571
+  },
+  {
+    "tag": "unforeseeably",
+    "popularity": 45628109
+  },
+  {
+    "tag": "sturniform",
+    "popularity": 40013489
+  },
+  {
+    "tag": "anesthetize",
+    "popularity": 35409226
+  },
+  {
+    "tag": "ametabolia",
+    "popularity": 31583050
+  },
+  {
+    "tag": "angiopathy",
+    "popularity": 28366350
+  },
+  {
+    "tag": "sultanaship",
+    "popularity": 25634218
+  },
+  {
+    "tag": "Frenchwise",
+    "popularity": 23292461
+  },
+  {
+    "tag": "cerviconasal",
+    "popularity": 21268909
+  },
+  {
+    "tag": "mercurialness",
+    "popularity": 19507481
+  },
+  {
+    "tag": "glutelin venditate",
+    "popularity": 17964042
+  },
+  {
+    "tag": "acred overblack",
+    "popularity": 16603454
+  },
+  {
+    "tag": "Atik",
+    "popularity": 15397451
+  },
+  {
+    "tag": "puncturer",
+    "popularity": 14323077
+  },
+  {
+    "tag": "pukatea",
+    "popularity": 13361525
+  },
+  {
+    "tag": "suberize",
+    "popularity": 12497261
+  },
+  {
+    "tag": "Godfrey",
+    "popularity": 11717365
+  },
+  {
+    "tag": "tetraptote",
+    "popularity": 11011011
+  },
+  {
+    "tag": "lucidness",
+    "popularity": 10369074
+  },
+  {
+    "tag": "tartness",
+    "popularity": 9783815
+  },
+  {
+    "tag": "axfetch",
+    "popularity": 9248634
+  },
+  {
+    "tag": "preacquittal",
+    "popularity": 8757877
+  },
+  {
+    "tag": "matris",
+    "popularity": 8306671
+  },
+  {
+    "tag": "hyphenate",
+    "popularity": 7890801
+  },
+  {
+    "tag": "semifabulous",
+    "popularity": 7506606
+  },
+  {
+    "tag": "oppressiveness",
+    "popularity": 7150890
+  },
+  {
+    "tag": "Protococcales",
+    "popularity": 6820856
+  },
+  {
+    "tag": "unpreventive",
+    "popularity": 6514045
+  },
+  {
+    "tag": "Cordia",
+    "popularity": 6228289
+  },
+  {
+    "tag": "Wakamba leaflike",
+    "popularity": 5961668
+  },
+  {
+    "tag": "dacryoma",
+    "popularity": 5712480
+  },
+  {
+    "tag": "inguinal",
+    "popularity": 5479211
+  },
+  {
+    "tag": "responseless",
+    "popularity": 5260507
+  },
+  {
+    "tag": "supplementarily",
+    "popularity": 5055158
+  },
+  {
+    "tag": "emu",
+    "popularity": 4862079
+  },
+  {
+    "tag": "countermeet",
+    "popularity": 4680292
+  },
+  {
+    "tag": "purrer",
+    "popularity": 4508918
+  },
+  {
+    "tag": "Corallinaceae",
+    "popularity": 4347162
+  },
+  {
+    "tag": "speculum",
+    "popularity": 4194304
+  },
+  {
+    "tag": "crimpness",
+    "popularity": 4049690
+  },
+  {
+    "tag": "antidetonant",
+    "popularity": 3912727
+  },
+  {
+    "tag": "topeewallah",
+    "popularity": 3782875
+  },
+  {
+    "tag": "fidalgo ballant",
+    "popularity": 3659640
+  },
+  {
+    "tag": "utriculose",
+    "popularity": 3542572
+  },
+  {
+    "tag": "testata",
+    "popularity": 3431259
+  },
+  {
+    "tag": "beltmaking",
+    "popularity": 3325322
+  },
+  {
+    "tag": "necrotype",
+    "popularity": 3224413
+  },
+  {
+    "tag": "ovistic",
+    "popularity": 3128215
+  },
+  {
+    "tag": "swindlership",
+    "popularity": 3036431
+  },
+  {
+    "tag": "augustal",
+    "popularity": 2948792
+  },
+  {
+    "tag": "Titoist",
+    "popularity": 2865047
+  },
+  {
+    "tag": "trisoctahedral",
+    "popularity": 2784963
+  },
+  {
+    "tag": "sequestrator",
+    "popularity": 2708327
+  },
+  {
+    "tag": "sideburns",
+    "popularity": 2634939
+  },
+  {
+    "tag": "paraphrasia",
+    "popularity": 2564616
+  },
+  {
+    "tag": "graminology unbay",
+    "popularity": 2497185
+  },
+  {
+    "tag": "acaridomatium emargination",
+    "popularity": 2432487
+  },
+  {
+    "tag": "roofward",
+    "popularity": 2370373
+  },
+  {
+    "tag": "lauder",
+    "popularity": 2310705
+  },
+  {
+    "tag": "subjunctive",
+    "popularity": 2253354
+  },
+  {
+    "tag": "subelongate",
+    "popularity": 2198199
+  },
+  {
+    "tag": "guacimo",
+    "popularity": 2145128
+  },
+  {
+    "tag": "cockade",
+    "popularity": 2094033
+  },
+  {
+    "tag": "misgauge",
+    "popularity": 2044818
+  },
+  {
+    "tag": "unexpensive",
+    "popularity": 1997388
+  },
+  {
+    "tag": "chebel",
+    "popularity": 1951657
+  },
+  {
+    "tag": "unpursuing",
+    "popularity": 1907543
+  },
+  {
+    "tag": "kilobar",
+    "popularity": 1864969
+  },
+  {
+    "tag": "obsecration",
+    "popularity": 1823863
+  },
+  {
+    "tag": "nacarine",
+    "popularity": 1784157
+  },
+  {
+    "tag": "spirituosity",
+    "popularity": 1745787
+  },
+  {
+    "tag": "movableness deity",
+    "popularity": 1708692
+  },
+  {
+    "tag": "exostracism",
+    "popularity": 1672816
+  },
+  {
+    "tag": "archipterygium",
+    "popularity": 1638104
+  },
+  {
+    "tag": "monostrophic",
+    "popularity": 1604506
+  },
+  {
+    "tag": "gynecide",
+    "popularity": 1571974
+  },
+  {
+    "tag": "gladden",
+    "popularity": 1540462
+  },
+  {
+    "tag": "throughbred",
+    "popularity": 1509927
+  },
+  {
+    "tag": "groper",
+    "popularity": 1480329
+  },
+  {
+    "tag": "Xenosaurus",
+    "popularity": 1451628
+  },
+  {
+    "tag": "photoetcher",
+    "popularity": 1423788
+  },
+  {
+    "tag": "glucosid",
+    "popularity": 1396775
+  },
+  {
+    "tag": "Galtonian",
+    "popularity": 1370555
+  },
+  {
+    "tag": "mesosporic",
+    "popularity": 1345097
+  },
+  {
+    "tag": "theody",
+    "popularity": 1320370
+  },
+  {
+    "tag": "zaffer",
+    "popularity": 1296348
+  },
+  {
+    "tag": "probiology",
+    "popularity": 1273003
+  },
+  {
+    "tag": "rhizomic",
+    "popularity": 1250308
+  },
+  {
+    "tag": "superphosphate",
+    "popularity": 1228240
+  },
+  {
+    "tag": "Hippolytan",
+    "popularity": 1206776
+  },
+  {
+    "tag": "garget",
+    "popularity": 1185892
+  },
+  {
+    "tag": "diploplacula",
+    "popularity": 1165568
+  },
+  {
+    "tag": "orohydrographical",
+    "popularity": 1145785
+  },
+  {
+    "tag": "enhypostatize",
+    "popularity": 1126521
+  },
+  {
+    "tag": "polisman",
+    "popularity": 1107759
+  },
+  {
+    "tag": "acetometer",
+    "popularity": 1089482
+  },
+  {
+    "tag": "unsnatched",
+    "popularity": 1071672
+  },
+  {
+    "tag": "yabber",
+    "popularity": 1054313
+  },
+  {
+    "tag": "demiwolf",
+    "popularity": 1037390
+  },
+  {
+    "tag": "chromascope",
+    "popularity": 1020888
+  },
+  {
+    "tag": "seamanship",
+    "popularity": 1004794
+  },
+  {
+    "tag": "nonfenestrated",
+    "popularity": 989092
+  },
+  {
+    "tag": "hydrophytism",
+    "popularity": 973771
+  },
+  {
+    "tag": "dotter",
+    "popularity": 958819
+  },
+  {
+    "tag": "thermoperiodism",
+    "popularity": 944222
+  },
+  {
+    "tag": "unlawyerlike",
+    "popularity": 929970
+  },
+  {
+    "tag": "enantiomeride citywards",
+    "popularity": 916052
+  },
+  {
+    "tag": "unmetallurgical",
+    "popularity": 902456
+  },
+  {
+    "tag": "prickled",
+    "popularity": 889174
+  },
+  {
+    "tag": "strangerwise manioc",
+    "popularity": 876195
+  },
+  {
+    "tag": "incisorial",
+    "popularity": 863510
+  },
+  {
+    "tag": "irrationalize",
+    "popularity": 851110
+  },
+  {
+    "tag": "nasology",
+    "popularity": 838987
+  },
+  {
+    "tag": "fatuism",
+    "popularity": 827131
+  },
+  {
+    "tag": "Huk",
+    "popularity": 815535
+  },
+  {
+    "tag": "properispomenon",
+    "popularity": 804192
+  },
+  {
+    "tag": "unpummelled",
+    "popularity": 793094
+  },
+  {
+    "tag": "technographically",
+    "popularity": 782233
+  },
+  {
+    "tag": "underfurnish",
+    "popularity": 771603
+  },
+  {
+    "tag": "sinter",
+    "popularity": 761198
+  },
+  {
+    "tag": "lateroanterior",
+    "popularity": 751010
+  },
+  {
+    "tag": "nonpersonification",
+    "popularity": 741034
+  },
+  {
+    "tag": "Sitophilus",
+    "popularity": 731264
+  },
+  {
+    "tag": "unstudded overexerted",
+    "popularity": 721694
+  },
+  {
+    "tag": "tracheation",
+    "popularity": 712318
+  },
+  {
+    "tag": "thirteenth begloze",
+    "popularity": 703131
+  },
+  {
+    "tag": "bespice",
+    "popularity": 694129
+  },
+  {
+    "tag": "doppia",
+    "popularity": 685305
+  },
+  {
+    "tag": "unadorned",
+    "popularity": 676656
+  },
+  {
+    "tag": "dovelet engraff",
+    "popularity": 668176
+  },
+  {
+    "tag": "diphyozooid",
+    "popularity": 659862
+  },
+  {
+    "tag": "mure",
+    "popularity": 651708
+  },
+  {
+    "tag": "Tripitaka",
+    "popularity": 643710
+  },
+  {
+    "tag": "Billjim",
+    "popularity": 635865
+  },
+  {
+    "tag": "pyramidical",
+    "popularity": 628169
+  },
+  {
+    "tag": "circumlocutionist",
+    "popularity": 620617
+  },
+  {
+    "tag": "slapstick",
+    "popularity": 613207
+  },
+  {
+    "tag": "preobedience",
+    "popularity": 605934
+  },
+  {
+    "tag": "unfriarlike",
+    "popularity": 598795
+  },
+  {
+    "tag": "microchromosome",
+    "popularity": 591786
+  },
+  {
+    "tag": "Orphicism",
+    "popularity": 584905
+  },
+  {
+    "tag": "peel",
+    "popularity": 578149
+  },
+  {
+    "tag": "obediential",
+    "popularity": 571514
+  },
+  {
+    "tag": "Peripatidea",
+    "popularity": 564997
+  },
+  {
+    "tag": "undoubtful",
+    "popularity": 558596
+  },
+  {
+    "tag": "lodgeable",
+    "popularity": 552307
+  },
+  {
+    "tag": "pustulated woodchat",
+    "popularity": 546129
+  },
+  {
+    "tag": "antepast",
+    "popularity": 540057
+  },
+  {
+    "tag": "sagittoid matrimoniously",
+    "popularity": 534091
+  },
+  {
+    "tag": "Albizzia",
+    "popularity": 528228
+  },
+  {
+    "tag": "Elateridae unnewness",
+    "popularity": 522464
+  },
+  {
+    "tag": "convertingness",
+    "popularity": 516798
+  },
+  {
+    "tag": "Pelew",
+    "popularity": 511228
+  },
+  {
+    "tag": "recapitulation",
+    "popularity": 505751
+  },
+  {
+    "tag": "shack",
+    "popularity": 500365
+  },
+  {
+    "tag": "unmellowed",
+    "popularity": 495069
+  },
+  {
+    "tag": "pavis capering",
+    "popularity": 489859
+  },
+  {
+    "tag": "fanfare",
+    "popularity": 484735
+  },
+  {
+    "tag": "sole",
+    "popularity": 479695
+  },
+  {
+    "tag": "subarcuate",
+    "popularity": 474735
+  },
+  {
+    "tag": "multivious",
+    "popularity": 469856
+  },
+  {
+    "tag": "squandermania",
+    "popularity": 465054
+  },
+  {
+    "tag": "scintle",
+    "popularity": 460329
+  },
+  {
+    "tag": "hash chirognomic",
+    "popularity": 455679
+  },
+  {
+    "tag": "linseed",
+    "popularity": 451101
+  },
+  {
+    "tag": "redoubtable",
+    "popularity": 446596
+  },
+  {
+    "tag": "poachy reimpact",
+    "popularity": 442160
+  },
+  {
+    "tag": "limestone",
+    "popularity": 437792
+  },
+  {
+    "tag": "serranid",
+    "popularity": 433492
+  },
+  {
+    "tag": "pohna",
+    "popularity": 429258
+  },
+  {
+    "tag": "warwolf",
+    "popularity": 425088
+  },
+  {
+    "tag": "ruthenous",
+    "popularity": 420981
+  },
+  {
+    "tag": "dover",
+    "popularity": 416935
+  },
+  {
+    "tag": "deuteroalbumose",
+    "popularity": 412950
+  },
+  {
+    "tag": "pseudoprophetic",
+    "popularity": 409025
+  },
+  {
+    "tag": "dissoluteness",
+    "popularity": 405157
+  },
+  {
+    "tag": "preinvention",
+    "popularity": 401347
+  },
+  {
+    "tag": "swagbellied",
+    "popularity": 397592
+  },
+  {
+    "tag": "Ophidia",
+    "popularity": 393892
+  },
+  {
+    "tag": "equanimity",
+    "popularity": 390245
+  },
+  {
+    "tag": "troutful",
+    "popularity": 386651
+  },
+  {
+    "tag": "uke",
+    "popularity": 383108
+  },
+  {
+    "tag": "preacquaint",
+    "popularity": 379616
+  },
+  {
+    "tag": "shoq",
+    "popularity": 376174
+  },
+  {
+    "tag": "yox",
+    "popularity": 372780
+  },
+  {
+    "tag": "unelemental",
+    "popularity": 369434
+  },
+  {
+    "tag": "Yavapai",
+    "popularity": 366134
+  },
+  {
+    "tag": "joulean",
+    "popularity": 362880
+  },
+  {
+    "tag": "dracontine",
+    "popularity": 359672
+  },
+  {
+    "tag": "hardmouth",
+    "popularity": 356507
+  },
+  {
+    "tag": "sylvanize",
+    "popularity": 353386
+  },
+  {
+    "tag": "intraparenchymatous meadowbur",
+    "popularity": 350308
+  },
+  {
+    "tag": "uncharily",
+    "popularity": 347271
+  },
+  {
+    "tag": "redtab flexibly",
+    "popularity": 344275
+  },
+  {
+    "tag": "centervelic",
+    "popularity": 341319
+  },
+  {
+    "tag": "unravellable",
+    "popularity": 338403
+  },
+  {
+    "tag": "infortunately",
+    "popularity": 335526
+  },
+  {
+    "tag": "cannel",
+    "popularity": 332687
+  },
+  {
+    "tag": "oxyblepsia",
+    "popularity": 329885
+  },
+  {
+    "tag": "Damon",
+    "popularity": 327120
+  },
+  {
+    "tag": "etherin",
+    "popularity": 324391
+  },
+  {
+    "tag": "luminal",
+    "popularity": 321697
+  },
+  {
+    "tag": "interrogatorily presbyte",
+    "popularity": 319038
+  },
+  {
+    "tag": "hemiclastic",
+    "popularity": 316414
+  },
+  {
+    "tag": "poh flush",
+    "popularity": 313823
+  },
+  {
+    "tag": "Psoroptes",
+    "popularity": 311265
+  },
+  {
+    "tag": "dispirit",
+    "popularity": 308740
+  },
+  {
+    "tag": "nashgab",
+    "popularity": 306246
+  },
+  {
+    "tag": "Aphidiinae",
+    "popularity": 303784
+  },
+  {
+    "tag": "rhapsody nonconstruction",
+    "popularity": 301353
+  },
+  {
+    "tag": "Osmond",
+    "popularity": 298952
+  },
+  {
+    "tag": "Leonis",
+    "popularity": 296581
+  },
+  {
+    "tag": "Lemnian",
+    "popularity": 294239
+  },
+  {
+    "tag": "acetonic gnathonic",
+    "popularity": 291926
+  },
+  {
+    "tag": "surculus",
+    "popularity": 289641
+  },
+  {
+    "tag": "diagonally",
+    "popularity": 287384
+  },
+  {
+    "tag": "counterpenalty",
+    "popularity": 285154
+  },
+  {
+    "tag": "Eugenie",
+    "popularity": 282952
+  },
+  {
+    "tag": "hornbook",
+    "popularity": 280776
+  },
+  {
+    "tag": "miscoin",
+    "popularity": 278626
+  },
+  {
+    "tag": "admi",
+    "popularity": 276501
+  },
+  {
+    "tag": "Tarmac",
+    "popularity": 274402
+  },
+  {
+    "tag": "inexplicable",
+    "popularity": 272328
+  },
+  {
+    "tag": "rascallion",
+    "popularity": 270278
+  },
+  {
+    "tag": "dusterman",
+    "popularity": 268252
+  },
+  {
+    "tag": "osteostomous unhoroscopic",
+    "popularity": 266250
+  },
+  {
+    "tag": "spinibulbar",
+    "popularity": 264271
+  },
+  {
+    "tag": "phototelegraphically",
+    "popularity": 262315
+  },
+  {
+    "tag": "Manihot",
+    "popularity": 260381
+  },
+  {
+    "tag": "neighborhood",
+    "popularity": 258470
+  },
+  {
+    "tag": "Vincetoxicum",
+    "popularity": 256581
+  },
+  {
+    "tag": "khirka",
+    "popularity": 254713
+  },
+  {
+    "tag": "conscriptive",
+    "popularity": 252866
+  },
+  {
+    "tag": "synechthran",
+    "popularity": 251040
+  },
+  {
+    "tag": "Guttiferales",
+    "popularity": 249235
+  },
+  {
+    "tag": "roomful",
+    "popularity": 247450
+  },
+  {
+    "tag": "germinal",
+    "popularity": 245685
+  },
+  {
+    "tag": "untraitorous",
+    "popularity": 243939
+  },
+  {
+    "tag": "nondissenting",
+    "popularity": 242213
+  },
+  {
+    "tag": "amotion",
+    "popularity": 240506
+  },
+  {
+    "tag": "badious",
+    "popularity": 238817
+  },
+  {
+    "tag": "sumpit",
+    "popularity": 237147
+  },
+  {
+    "tag": "ectozoic",
+    "popularity": 235496
+  },
+  {
+    "tag": "elvet",
+    "popularity": 233862
+  },
+  {
+    "tag": "underclerk",
+    "popularity": 232246
+  },
+  {
+    "tag": "reticency",
+    "popularity": 230647
+  },
+  {
+    "tag": "neutroclusion",
+    "popularity": 229065
+  },
+  {
+    "tag": "unbelieving",
+    "popularity": 227500
+  },
+  {
+    "tag": "histogenetic",
+    "popularity": 225952
+  },
+  {
+    "tag": "dermamyiasis",
+    "popularity": 224421
+  },
+  {
+    "tag": "telenergy",
+    "popularity": 222905
+  },
+  {
+    "tag": "axiomatic",
+    "popularity": 221406
+  },
+  {
+    "tag": "undominoed",
+    "popularity": 219922
+  },
+  {
+    "tag": "periosteoma",
+    "popularity": 218454
+  },
+  {
+    "tag": "justiciaryship",
+    "popularity": 217001
+  },
+  {
+    "tag": "autoluminescence",
+    "popularity": 215563
+  },
+  {
+    "tag": "osmous",
+    "popularity": 214140
+  },
+  {
+    "tag": "borgh",
+    "popularity": 212731
+  },
+  {
+    "tag": "bedebt",
+    "popularity": 211337
+  },
+  {
+    "tag": "considerableness adenoidism",
+    "popularity": 209957
+  },
+  {
+    "tag": "sailorizing",
+    "popularity": 208592
+  },
+  {
+    "tag": "Montauk",
+    "popularity": 207240
+  },
+  {
+    "tag": "Bridget",
+    "popularity": 205901
+  },
+  {
+    "tag": "Gekkota",
+    "popularity": 204577
+  },
+  {
+    "tag": "subcorymbose",
+    "popularity": 203265
+  },
+  {
+    "tag": "undersap",
+    "popularity": 201967
+  },
+  {
+    "tag": "poikilothermic",
+    "popularity": 200681
+  },
+  {
+    "tag": "enneatical",
+    "popularity": 199409
+  },
+  {
+    "tag": "martinetism",
+    "popularity": 198148
+  },
+  {
+    "tag": "sustanedly",
+    "popularity": 196901
+  },
+  {
+    "tag": "declaration",
+    "popularity": 195665
+  },
+  {
+    "tag": "myringoplasty",
+    "popularity": 194442
+  },
+  {
+    "tag": "Ginkgo",
+    "popularity": 193230
+  },
+  {
+    "tag": "unrecurrent",
+    "popularity": 192031
+  },
+  {
+    "tag": "proprecedent",
+    "popularity": 190843
+  },
+  {
+    "tag": "roadman",
+    "popularity": 189666
+  },
+  {
+    "tag": "elemin",
+    "popularity": 188501
+  },
+  {
+    "tag": "maggot",
+    "popularity": 187347
+  },
+  {
+    "tag": "alitrunk",
+    "popularity": 186204
+  },
+  {
+    "tag": "introspection",
+    "popularity": 185071
+  },
+  {
+    "tag": "batiker",
+    "popularity": 183950
+  },
+  {
+    "tag": "backhatch oversettle",
+    "popularity": 182839
+  },
+  {
+    "tag": "thresherman",
+    "popularity": 181738
+  },
+  {
+    "tag": "protemperance",
+    "popularity": 180648
+  },
+  {
+    "tag": "undern",
+    "popularity": 179568
+  },
+  {
+    "tag": "tweeg",
+    "popularity": 178498
+  },
+  {
+    "tag": "crosspath",
+    "popularity": 177438
+  },
+  {
+    "tag": "Tangaridae",
+    "popularity": 176388
+  },
+  {
+    "tag": "scrutation",
+    "popularity": 175348
+  },
+  {
+    "tag": "piecemaker",
+    "popularity": 174317
+  },
+  {
+    "tag": "paster",
+    "popularity": 173296
+  },
+  {
+    "tag": "unpretendingness",
+    "popularity": 172284
+  },
+  {
+    "tag": "inframundane",
+    "popularity": 171281
+  },
+  {
+    "tag": "kiblah",
+    "popularity": 170287
+  },
+  {
+    "tag": "playwrighting",
+    "popularity": 169302
+  },
+  {
+    "tag": "gonepoiesis snowslip",
+    "popularity": 168326
+  },
+  {
+    "tag": "hoodwise",
+    "popularity": 167359
+  },
+  {
+    "tag": "postseason",
+    "popularity": 166401
+  },
+  {
+    "tag": "equivocality",
+    "popularity": 165451
+  },
+  {
+    "tag": "Opiliaceae nuclease",
+    "popularity": 164509
+  },
+  {
+    "tag": "sextipara",
+    "popularity": 163576
+  },
+  {
+    "tag": "weeper",
+    "popularity": 162651
+  },
+  {
+    "tag": "frambesia",
+    "popularity": 161735
+  },
+  {
+    "tag": "answerable",
+    "popularity": 160826
+  },
+  {
+    "tag": "Trichosporum",
+    "popularity": 159925
+  },
+  {
+    "tag": "cajuputol",
+    "popularity": 159033
+  },
+  {
+    "tag": "pleomorphous",
+    "popularity": 158148
+  },
+  {
+    "tag": "aculeolate",
+    "popularity": 157270
+  },
+  {
+    "tag": "wherever",
+    "popularity": 156400
+  },
+  {
+    "tag": "collapse",
+    "popularity": 155538
+  },
+  {
+    "tag": "porky",
+    "popularity": 154683
+  },
+  {
+    "tag": "perule",
+    "popularity": 153836
+  },
+  {
+    "tag": "Nevada",
+    "popularity": 152996
+  },
+  {
+    "tag": "conalbumin",
+    "popularity": 152162
+  },
+  {
+    "tag": "tsunami",
+    "popularity": 151336
+  },
+  {
+    "tag": "Gulf",
+    "popularity": 150517
+  },
+  {
+    "tag": "hertz",
+    "popularity": 149705
+  },
+  {
+    "tag": "limmock",
+    "popularity": 148900
+  },
+  {
+    "tag": "Tartarize",
+    "popularity": 148101
+  },
+  {
+    "tag": "entosphenoid",
+    "popularity": 147310
+  },
+  {
+    "tag": "ibis",
+    "popularity": 146524
+  },
+  {
+    "tag": "unyeaned",
+    "popularity": 145746
+  },
+  {
+    "tag": "tritural",
+    "popularity": 144973
+  },
+  {
+    "tag": "hundredary",
+    "popularity": 144207
+  },
+  {
+    "tag": "stolonlike",
+    "popularity": 143448
+  },
+  {
+    "tag": "chorister",
+    "popularity": 142694
+  },
+  {
+    "tag": "mismove",
+    "popularity": 141947
+  },
+  {
+    "tag": "Andine",
+    "popularity": 141206
+  },
+  {
+    "tag": "Annette proneur escribe",
+    "popularity": 140471
+  },
+  {
+    "tag": "exoperidium",
+    "popularity": 139742
+  },
+  {
+    "tag": "disedge",
+    "popularity": 139019
+  },
+  {
+    "tag": "hypochloruria",
+    "popularity": 138302
+  },
+  {
+    "tag": "prepupa",
+    "popularity": 137590
+  },
+  {
+    "tag": "assent",
+    "popularity": 136884
+  },
+  {
+    "tag": "hydrazobenzene",
+    "popularity": 136184
+  },
+  {
+    "tag": "emballonurid",
+    "popularity": 135489
+  },
+  {
+    "tag": "roselle",
+    "popularity": 134800
+  },
+  {
+    "tag": "unifiedly",
+    "popularity": 134117
+  },
+  {
+    "tag": "clang",
+    "popularity": 133439
+  },
+  {
+    "tag": "acetolytic",
+    "popularity": 132766
+  },
+  {
+    "tag": "cladodont",
+    "popularity": 132098
+  },
+  {
+    "tag": "recoast",
+    "popularity": 131436
+  },
+  {
+    "tag": "celebrated tydie Eocarboniferous",
+    "popularity": 130779
+  },
+  {
+    "tag": "superconsciousness",
+    "popularity": 130127
+  },
+  {
+    "tag": "soberness",
+    "popularity": 129480
+  },
+  {
+    "tag": "panoramist",
+    "popularity": 128838
+  },
+  {
+    "tag": "Orbitolina",
+    "popularity": 128201
+  },
+  {
+    "tag": "overlewd",
+    "popularity": 127569
+  },
+  {
+    "tag": "demiquaver",
+    "popularity": 126942
+  },
+  {
+    "tag": "kamelaukion",
+    "popularity": 126319
+  },
+  {
+    "tag": "flancard",
+    "popularity": 125702
+  },
+  {
+    "tag": "tricuspid",
+    "popularity": 125089
+  },
+  {
+    "tag": "bepelt",
+    "popularity": 124480
+  },
+  {
+    "tag": "decuplet",
+    "popularity": 123877
+  },
+  {
+    "tag": "Rockies",
+    "popularity": 123278
+  },
+  {
+    "tag": "unforgeability",
+    "popularity": 122683
+  },
+  {
+    "tag": "mocha",
+    "popularity": 122093
+  },
+  {
+    "tag": "scrunge",
+    "popularity": 121507
+  },
+  {
+    "tag": "delighter",
+    "popularity": 120926
+  },
+  {
+    "tag": "willey Microtinae",
+    "popularity": 120349
+  },
+  {
+    "tag": "unhuntable",
+    "popularity": 119777
+  },
+  {
+    "tag": "historically",
+    "popularity": 119208
+  },
+  {
+    "tag": "vicegerentship",
+    "popularity": 118644
+  },
+  {
+    "tag": "hemangiosarcoma",
+    "popularity": 118084
+  },
+  {
+    "tag": "harpago",
+    "popularity": 117528
+  },
+  {
+    "tag": "unionoid",
+    "popularity": 116976
+  },
+  {
+    "tag": "wiseman",
+    "popularity": 116429
+  },
+  {
+    "tag": "diclinism",
+    "popularity": 115885
+  },
+  {
+    "tag": "Maud",
+    "popularity": 115345
+  },
+  {
+    "tag": "scaphocephalism",
+    "popularity": 114809
+  },
+  {
+    "tag": "obtenebration",
+    "popularity": 114277
+  },
+  {
+    "tag": "cymar predreadnought",
+    "popularity": 113749
+  },
+  {
+    "tag": "discommend",
+    "popularity": 113225
+  },
+  {
+    "tag": "crude",
+    "popularity": 112704
+  },
+  {
+    "tag": "upflash",
+    "popularity": 112187
+  },
+  {
+    "tag": "saltimbank",
+    "popularity": 111674
+  },
+  {
+    "tag": "posthysterical",
+    "popularity": 111165
+  },
+  {
+    "tag": "trample",
+    "popularity": 110659
+  },
+  {
+    "tag": "ungirthed",
+    "popularity": 110157
+  },
+  {
+    "tag": "unshakable",
+    "popularity": 109658
+  },
+  {
+    "tag": "hepatocystic",
+    "popularity": 109163
+  },
+  {
+    "tag": "psammophyte",
+    "popularity": 108671
+  },
+  {
+    "tag": "millionfold",
+    "popularity": 108183
+  },
+  {
+    "tag": "outtaste",
+    "popularity": 107698
+  },
+  {
+    "tag": "poppycockish",
+    "popularity": 107217
+  },
+  {
+    "tag": "viduine",
+    "popularity": 106739
+  },
+  {
+    "tag": "pleasureman",
+    "popularity": 106264
+  },
+  {
+    "tag": "cholesterolemia",
+    "popularity": 105792
+  },
+  {
+    "tag": "hostlerwife",
+    "popularity": 105324
+  },
+  {
+    "tag": "figure undergrass",
+    "popularity": 104859
+  },
+  {
+    "tag": "bedrape",
+    "popularity": 104398
+  },
+  {
+    "tag": "nuttishness",
+    "popularity": 103939
+  },
+  {
+    "tag": "fow",
+    "popularity": 103484
+  },
+  {
+    "tag": "rachianesthesia",
+    "popularity": 103031
+  },
+  {
+    "tag": "recruitable",
+    "popularity": 102582
+  },
+  {
+    "tag": "semianatomical Oenotheraceae",
+    "popularity": 102136
+  },
+  {
+    "tag": "extracapsular",
+    "popularity": 101693
+  },
+  {
+    "tag": "unsigneted",
+    "popularity": 101253
+  },
+  {
+    "tag": "fissural",
+    "popularity": 100816
+  },
+  {
+    "tag": "ayous",
+    "popularity": 100381
+  },
+  {
+    "tag": "crestfallenness odontograph",
+    "popularity": 99950
+  },
+  {
+    "tag": "monopodium",
+    "popularity": 99522
+  },
+  {
+    "tag": "germfree",
+    "popularity": 99096
+  },
+  {
+    "tag": "dauphin",
+    "popularity": 98673
+  },
+  {
+    "tag": "nonagesimal",
+    "popularity": 98254
+  },
+  {
+    "tag": "waterchat",
+    "popularity": 97836
+  },
+  {
+    "tag": "Entelodon",
+    "popularity": 97422
+  },
+  {
+    "tag": "semischolastic",
+    "popularity": 97010
+  },
+  {
+    "tag": "somata",
+    "popularity": 96602
+  },
+  {
+    "tag": "expositorily",
+    "popularity": 96195
+  },
+  {
+    "tag": "bass",
+    "popularity": 95792
+  },
+  {
+    "tag": "calorimetry",
+    "popularity": 95391
+  },
+  {
+    "tag": "entireness",
+    "popularity": 94993
+  },
+  {
+    "tag": "ratline soppiness",
+    "popularity": 94597
+  },
+  {
+    "tag": "shor",
+    "popularity": 94204
+  },
+  {
+    "tag": "coprecipitation",
+    "popularity": 93813
+  },
+  {
+    "tag": "unblushingly",
+    "popularity": 93425
+  },
+  {
+    "tag": "macarize",
+    "popularity": 93040
+  },
+  {
+    "tag": "scruplesomeness",
+    "popularity": 92657
+  },
+  {
+    "tag": "offsaddle",
+    "popularity": 92276
+  },
+  {
+    "tag": "hypertragical",
+    "popularity": 91898
+  },
+  {
+    "tag": "uncassock loined",
+    "popularity": 91522
+  },
+  {
+    "tag": "interlobate",
+    "popularity": 91149
+  },
+  {
+    "tag": "releasor orrisroot stoloniferously",
+    "popularity": 90778
+  },
+  {
+    "tag": "elementoid",
+    "popularity": 90410
+  },
+  {
+    "tag": "Lentilla",
+    "popularity": 90043
+  },
+  {
+    "tag": "distressing",
+    "popularity": 89679
+  },
+  {
+    "tag": "hydrodrome",
+    "popularity": 89318
+  },
+  {
+    "tag": "Jeannette",
+    "popularity": 88958
+  },
+  {
+    "tag": "Kuli",
+    "popularity": 88601
+  },
+  {
+    "tag": "taxinomist",
+    "popularity": 88246
+  },
+  {
+    "tag": "southwestwardly",
+    "popularity": 87894
+  },
+  {
+    "tag": "polyparia",
+    "popularity": 87543
+  },
+  {
+    "tag": "exmeridian",
+    "popularity": 87195
+  },
+  {
+    "tag": "splenius regimentaled",
+    "popularity": 86849
+  },
+  {
+    "tag": "Sphaeropsidaceae",
+    "popularity": 86505
+  },
+  {
+    "tag": "unbegun",
+    "popularity": 86163
+  },
+  {
+    "tag": "something",
+    "popularity": 85823
+  },
+  {
+    "tag": "contaminable nonexpulsion",
+    "popularity": 85486
+  },
+  {
+    "tag": "douser",
+    "popularity": 85150
+  },
+  {
+    "tag": "prostrike",
+    "popularity": 84817
+  },
+  {
+    "tag": "worky",
+    "popularity": 84485
+  },
+  {
+    "tag": "folliful",
+    "popularity": 84156
+  },
+  {
+    "tag": "prioracy",
+    "popularity": 83828
+  },
+  {
+    "tag": "undermentioned",
+    "popularity": 83503
+  },
+  {
+    "tag": "Judaica",
+    "popularity": 83179
+  },
+  {
+    "tag": "multifarious",
+    "popularity": 82858
+  },
+  {
+    "tag": "poogye",
+    "popularity": 82538
+  },
+  {
+    "tag": "Sparganium",
+    "popularity": 82221
+  },
+  {
+    "tag": "thurrock",
+    "popularity": 81905
+  },
+  {
+    "tag": "outblush",
+    "popularity": 81591
+  },
+  {
+    "tag": "Strophanthus supraordination",
+    "popularity": 81279
+  },
+  {
+    "tag": "gingerroot",
+    "popularity": 80969
+  },
+  {
+    "tag": "unconscient",
+    "popularity": 80661
+  },
+  {
+    "tag": "unconstitutionally",
+    "popularity": 80354
+  },
+  {
+    "tag": "plaguily",
+    "popularity": 80050
+  },
+  {
+    "tag": "waterily equatorwards",
+    "popularity": 79747
+  },
+  {
+    "tag": "nondeposition",
+    "popularity": 79446
+  },
+  {
+    "tag": "dronishly",
+    "popularity": 79147
+  },
+  {
+    "tag": "gateado",
+    "popularity": 78849
+  },
+  {
+    "tag": "dislink",
+    "popularity": 78553
+  },
+  {
+    "tag": "Joceline",
+    "popularity": 78259
+  },
+  {
+    "tag": "amphiboliferous",
+    "popularity": 77967
+  },
+  {
+    "tag": "bushrope",
+    "popularity": 77676
+  },
+  {
+    "tag": "plumicorn sulphosalicylic",
+    "popularity": 77387
+  },
+  {
+    "tag": "nonefficiency",
+    "popularity": 77100
+  },
+  {
+    "tag": "hieroscopy",
+    "popularity": 76815
+  },
+  {
+    "tag": "causativeness",
+    "popularity": 76531
+  },
+  {
+    "tag": "swird paleoeremology",
+    "popularity": 76249
+  },
+  {
+    "tag": "camphoric",
+    "popularity": 75968
+  },
+  {
+    "tag": "retaining",
+    "popularity": 75689
+  },
+  {
+    "tag": "thyreoprotein",
+    "popularity": 75411
+  },
+  {
+    "tag": "carbona",
+    "popularity": 75136
+  },
+  {
+    "tag": "protectively",
+    "popularity": 74861
+  },
+  {
+    "tag": "mosasaur",
+    "popularity": 74589
+  },
+  {
+    "tag": "reciprocator",
+    "popularity": 74317
+  },
+  {
+    "tag": "detentive",
+    "popularity": 74048
+  },
+  {
+    "tag": "supravital",
+    "popularity": 73780
+  },
+  {
+    "tag": "Vespertilionidae",
+    "popularity": 73513
+  },
+  {
+    "tag": "parka",
+    "popularity": 73248
+  },
+  {
+    "tag": "pickaway",
+    "popularity": 72984
+  },
+  {
+    "tag": "oleaceous",
+    "popularity": 72722
+  },
+  {
+    "tag": "anticogitative",
+    "popularity": 72462
+  },
+  {
+    "tag": "woe",
+    "popularity": 72203
+  },
+  {
+    "tag": "skeuomorph",
+    "popularity": 71945
+  },
+  {
+    "tag": "helpmeet",
+    "popularity": 71689
+  },
+  {
+    "tag": "Hexactinellida brickmaking",
+    "popularity": 71434
+  },
+  {
+    "tag": "resink",
+    "popularity": 71180
+  },
+  {
+    "tag": "diluter",
+    "popularity": 70928
+  },
+  {
+    "tag": "micromicron",
+    "popularity": 70677
+  },
+  {
+    "tag": "parentage",
+    "popularity": 70428
+  },
+  {
+    "tag": "galactorrhoea",
+    "popularity": 70180
+  },
+  {
+    "tag": "gey",
+    "popularity": 69934
+  },
+  {
+    "tag": "gesticulatory",
+    "popularity": 69689
+  },
+  {
+    "tag": "wergil",
+    "popularity": 69445
+  },
+  {
+    "tag": "Lecanora",
+    "popularity": 69202
+  },
+  {
+    "tag": "malanders karst",
+    "popularity": 68961
+  },
+  {
+    "tag": "vibetoite",
+    "popularity": 68721
+  },
+  {
+    "tag": "unrequitedness",
+    "popularity": 68483
+  },
+  {
+    "tag": "outwash",
+    "popularity": 68245
+  },
+  {
+    "tag": "unsacred",
+    "popularity": 68009
+  },
+  {
+    "tag": "unabetted dividend",
+    "popularity": 67775
+  },
+  {
+    "tag": "untraveling",
+    "popularity": 67541
+  },
+  {
+    "tag": "thermobattery",
+    "popularity": 67309
+  },
+  {
+    "tag": "polypragmist",
+    "popularity": 67078
+  },
+  {
+    "tag": "irrefutableness",
+    "popularity": 66848
+  },
+  {
+    "tag": "remiges",
+    "popularity": 66620
+  },
+  {
+    "tag": "implode",
+    "popularity": 66393
+  },
+  {
+    "tag": "superfluousness",
+    "popularity": 66166
+  },
+  {
+    "tag": "croakily unalleviated",
+    "popularity": 65942
+  },
+  {
+    "tag": "edicule",
+    "popularity": 65718
+  },
+  {
+    "tag": "entophytous",
+    "popularity": 65495
+  },
+  {
+    "tag": "benefactorship Toryish",
+    "popularity": 65274
+  },
+  {
+    "tag": "pseudoamateurish",
+    "popularity": 65054
+  },
+  {
+    "tag": "flueless Iguanodontoidea snipnose",
+    "popularity": 64835
+  },
+  {
+    "tag": "zealotical Zamicrus interpole",
+    "popularity": 64617
+  },
+  {
+    "tag": "whereabout",
+    "popularity": 64401
+  },
+  {
+    "tag": "benzazide",
+    "popularity": 64185
+  },
+  {
+    "tag": "pokeweed",
+    "popularity": 63971
+  },
+  {
+    "tag": "calamitoid",
+    "popularity": 63757
+  },
+  {
+    "tag": "sporozoal",
+    "popularity": 63545
+  },
+  {
+    "tag": "physcioid Welshwoman",
+    "popularity": 63334
+  },
+  {
+    "tag": "wanting",
+    "popularity": 63124
+  },
+  {
+    "tag": "unencumbering",
+    "popularity": 62915
+  },
+  {
+    "tag": "Tupi",
+    "popularity": 62707
+  },
+  {
+    "tag": "potbank",
+    "popularity": 62501
+  },
+  {
+    "tag": "bulked",
+    "popularity": 62295
+  },
+  {
+    "tag": "uparise",
+    "popularity": 62090
+  },
+  {
+    "tag": "Sudra",
+    "popularity": 61887
+  },
+  {
+    "tag": "hyperscrupulosity",
+    "popularity": 61684
+  },
+  {
+    "tag": "subterraneously unmaid",
+    "popularity": 61483
+  },
+  {
+    "tag": "poisonousness",
+    "popularity": 61282
+  },
+  {
+    "tag": "phare",
+    "popularity": 61083
+  },
+  {
+    "tag": "dicynodont",
+    "popularity": 60884
+  },
+  {
+    "tag": "chewer",
+    "popularity": 60687
+  },
+  {
+    "tag": "uliginous",
+    "popularity": 60490
+  },
+  {
+    "tag": "tinman",
+    "popularity": 60295
+  },
+  {
+    "tag": "coconut",
+    "popularity": 60100
+  },
+  {
+    "tag": "phryganeoid",
+    "popularity": 59907
+  },
+  {
+    "tag": "bismillah",
+    "popularity": 59714
+  },
+  {
+    "tag": "tautomeric",
+    "popularity": 59523
+  },
+  {
+    "tag": "jerquer",
+    "popularity": 59332
+  },
+  {
+    "tag": "Dryopithecinae",
+    "popularity": 59143
+  },
+  {
+    "tag": "ghizite",
+    "popularity": 58954
+  },
+  {
+    "tag": "unliveable",
+    "popularity": 58766
+  },
+  {
+    "tag": "craftsmaster",
+    "popularity": 58579
+  },
+  {
+    "tag": "semiscenic",
+    "popularity": 58394
+  },
+  {
+    "tag": "danaid",
+    "popularity": 58209
+  },
+  {
+    "tag": "flawful",
+    "popularity": 58025
+  },
+  {
+    "tag": "risibleness",
+    "popularity": 57841
+  },
+  {
+    "tag": "Muscovite",
+    "popularity": 57659
+  },
+  {
+    "tag": "snaringly",
+    "popularity": 57478
+  },
+  {
+    "tag": "brilliantwise",
+    "popularity": 57297
+  },
+  {
+    "tag": "plebeity",
+    "popularity": 57118
+  },
+  {
+    "tag": "historicalness",
+    "popularity": 56939
+  },
+  {
+    "tag": "piecemeal",
+    "popularity": 56761
+  },
+  {
+    "tag": "maxillipedary",
+    "popularity": 56584
+  },
+  {
+    "tag": "Hypenantron",
+    "popularity": 56408
+  },
+  {
+    "tag": "quaintness avigate",
+    "popularity": 56233
+  },
+  {
+    "tag": "ave",
+    "popularity": 56059
+  },
+  {
+    "tag": "mediaevally",
+    "popularity": 55885
+  },
+  {
+    "tag": "brucite",
+    "popularity": 55712
+  },
+  {
+    "tag": "Schwendenerian",
+    "popularity": 55541
+  },
+  {
+    "tag": "julole",
+    "popularity": 55370
+  },
+  {
+    "tag": "palaeolith",
+    "popularity": 55199
+  },
+  {
+    "tag": "cotyledonary",
+    "popularity": 55030
+  },
+  {
+    "tag": "rond",
+    "popularity": 54861
+  },
+  {
+    "tag": "boomster tassoo",
+    "popularity": 54694
+  },
+  {
+    "tag": "cattishly",
+    "popularity": 54527
+  },
+  {
+    "tag": "tonguefence",
+    "popularity": 54360
+  },
+  {
+    "tag": "hexastylar triskele",
+    "popularity": 54195
+  },
+  {
+    "tag": "ariot",
+    "popularity": 54030
+  },
+  {
+    "tag": "intarsist",
+    "popularity": 53867
+  },
+  {
+    "tag": "Oscines",
+    "popularity": 53704
+  },
+  {
+    "tag": "Spaniolize",
+    "popularity": 53541
+  },
+  {
+    "tag": "smellfungus",
+    "popularity": 53380
+  },
+  {
+    "tag": "redisplay",
+    "popularity": 53219
+  },
+  {
+    "tag": "phosphene",
+    "popularity": 53059
+  },
+  {
+    "tag": "phycomycete",
+    "popularity": 52900
+  },
+  {
+    "tag": "prophetic",
+    "popularity": 52741
+  },
+  {
+    "tag": "overtrustful",
+    "popularity": 52584
+  },
+  {
+    "tag": "pinitol",
+    "popularity": 52427
+  },
+  {
+    "tag": "asthmatic",
+    "popularity": 52270
+  },
+  {
+    "tag": "convulsive",
+    "popularity": 52115
+  },
+  {
+    "tag": "draughtswoman",
+    "popularity": 51960
+  },
+  {
+    "tag": "unetymologizable",
+    "popularity": 51806
+  },
+  {
+    "tag": "centrarchoid",
+    "popularity": 51652
+  },
+  {
+    "tag": "mesioincisal",
+    "popularity": 51500
+  },
+  {
+    "tag": "transbaikal",
+    "popularity": 51348
+  },
+  {
+    "tag": "silveriness",
+    "popularity": 51196
+  },
+  {
+    "tag": "costotomy",
+    "popularity": 51046
+  },
+  {
+    "tag": "caracore",
+    "popularity": 50896
+  },
+  {
+    "tag": "depotentiation",
+    "popularity": 50747
+  },
+  {
+    "tag": "glossoepiglottidean",
+    "popularity": 50598
+  },
+  {
+    "tag": "upswell",
+    "popularity": 50450
+  },
+  {
+    "tag": "flecnodal",
+    "popularity": 50303
+  },
+  {
+    "tag": "coventrate",
+    "popularity": 50157
+  },
+  {
+    "tag": "duchesse",
+    "popularity": 50011
+  },
+  {
+    "tag": "excisemanship trophied",
+    "popularity": 49866
+  },
+  {
+    "tag": "cytinaceous",
+    "popularity": 49721
+  },
+  {
+    "tag": "assuringly",
+    "popularity": 49577
+  },
+  {
+    "tag": "unconducted upliftitis",
+    "popularity": 49434
+  },
+  {
+    "tag": "rachicentesis",
+    "popularity": 49292
+  },
+  {
+    "tag": "antiangular",
+    "popularity": 49150
+  },
+  {
+    "tag": "advisal",
+    "popularity": 49008
+  },
+  {
+    "tag": "birdcatcher",
+    "popularity": 48868
+  },
+  {
+    "tag": "secularistic",
+    "popularity": 48728
+  },
+  {
+    "tag": "grandeeism superinformal",
+    "popularity": 48588
+  },
+  {
+    "tag": "unapprehension",
+    "popularity": 48449
+  },
+  {
+    "tag": "excipulum",
+    "popularity": 48311
+  },
+  {
+    "tag": "decimole",
+    "popularity": 48174
+  },
+  {
+    "tag": "semidrachm",
+    "popularity": 48037
+  },
+  {
+    "tag": "uvulotome",
+    "popularity": 47901
+  },
+  {
+    "tag": "Lemaneaceae",
+    "popularity": 47765
+  },
+  {
+    "tag": "corrade",
+    "popularity": 47630
+  },
+  {
+    "tag": "Kuroshio",
+    "popularity": 47495
+  },
+  {
+    "tag": "Araliophyllum",
+    "popularity": 47361
+  },
+  {
+    "tag": "victoriousness cardiosphygmograph",
+    "popularity": 47228
+  },
+  {
+    "tag": "reinvent",
+    "popularity": 47095
+  },
+  {
+    "tag": "Macrotolagus",
+    "popularity": 46963
+  },
+  {
+    "tag": "strenuousness",
+    "popularity": 46831
+  },
+  {
+    "tag": "deviability",
+    "popularity": 46700
+  },
+  {
+    "tag": "phyllospondylous",
+    "popularity": 46570
+  },
+  {
+    "tag": "bisect rudderhole",
+    "popularity": 46440
+  },
+  {
+    "tag": "crownwork",
+    "popularity": 46311
+  },
+  {
+    "tag": "Ascalabota",
+    "popularity": 46182
+  },
+  {
+    "tag": "prostatomyomectomy",
+    "popularity": 46054
+  },
+  {
+    "tag": "neurosyphilis",
+    "popularity": 45926
+  },
+  {
+    "tag": "tabloid scraplet",
+    "popularity": 45799
+  },
+  {
+    "tag": "nonmedullated servility",
+    "popularity": 45673
+  },
+  {
+    "tag": "melopoeic practicalization",
+    "popularity": 45547
+  },
+  {
+    "tag": "nonrhythmic",
+    "popularity": 45421
+  },
+  {
+    "tag": "deplorer",
+    "popularity": 45296
+  },
+  {
+    "tag": "Ophion",
+    "popularity": 45172
+  },
+  {
+    "tag": "subprioress",
+    "popularity": 45048
+  },
+  {
+    "tag": "semiregular",
+    "popularity": 44925
+  },
+  {
+    "tag": "praelection",
+    "popularity": 44802
+  },
+  {
+    "tag": "discinct",
+    "popularity": 44680
+  },
+  {
+    "tag": "preplace",
+    "popularity": 44558
+  },
+  {
+    "tag": "paternoster",
+    "popularity": 44437
+  },
+  {
+    "tag": "suboccipital",
+    "popularity": 44316
+  },
+  {
+    "tag": "Teutophil",
+    "popularity": 44196
+  },
+  {
+    "tag": "tracheole",
+    "popularity": 44076
+  },
+  {
+    "tag": "subsmile",
+    "popularity": 43957
+  },
+  {
+    "tag": "nonapostatizing",
+    "popularity": 43839
+  },
+  {
+    "tag": "cleidotomy",
+    "popularity": 43720
+  },
+  {
+    "tag": "hingle",
+    "popularity": 43603
+  },
+  {
+    "tag": "jocoque",
+    "popularity": 43486
+  },
+  {
+    "tag": "trundler notidanian",
+    "popularity": 43369
+  },
+  {
+    "tag": "strangling misdaub",
+    "popularity": 43253
+  },
+  {
+    "tag": "noncancellable",
+    "popularity": 43137
+  },
+  {
+    "tag": "lavabo",
+    "popularity": 43022
+  },
+  {
+    "tag": "lanterloo",
+    "popularity": 42907
+  },
+  {
+    "tag": "uncitizenly",
+    "popularity": 42793
+  },
+  {
+    "tag": "autoturning",
+    "popularity": 42679
+  },
+  {
+    "tag": "Haganah",
+    "popularity": 42566
+  },
+  {
+    "tag": "Glecoma",
+    "popularity": 42453
+  },
+  {
+    "tag": "membered",
+    "popularity": 42341
+  },
+  {
+    "tag": "consuetudinal",
+    "popularity": 42229
+  },
+  {
+    "tag": "gatehouse",
+    "popularity": 42117
+  },
+  {
+    "tag": "tetherball",
+    "popularity": 42006
+  },
+  {
+    "tag": "counterrevolutionist numismatical",
+    "popularity": 41896
+  },
+  {
+    "tag": "pagehood plateiasmus",
+    "popularity": 41786
+  },
+  {
+    "tag": "pelterer",
+    "popularity": 41676
+  },
+  {
+    "tag": "splenemphraxis",
+    "popularity": 41567
+  },
+  {
+    "tag": "Crypturidae",
+    "popularity": 41458
+  },
+  {
+    "tag": "caboodle",
+    "popularity": 41350
+  },
+  {
+    "tag": "Filaria",
+    "popularity": 41242
+  },
+  {
+    "tag": "noninvincibility",
+    "popularity": 41135
+  },
+  {
+    "tag": "preadvertisement",
+    "popularity": 41028
+  },
+  {
+    "tag": "bathrobe",
+    "popularity": 40921
+  },
+  {
+    "tag": "nitrifier",
+    "popularity": 40815
+  },
+  {
+    "tag": "furthermore",
+    "popularity": 40709
+  },
+  {
+    "tag": "recrate",
+    "popularity": 40604
+  },
+  {
+    "tag": "inexist",
+    "popularity": 40499
+  },
+  {
+    "tag": "Mocoan",
+    "popularity": 40395
+  },
+  {
+    "tag": "forint",
+    "popularity": 40291
+  },
+  {
+    "tag": "cardiomyoliposis",
+    "popularity": 40187
+  },
+  {
+    "tag": "channeling",
+    "popularity": 40084
+  },
+  {
+    "tag": "quebrachine",
+    "popularity": 39981
+  },
+  {
+    "tag": "magistery",
+    "popularity": 39879
+  },
+  {
+    "tag": "koko",
+    "popularity": 39777
+  },
+  {
+    "tag": "nobilify",
+    "popularity": 39676
+  },
+  {
+    "tag": "articulate taprooted",
+    "popularity": 39575
+  },
+  {
+    "tag": "cardiotonic Nicaragua",
+    "popularity": 39474
+  },
+  {
+    "tag": "assertiveness",
+    "popularity": 39374
+  },
+  {
+    "tag": "springtail",
+    "popularity": 39274
+  },
+  {
+    "tag": "spontoon",
+    "popularity": 39174
+  },
+  {
+    "tag": "plesiobiosis",
+    "popularity": 39075
+  },
+  {
+    "tag": "rooinek",
+    "popularity": 38976
+  },
+  {
+    "tag": "hairif falsehood",
+    "popularity": 38878
+  },
+  {
+    "tag": "synodally",
+    "popularity": 38780
+  },
+  {
+    "tag": "biodynamics",
+    "popularity": 38683
+  },
+  {
+    "tag": "trickling",
+    "popularity": 38585
+  },
+  {
+    "tag": "oxfly daystar",
+    "popularity": 38489
+  },
+  {
+    "tag": "epicycloidal",
+    "popularity": 38392
+  },
+  {
+    "tag": "shorthand",
+    "popularity": 38296
+  },
+  {
+    "tag": "herpolhode",
+    "popularity": 38201
+  },
+  {
+    "tag": "polysynthesism",
+    "popularity": 38105
+  },
+  {
+    "tag": "cany",
+    "popularity": 38010
+  },
+  {
+    "tag": "sideage",
+    "popularity": 37916
+  },
+  {
+    "tag": "strainableness",
+    "popularity": 37822
+  },
+  {
+    "tag": "superformidable",
+    "popularity": 37728
+  },
+  {
+    "tag": "slendang",
+    "popularity": 37634
+  },
+  {
+    "tag": "impropriation",
+    "popularity": 37541
+  },
+  {
+    "tag": "ficklehearted",
+    "popularity": 37449
+  },
+  {
+    "tag": "wintrify",
+    "popularity": 37356
+  },
+  {
+    "tag": "geomorphogenist",
+    "popularity": 37264
+  },
+  {
+    "tag": "smuggleable",
+    "popularity": 37173
+  },
+  {
+    "tag": "delapsion",
+    "popularity": 37081
+  },
+  {
+    "tag": "projective",
+    "popularity": 36990
+  },
+  {
+    "tag": "unglue exfoliation",
+    "popularity": 36900
+  },
+  {
+    "tag": "Acerae",
+    "popularity": 36810
+  },
+  {
+    "tag": "unstaged",
+    "popularity": 36720
+  },
+  {
+    "tag": "ranal",
+    "popularity": 36630
+  },
+  {
+    "tag": "worrier",
+    "popularity": 36541
+  },
+  {
+    "tag": "unhid",
+    "popularity": 36452
+  },
+  {
+    "tag": "adequation",
+    "popularity": 36363
+  },
+  {
+    "tag": "strongylid Sokotri",
+    "popularity": 36275
+  },
+  {
+    "tag": "fumingly",
+    "popularity": 36187
+  },
+  {
+    "tag": "gynosporangium phaenogenetic",
+    "popularity": 36100
+  },
+  {
+    "tag": "uniunguiculate",
+    "popularity": 36012
+  },
+  {
+    "tag": "prudelike",
+    "popularity": 35926
+  },
+  {
+    "tag": "seminomata",
+    "popularity": 35839
+  },
+  {
+    "tag": "trinklet",
+    "popularity": 35753
+  },
+  {
+    "tag": "risorial",
+    "popularity": 35667
+  },
+  {
+    "tag": "pericardiocentesis",
+    "popularity": 35581
+  },
+  {
+    "tag": "filmist",
+    "popularity": 35496
+  },
+  {
+    "tag": "Nana",
+    "popularity": 35411
+  },
+  {
+    "tag": "cynipoid",
+    "popularity": 35326
+  },
+  {
+    "tag": "cteniform",
+    "popularity": 35242
+  },
+  {
+    "tag": "semiflex",
+    "popularity": 35158
+  },
+  {
+    "tag": "solstitially",
+    "popularity": 35074
+  },
+  {
+    "tag": "Algarsife",
+    "popularity": 34991
+  },
+  {
+    "tag": "noncriminal",
+    "popularity": 34908
+  },
+  {
+    "tag": "compassion",
+    "popularity": 34825
+  },
+  {
+    "tag": "Buddhic",
+    "popularity": 34743
+  },
+  {
+    "tag": "vellicative dactylically hotfoot",
+    "popularity": 34661
+  },
+  {
+    "tag": "chicory",
+    "popularity": 34579
+  },
+  {
+    "tag": "transperitoneally",
+    "popularity": 34497
+  },
+  {
+    "tag": "pennae",
+    "popularity": 34416
+  },
+  {
+    "tag": "Flamandize",
+    "popularity": 34335
+  },
+  {
+    "tag": "underviewer",
+    "popularity": 34254
+  },
+  {
+    "tag": "assoil",
+    "popularity": 34174
+  },
+  {
+    "tag": "saccharobacillus",
+    "popularity": 34094
+  },
+  {
+    "tag": "biacetylene",
+    "popularity": 34014
+  },
+  {
+    "tag": "mouchardism",
+    "popularity": 33935
+  },
+  {
+    "tag": "anisomeric",
+    "popularity": 33856
+  },
+  {
+    "tag": "digestive",
+    "popularity": 33777
+  },
+  {
+    "tag": "darlingly",
+    "popularity": 33698
+  },
+  {
+    "tag": "liman",
+    "popularity": 33620
+  },
+  {
+    "tag": "soldanrie",
+    "popularity": 33542
+  },
+  {
+    "tag": "sully",
+    "popularity": 33464
+  },
+  {
+    "tag": "brightsmith",
+    "popularity": 33387
+  },
+  {
+    "tag": "inwrap antiliturgist ureterocervical",
+    "popularity": 33309
+  },
+  {
+    "tag": "discommodity",
+    "popularity": 33232
+  },
+  {
+    "tag": "typical aggrandizer",
+    "popularity": 33156
+  },
+  {
+    "tag": "xenogeny",
+    "popularity": 33079
+  },
+  {
+    "tag": "uncountrified",
+    "popularity": 33003
+  },
+  {
+    "tag": "Podarge",
+    "popularity": 32928
+  },
+  {
+    "tag": "uninterviewed",
+    "popularity": 32852
+  },
+  {
+    "tag": "underprior",
+    "popularity": 32777
+  },
+  {
+    "tag": "leiomyomatous",
+    "popularity": 32702
+  },
+  {
+    "tag": "postdysenteric",
+    "popularity": 32627
+  },
+  {
+    "tag": "Fusicladium",
+    "popularity": 32553
+  },
+  {
+    "tag": "Dulcinea",
+    "popularity": 32478
+  },
+  {
+    "tag": "interspersion",
+    "popularity": 32404
+  },
+  {
+    "tag": "preobligate",
+    "popularity": 32331
+  },
+  {
+    "tag": "subaggregate",
+    "popularity": 32257
+  },
+  {
+    "tag": "grammarianism",
+    "popularity": 32184
+  },
+  {
+    "tag": "palikar",
+    "popularity": 32111
+  },
+  {
+    "tag": "facileness",
+    "popularity": 32039
+  },
+  {
+    "tag": "deuterofibrinose",
+    "popularity": 31966
+  },
+  {
+    "tag": "pseudesthesia",
+    "popularity": 31894
+  },
+  {
+    "tag": "sedimentary",
+    "popularity": 31822
+  },
+  {
+    "tag": "typewrite",
+    "popularity": 31751
+  },
+  {
+    "tag": "immemorable",
+    "popularity": 31679
+  },
+  {
+    "tag": "Myrtus",
+    "popularity": 31608
+  },
+  {
+    "tag": "hauchecornite",
+    "popularity": 31537
+  },
+  {
+    "tag": "galleylike",
+    "popularity": 31467
+  },
+  {
+    "tag": "thimber",
+    "popularity": 31396
+  },
+  {
+    "tag": "Hegelianism",
+    "popularity": 31326
+  },
+  {
+    "tag": "strig",
+    "popularity": 31256
+  },
+  {
+    "tag": "skyre",
+    "popularity": 31187
+  },
+  {
+    "tag": "eupepticism",
+    "popularity": 31117
+  },
+  {
+    "tag": "eponymism",
+    "popularity": 31048
+  },
+  {
+    "tag": "flunkeyhood",
+    "popularity": 30979
+  },
+  {
+    "tag": "Abama",
+    "popularity": 30911
+  },
+  {
+    "tag": "adiadochokinesis",
+    "popularity": 30842
+  },
+  {
+    "tag": "spendthrifty",
+    "popularity": 30774
+  },
+  {
+    "tag": "chalcedony",
+    "popularity": 30706
+  },
+  {
+    "tag": "authorism",
+    "popularity": 30638
+  },
+  {
+    "tag": "nasturtium",
+    "popularity": 30571
+  },
+  {
+    "tag": "Acanthocereus",
+    "popularity": 30504
+  },
+  {
+    "tag": "uncollapsible",
+    "popularity": 30437
+  },
+  {
+    "tag": "excursionist",
+    "popularity": 30370
+  },
+  {
+    "tag": "fogbow",
+    "popularity": 30303
+  },
+  {
+    "tag": "overlie",
+    "popularity": 30237
+  },
+  {
+    "tag": "velours",
+    "popularity": 30171
+  },
+  {
+    "tag": "zoodendria madrigal stagbush",
+    "popularity": 30105
+  },
+  {
+    "tag": "imi",
+    "popularity": 30039
+  },
+  {
+    "tag": "cojudge",
+    "popularity": 29974
+  },
+  {
+    "tag": "depurate argal",
+    "popularity": 29909
+  },
+  {
+    "tag": "unrecognition",
+    "popularity": 29844
+  },
+  {
+    "tag": "paunchful",
+    "popularity": 29779
+  },
+  {
+    "tag": "invalued",
+    "popularity": 29714
+  },
+  {
+    "tag": "probang",
+    "popularity": 29650
+  },
+  {
+    "tag": "chetvert",
+    "popularity": 29586
+  },
+  {
+    "tag": "enactable",
+    "popularity": 29522
+  },
+  {
+    "tag": "detoxicate adhibit",
+    "popularity": 29458
+  },
+  {
+    "tag": "kullaite",
+    "popularity": 29395
+  },
+  {
+    "tag": "undazzling",
+    "popularity": 29332
+  },
+  {
+    "tag": "excalation",
+    "popularity": 29269
+  },
+  {
+    "tag": "sievings",
+    "popularity": 29206
+  },
+  {
+    "tag": "disenthral",
+    "popularity": 29143
+  },
+  {
+    "tag": "disinterestedly",
+    "popularity": 29081
+  },
+  {
+    "tag": "stanner",
+    "popularity": 29018
+  },
+  {
+    "tag": "recapitulative",
+    "popularity": 28956
+  },
+  {
+    "tag": "objectivist",
+    "popularity": 28895
+  },
+  {
+    "tag": "hypermetropia",
+    "popularity": 28833
+  },
+  {
+    "tag": "incumbency",
+    "popularity": 28772
+  },
+  {
+    "tag": "protegee",
+    "popularity": 28711
+  },
+  {
+    "tag": "zealotic",
+    "popularity": 28650
+  },
+  {
+    "tag": "predebit",
+    "popularity": 28589
+  },
+  {
+    "tag": "cupolar",
+    "popularity": 28528
+  },
+  {
+    "tag": "unattributed",
+    "popularity": 28468
+  },
+  {
+    "tag": "louisine",
+    "popularity": 28408
+  },
+  {
+    "tag": "illustrate",
+    "popularity": 28348
+  },
+  {
+    "tag": "inofficiousness",
+    "popularity": 28288
+  },
+  {
+    "tag": "Americawards",
+    "popularity": 28228
+  },
+  {
+    "tag": "foreflap",
+    "popularity": 28169
+  },
+  {
+    "tag": "eruditeness",
+    "popularity": 28110
+  },
+  {
+    "tag": "copiopsia",
+    "popularity": 28051
+  },
+  {
+    "tag": "sporuliferous",
+    "popularity": 27992
+  },
+  {
+    "tag": "muttering",
+    "popularity": 27934
+  },
+  {
+    "tag": "prepsychology adrip",
+    "popularity": 27875
+  },
+  {
+    "tag": "unfriendly",
+    "popularity": 27817
+  },
+  {
+    "tag": "sulphanilic",
+    "popularity": 27759
+  },
+  {
+    "tag": "Coelococcus",
+    "popularity": 27701
+  },
+  {
+    "tag": "undoubtfulness",
+    "popularity": 27643
+  },
+  {
+    "tag": "flaringly",
+    "popularity": 27586
+  },
+  {
+    "tag": "unordain",
+    "popularity": 27529
+  },
+  {
+    "tag": "fratchety",
+    "popularity": 27472
+  },
+  {
+    "tag": "decadentism dolefully",
+    "popularity": 27415
+  },
+  {
+    "tag": "synthronus",
+    "popularity": 27358
+  },
+  {
+    "tag": "maiid",
+    "popularity": 27301
+  },
+  {
+    "tag": "rhinobyon",
+    "popularity": 27245
+  },
+  {
+    "tag": "Didynamia",
+    "popularity": 27189
+  },
+  {
+    "tag": "millionairedom",
+    "popularity": 27133
+  },
+  {
+    "tag": "mulierine",
+    "popularity": 27077
+  },
+  {
+    "tag": "Mayo",
+    "popularity": 27021
+  },
+  {
+    "tag": "perceivedness",
+    "popularity": 26966
+  },
+  {
+    "tag": "unadoration",
+    "popularity": 26911
+  },
+  {
+    "tag": "regraft",
+    "popularity": 26856
+  },
+  {
+    "tag": "witch",
+    "popularity": 26801
+  },
+  {
+    "tag": "ungrow",
+    "popularity": 26746
+  },
+  {
+    "tag": "glossopharyngeus",
+    "popularity": 26691
+  },
+  {
+    "tag": "unstirrable",
+    "popularity": 26637
+  },
+  {
+    "tag": "synodsman",
+    "popularity": 26583
+  },
+  {
+    "tag": "placentalian",
+    "popularity": 26529
+  },
+  {
+    "tag": "corpulently",
+    "popularity": 26475
+  },
+  {
+    "tag": "photochromoscope",
+    "popularity": 26421
+  },
+  {
+    "tag": "indusiate retinasphaltum chokestrap",
+    "popularity": 26368
+  },
+  {
+    "tag": "murdrum",
+    "popularity": 26314
+  },
+  {
+    "tag": "belatedness",
+    "popularity": 26261
+  },
+  {
+    "tag": "Cochin",
+    "popularity": 26208
+  },
+  {
+    "tag": "Leonist",
+    "popularity": 26155
+  },
+  {
+    "tag": "keeker confined",
+    "popularity": 26102
+  },
+  {
+    "tag": "unintellectual",
+    "popularity": 26050
+  },
+  {
+    "tag": "nymphaline bait",
+    "popularity": 25997
+  },
+  {
+    "tag": "sarcosporidiosis",
+    "popularity": 25945
+  },
+  {
+    "tag": "catawamptiously",
+    "popularity": 25893
+  },
+  {
+    "tag": "outshame",
+    "popularity": 25841
+  },
+  {
+    "tag": "animalism",
+    "popularity": 25790
+  },
+  {
+    "tag": "epithalamial",
+    "popularity": 25738
+  },
+  {
+    "tag": "ganner",
+    "popularity": 25687
+  },
+  {
+    "tag": "desilicify",
+    "popularity": 25635
+  },
+  {
+    "tag": "dandyism",
+    "popularity": 25584
+  },
+  {
+    "tag": "hyleg",
+    "popularity": 25533
+  },
+  {
+    "tag": "photophysical",
+    "popularity": 25483
+  },
+  {
+    "tag": "underload",
+    "popularity": 25432
+  },
+  {
+    "tag": "unintrusive",
+    "popularity": 25382
+  },
+  {
+    "tag": "succinamic",
+    "popularity": 25331
+  },
+  {
+    "tag": "matchy",
+    "popularity": 25281
+  },
+  {
+    "tag": "concordal",
+    "popularity": 25231
+  },
+  {
+    "tag": "exteriority",
+    "popularity": 25181
+  },
+  {
+    "tag": "sterculiad",
+    "popularity": 25132
+  },
+  {
+    "tag": "sulfoxylic",
+    "popularity": 25082
+  },
+  {
+    "tag": "oversubscription",
+    "popularity": 25033
+  },
+  {
+    "tag": "chiasmic",
+    "popularity": 24984
+  },
+  {
+    "tag": "pseudoparthenogenesis",
+    "popularity": 24935
+  },
+  {
+    "tag": "indorse",
+    "popularity": 24886
+  },
+  {
+    "tag": "Krishnaite",
+    "popularity": 24837
+  },
+  {
+    "tag": "calcinize",
+    "popularity": 24788
+  },
+  {
+    "tag": "rhodium",
+    "popularity": 24740
+  },
+  {
+    "tag": "tragopan",
+    "popularity": 24692
+  },
+  {
+    "tag": "overwhelmingly",
+    "popularity": 24643
+  },
+  {
+    "tag": "procidence accorporate",
+    "popularity": 24595
+  },
+  {
+    "tag": "polemize speelless",
+    "popularity": 24548
+  },
+  {
+    "tag": "radiocarpal goran",
+    "popularity": 24500
+  },
+  {
+    "tag": "counteroffer Pelodytes",
+    "popularity": 24452
+  },
+  {
+    "tag": "lionhearted",
+    "popularity": 24405
+  },
+  {
+    "tag": "paramastoid",
+    "popularity": 24358
+  },
+  {
+    "tag": "murine",
+    "popularity": 24310
+  },
+  {
+    "tag": "woodbined",
+    "popularity": 24263
+  },
+  {
+    "tag": "packthread",
+    "popularity": 24217
+  },
+  {
+    "tag": "citreous",
+    "popularity": 24170
+  },
+  {
+    "tag": "unfallaciously",
+    "popularity": 24123
+  },
+  {
+    "tag": "tentwork reincarnadine",
+    "popularity": 24077
+  },
+  {
+    "tag": "verminousness",
+    "popularity": 24030
+  },
+  {
+    "tag": "sillometer",
+    "popularity": 23984
+  },
+  {
+    "tag": "jointy",
+    "popularity": 23938
+  },
+  {
+    "tag": "streptolysin",
+    "popularity": 23892
+  },
+  {
+    "tag": "Florentinism",
+    "popularity": 23847
+  },
+  {
+    "tag": "monosomatous",
+    "popularity": 23801
+  },
+  {
+    "tag": "capsulociliary",
+    "popularity": 23756
+  },
+  {
+    "tag": "organum",
+    "popularity": 23710
+  },
+  {
+    "tag": "overtly",
+    "popularity": 23665
+  },
+  {
+    "tag": "ophthalmoscopical",
+    "popularity": 23620
+  },
+  {
+    "tag": "supposititiously",
+    "popularity": 23575
+  },
+  {
+    "tag": "radiochemistry",
+    "popularity": 23530
+  },
+  {
+    "tag": "flaxtail",
+    "popularity": 23486
+  },
+  {
+    "tag": "pretympanic",
+    "popularity": 23441
+  },
+  {
+    "tag": "auscultation",
+    "popularity": 23397
+  },
+  {
+    "tag": "hairdresser",
+    "popularity": 23352
+  },
+  {
+    "tag": "chaffless",
+    "popularity": 23308
+  },
+  {
+    "tag": "polioencephalitis",
+    "popularity": 23264
+  },
+  {
+    "tag": "axolotl",
+    "popularity": 23220
+  },
+  {
+    "tag": "smous",
+    "popularity": 23177
+  },
+  {
+    "tag": "morgen disenamour toothed",
+    "popularity": 23133
+  },
+  {
+    "tag": "chaiseless",
+    "popularity": 23089
+  },
+  {
+    "tag": "frugally",
+    "popularity": 23046
+  },
+  {
+    "tag": "combustive antievolutionist cinenegative",
+    "popularity": 23003
+  },
+  {
+    "tag": "malacolite",
+    "popularity": 22960
+  },
+  {
+    "tag": "borne",
+    "popularity": 22917
+  },
+  {
+    "tag": "mercaptole",
+    "popularity": 22874
+  },
+  {
+    "tag": "judicatory",
+    "popularity": 22831
+  },
+  {
+    "tag": "noctivagation",
+    "popularity": 22789
+  },
+  {
+    "tag": "synthete",
+    "popularity": 22746
+  },
+  {
+    "tag": "tomboyism",
+    "popularity": 22704
+  },
+  {
+    "tag": "serranoid",
+    "popularity": 22661
+  },
+  {
+    "tag": "impostorism",
+    "popularity": 22619
+  },
+  {
+    "tag": "flagellosis Talitha",
+    "popularity": 22577
+  },
+  {
+    "tag": "pseudoviscous",
+    "popularity": 22535
+  },
+  {
+    "tag": "Galleriidae",
+    "popularity": 22494
+  },
+  {
+    "tag": "undulation didelph Comintern",
+    "popularity": 22452
+  },
+  {
+    "tag": "triangulopyramidal",
+    "popularity": 22411
+  },
+  {
+    "tag": "middlings",
+    "popularity": 22369
+  },
+  {
+    "tag": "piperazin",
+    "popularity": 22328
+  },
+  {
+    "tag": "endostitis",
+    "popularity": 22287
+  },
+  {
+    "tag": "swordlike",
+    "popularity": 22246
+  },
+  {
+    "tag": "forthwith",
+    "popularity": 22205
+  },
+  {
+    "tag": "menaceful",
+    "popularity": 22164
+  },
+  {
+    "tag": "explantation defective",
+    "popularity": 22123
+  },
+  {
+    "tag": "arrear",
+    "popularity": 22083
+  },
+  {
+    "tag": "engraft",
+    "popularity": 22042
+  },
+  {
+    "tag": "revolunteer",
+    "popularity": 22002
+  },
+  {
+    "tag": "foliaceous",
+    "popularity": 21962
+  },
+  {
+    "tag": "pseudograph",
+    "popularity": 21922
+  },
+  {
+    "tag": "maenaite",
+    "popularity": 21882
+  },
+  {
+    "tag": "interfinger",
+    "popularity": 21842
+  },
+  {
+    "tag": "macroscopically",
+    "popularity": 21802
+  },
+  {
+    "tag": "bluewood",
+    "popularity": 21762
+  },
+  {
+    "tag": "chikara",
+    "popularity": 21723
+  },
+  {
+    "tag": "reprehension diazeuxis nickelous",
+    "popularity": 21683
+  },
+  {
+    "tag": "vacuation",
+    "popularity": 21644
+  },
+  {
+    "tag": "Sartish",
+    "popularity": 21605
+  },
+  {
+    "tag": "pseudogyny",
+    "popularity": 21566
+  },
+  {
+    "tag": "friedcake",
+    "popularity": 21527
+  },
+  {
+    "tag": "thraw",
+    "popularity": 21488
+  },
+  {
+    "tag": "bifid",
+    "popularity": 21449
+  },
+  {
+    "tag": "truthlessly",
+    "popularity": 21411
+  },
+  {
+    "tag": "lungy",
+    "popularity": 21372
+  },
+  {
+    "tag": "fluoborite",
+    "popularity": 21334
+  },
+  {
+    "tag": "anthropolithic",
+    "popularity": 21295
+  },
+  {
+    "tag": "coachee straw",
+    "popularity": 21257
+  },
+  {
+    "tag": "dehorner Grecize",
+    "popularity": 21219
+  },
+  {
+    "tag": "spondylopyosis",
+    "popularity": 21181
+  },
+  {
+    "tag": "institutionary",
+    "popularity": 21143
+  },
+  {
+    "tag": "agentry",
+    "popularity": 21105
+  },
+  {
+    "tag": "musing bietle",
+    "popularity": 21068
+  },
+  {
+    "tag": "cormophyte",
+    "popularity": 21030
+  },
+  {
+    "tag": "semielliptic",
+    "popularity": 20993
+  },
+  {
+    "tag": "ependytes",
+    "popularity": 20955
+  },
+  {
+    "tag": "coachmaster",
+    "popularity": 20918
+  },
+  {
+    "tag": "overexuberant",
+    "popularity": 20881
+  },
+  {
+    "tag": "selectable",
+    "popularity": 20844
+  },
+  {
+    "tag": "saclike",
+    "popularity": 20807
+  },
+  {
+    "tag": "mullion",
+    "popularity": 20770
+  },
+  {
+    "tag": "pantheonize prevalency",
+    "popularity": 20733
+  },
+  {
+    "tag": "trophosperm",
+    "popularity": 20697
+  },
+  {
+    "tag": "paraphrasist",
+    "popularity": 20660
+  },
+  {
+    "tag": "undercarry",
+    "popularity": 20624
+  },
+  {
+    "tag": "thallogenic",
+    "popularity": 20587
+  },
+  {
+    "tag": "bulgy forbid",
+    "popularity": 20551
+  },
+  {
+    "tag": "proliquor gratulatory",
+    "popularity": 20515
+  },
+  {
+    "tag": "booker",
+    "popularity": 20479
+  },
+  {
+    "tag": "wizen",
+    "popularity": 20443
+  },
+  {
+    "tag": "synchondrosially",
+    "popularity": 20407
+  },
+  {
+    "tag": "herbless",
+    "popularity": 20371
+  },
+  {
+    "tag": "arfvedsonite",
+    "popularity": 20336
+  },
+  {
+    "tag": "Neuroptera",
+    "popularity": 20300
+  },
+  {
+    "tag": "fingerstone",
+    "popularity": 20265
+  },
+  {
+    "tag": "Odontoglossae",
+    "popularity": 20229
+  },
+  {
+    "tag": "transmigrator",
+    "popularity": 20194
+  },
+  {
+    "tag": "Dehaites",
+    "popularity": 20159
+  },
+  {
+    "tag": "Molinist",
+    "popularity": 20124
+  },
+  {
+    "tag": "novelistic",
+    "popularity": 20089
+  },
+  {
+    "tag": "astelic",
+    "popularity": 20054
+  },
+  {
+    "tag": "pyelometry",
+    "popularity": 20019
+  },
+  {
+    "tag": "pigmentation",
+    "popularity": 19984
+  },
+  {
+    "tag": "epinaos",
+    "popularity": 19950
+  },
+  {
+    "tag": "outdare",
+    "popularity": 19915
+  },
+  {
+    "tag": "Funje philaristocracy",
+    "popularity": 19881
+  },
+  {
+    "tag": "keddah",
+    "popularity": 19846
+  },
+  {
+    "tag": "axoidean",
+    "popularity": 19812
+  },
+  {
+    "tag": "ovule",
+    "popularity": 19778
+  },
+  {
+    "tag": "solidify",
+    "popularity": 19744
+  },
+  {
+    "tag": "noncelestial",
+    "popularity": 19710
+  },
+  {
+    "tag": "overmultiplication",
+    "popularity": 19676
+  },
+  {
+    "tag": "hexatetrahedron",
+    "popularity": 19642
+  },
+  {
+    "tag": "pliciform",
+    "popularity": 19609
+  },
+  {
+    "tag": "zimbalon",
+    "popularity": 19575
+  },
+  {
+    "tag": "annexational",
+    "popularity": 19542
+  },
+  {
+    "tag": "eurhodol",
+    "popularity": 19508
+  },
+  {
+    "tag": "yark",
+    "popularity": 19475
+  },
+  {
+    "tag": "illegality nitroalizarin",
+    "popularity": 19442
+  },
+  {
+    "tag": "quadratum",
+    "popularity": 19409
+  },
+  {
+    "tag": "saccharine",
+    "popularity": 19376
+  },
+  {
+    "tag": "unemploy",
+    "popularity": 19343
+  },
+  {
+    "tag": "uniclinal unipotent",
+    "popularity": 19310
+  },
+  {
+    "tag": "turbo",
+    "popularity": 19277
+  },
+  {
+    "tag": "sybarism",
+    "popularity": 19244
+  },
+  {
+    "tag": "motacilline",
+    "popularity": 19212
+  },
+  {
+    "tag": "weaselly",
+    "popularity": 19179
+  },
+  {
+    "tag": "plastid",
+    "popularity": 19147
+  },
+  {
+    "tag": "wasting",
+    "popularity": 19114
+  },
+  {
+    "tag": "begrime fluting",
+    "popularity": 19082
+  },
+  {
+    "tag": "Nephilinae",
+    "popularity": 19050
+  },
+  {
+    "tag": "disregardance",
+    "popularity": 19018
+  },
+  {
+    "tag": "Shakerlike",
+    "popularity": 18986
+  },
+  {
+    "tag": "uniped",
+    "popularity": 18954
+  },
+  {
+    "tag": "knap",
+    "popularity": 18922
+  },
+  {
+    "tag": "electivism undergardener",
+    "popularity": 18890
+  },
+  {
+    "tag": "hulverheaded",
+    "popularity": 18858
+  },
+  {
+    "tag": "unruptured",
+    "popularity": 18827
+  },
+  {
+    "tag": "solemnize credently",
+    "popularity": 18795
+  },
+  {
+    "tag": "pentastomoid possessingly",
+    "popularity": 18764
+  },
+  {
+    "tag": "octose",
+    "popularity": 18733
+  },
+  {
+    "tag": "psithurism indefensibility",
+    "popularity": 18701
+  },
+  {
+    "tag": "torrentuous cyanometer subcrenate",
+    "popularity": 18670
+  },
+  {
+    "tag": "photoplaywright tapaculo",
+    "popularity": 18639
+  },
+  {
+    "tag": "univalence",
+    "popularity": 18608
+  },
+  {
+    "tag": "Porthetria",
+    "popularity": 18577
+  },
+  {
+    "tag": "funambulo",
+    "popularity": 18546
+  },
+  {
+    "tag": "pedion",
+    "popularity": 18515
+  },
+  {
+    "tag": "horticulturally",
+    "popularity": 18485
+  },
+  {
+    "tag": "marennin",
+    "popularity": 18454
+  },
+  {
+    "tag": "horselaugh",
+    "popularity": 18423
+  },
+  {
+    "tag": "semiexecutive",
+    "popularity": 18393
+  },
+  {
+    "tag": "Monopteridae",
+    "popularity": 18363
+  },
+  {
+    "tag": "commonable",
+    "popularity": 18332
+  },
+  {
+    "tag": "dreariment",
+    "popularity": 18302
+  },
+  {
+    "tag": "disbud",
+    "popularity": 18272
+  },
+  {
+    "tag": "monocled",
+    "popularity": 18242
+  },
+  {
+    "tag": "hurlbarrow",
+    "popularity": 18212
+  },
+  {
+    "tag": "opiateproof",
+    "popularity": 18182
+  },
+  {
+    "tag": "Fahrenheit",
+    "popularity": 18152
+  },
+  {
+    "tag": "writhed",
+    "popularity": 18122
+  },
+  {
+    "tag": "Volstead",
+    "popularity": 18093
+  },
+  {
+    "tag": "yesternight",
+    "popularity": 18063
+  },
+  {
+    "tag": "readmittance",
+    "popularity": 18033
+  },
+  {
+    "tag": "reiterable",
+    "popularity": 18004
+  },
+  {
+    "tag": "triquetral",
+    "popularity": 17975
+  },
+  {
+    "tag": "guillotinement",
+    "popularity": 17945
+  },
+  {
+    "tag": "repermission",
+    "popularity": 17916
+  },
+  {
+    "tag": "assishly",
+    "popularity": 17887
+  },
+  {
+    "tag": "daidle",
+    "popularity": 17858
+  },
+  {
+    "tag": "prismatoid",
+    "popularity": 17829
+  },
+  {
+    "tag": "irreptitious",
+    "popularity": 17800
+  },
+  {
+    "tag": "sourdeline",
+    "popularity": 17771
+  },
+  {
+    "tag": "Austrian",
+    "popularity": 17742
+  },
+  {
+    "tag": "psychorrhagic",
+    "popularity": 17713
+  },
+  {
+    "tag": "Monumbo",
+    "popularity": 17685
+  },
+  {
+    "tag": "cloiochoanitic",
+    "popularity": 17656
+  },
+  {
+    "tag": "hant",
+    "popularity": 17628
+  },
+  {
+    "tag": "roily pulldown",
+    "popularity": 17599
+  },
+  {
+    "tag": "recongratulation",
+    "popularity": 17571
+  },
+  {
+    "tag": "Peking",
+    "popularity": 17543
+  },
+  {
+    "tag": "erdvark",
+    "popularity": 17514
+  },
+  {
+    "tag": "antimnemonic",
+    "popularity": 17486
+  },
+  {
+    "tag": "noncapillarity",
+    "popularity": 17458
+  },
+  {
+    "tag": "irrepressive",
+    "popularity": 17430
+  },
+  {
+    "tag": "Petromyzontes",
+    "popularity": 17402
+  },
+  {
+    "tag": "piscatorially",
+    "popularity": 17374
+  },
+  {
+    "tag": "cholesterosis",
+    "popularity": 17346
+  },
+  {
+    "tag": "denunciate",
+    "popularity": 17319
+  },
+  {
+    "tag": "unmetalled",
+    "popularity": 17291
+  },
+  {
+    "tag": "Tigris enruin",
+    "popularity": 17263
+  },
+  {
+    "tag": "anaspalin",
+    "popularity": 17236
+  },
+  {
+    "tag": "monodromy",
+    "popularity": 17208
+  },
+  {
+    "tag": "Canichanan",
+    "popularity": 17181
+  },
+  {
+    "tag": "mesolabe",
+    "popularity": 17154
+  },
+  {
+    "tag": "trichothallic overcunningness",
+    "popularity": 17127
+  },
+  {
+    "tag": "spinsterishly",
+    "popularity": 17099
+  },
+  {
+    "tag": "sensilla",
+    "popularity": 17072
+  },
+  {
+    "tag": "wifelkin",
+    "popularity": 17045
+  },
+  {
+    "tag": "suppositionless",
+    "popularity": 17018
+  },
+  {
+    "tag": "irksomeness",
+    "popularity": 16991
+  },
+  {
+    "tag": "sanbenito",
+    "popularity": 16964
+  },
+  {
+    "tag": "nonstatement",
+    "popularity": 16938
+  },
+  {
+    "tag": "phenoloid",
+    "popularity": 16911
+  },
+  {
+    "tag": "Steinberger",
+    "popularity": 16884
+  },
+  {
+    "tag": "replicated boom",
+    "popularity": 16858
+  },
+  {
+    "tag": "sciomachiology",
+    "popularity": 16831
+  },
+  {
+    "tag": "starwise",
+    "popularity": 16805
+  },
+  {
+    "tag": "prerich",
+    "popularity": 16778
+  },
+  {
+    "tag": "unspawned",
+    "popularity": 16752
+  },
+  {
+    "tag": "unindentable",
+    "popularity": 16726
+  },
+  {
+    "tag": "stromatic",
+    "popularity": 16700
+  },
+  {
+    "tag": "fetishize",
+    "popularity": 16673
+  },
+  {
+    "tag": "dihydroxy",
+    "popularity": 16647
+  },
+  {
+    "tag": "precaudal",
+    "popularity": 16621
+  },
+  {
+    "tag": "Madagascar",
+    "popularity": 16595
+  },
+  {
+    "tag": "repinement",
+    "popularity": 16570
+  },
+  {
+    "tag": "noncathedral wenzel",
+    "popularity": 16544
+  },
+  {
+    "tag": "corollike",
+    "popularity": 16518
+  },
+  {
+    "tag": "pubes unamortization",
+    "popularity": 16492
+  },
+  {
+    "tag": "brickcroft",
+    "popularity": 16467
+  },
+  {
+    "tag": "intertrabecular",
+    "popularity": 16441
+  },
+  {
+    "tag": "formulaic",
+    "popularity": 16416
+  },
+  {
+    "tag": "arienzo",
+    "popularity": 16390
+  },
+  {
+    "tag": "Mazzinian",
+    "popularity": 16365
+  },
+  {
+    "tag": "wallowishly",
+    "popularity": 16339
+  },
+  {
+    "tag": "sysselman",
+    "popularity": 16314
+  },
+  {
+    "tag": "seligmannite",
+    "popularity": 16289
+  },
+  {
+    "tag": "harlequinery",
+    "popularity": 16264
+  },
+  {
+    "tag": "zucchetto",
+    "popularity": 16239
+  },
+  {
+    "tag": "malonyl",
+    "popularity": 16214
+  },
+  {
+    "tag": "patwari",
+    "popularity": 16189
+  },
+  {
+    "tag": "neoholmia venturesomeness",
+    "popularity": 16164
+  },
+  {
+    "tag": "Dehwar",
+    "popularity": 16139
+  },
+  {
+    "tag": "fetiferous",
+    "popularity": 16114
+  },
+  {
+    "tag": "chromatophore",
+    "popularity": 16090
+  },
+  {
+    "tag": "reregistration",
+    "popularity": 16065
+  },
+  {
+    "tag": "alienor",
+    "popularity": 16040
+  },
+  {
+    "tag": "Hexagynia",
+    "popularity": 16016
+  },
+  {
+    "tag": "cerebrotonia",
+    "popularity": 15991
+  },
+  {
+    "tag": "deedbox",
+    "popularity": 15967
+  },
+  {
+    "tag": "staab",
+    "popularity": 15943
+  },
+  {
+    "tag": "uratemia",
+    "popularity": 15918
+  },
+  {
+    "tag": "flaunt",
+    "popularity": 15894
+  },
+  {
+    "tag": "bogy",
+    "popularity": 15870
+  },
+  {
+    "tag": "subcartilaginous",
+    "popularity": 15846
+  },
+  {
+    "tag": "protonephridial",
+    "popularity": 15822
+  },
+  {
+    "tag": "Boswellia",
+    "popularity": 15798
+  },
+  {
+    "tag": "relaxant untiaraed protoepiphyte",
+    "popularity": 15774
+  },
+  {
+    "tag": "nesslerization",
+    "popularity": 15750
+  },
+  {
+    "tag": "precession",
+    "popularity": 15726
+  },
+  {
+    "tag": "peat",
+    "popularity": 15702
+  },
+  {
+    "tag": "unbit",
+    "popularity": 15678
+  },
+  {
+    "tag": "snailish",
+    "popularity": 15655
+  },
+  {
+    "tag": "porismatical",
+    "popularity": 15631
+  },
+  {
+    "tag": "hooflike",
+    "popularity": 15608
+  },
+  {
+    "tag": "resuppose phene cranic",
+    "popularity": 15584
+  },
+  {
+    "tag": "peptonization kipskin",
+    "popularity": 15561
+  },
+  {
+    "tag": "birdstone",
+    "popularity": 15537
+  },
+  {
+    "tag": "empty inferoanterior",
+    "popularity": 15514
+  },
+  {
+    "tag": "androtauric",
+    "popularity": 15491
+  },
+  {
+    "tag": "triamide",
+    "popularity": 15467
+  },
+  {
+    "tag": "showmanry",
+    "popularity": 15444
+  },
+  {
+    "tag": "doing",
+    "popularity": 15421
+  },
+  {
+    "tag": "bouchaleen",
+    "popularity": 15398
+  },
+  {
+    "tag": "precollude",
+    "popularity": 15375
+  },
+  {
+    "tag": "finger",
+    "popularity": 15352
+  },
+  {
+    "tag": "limnetic intermessenger",
+    "popularity": 15329
+  },
+  {
+    "tag": "uncharitable picrotoxic",
+    "popularity": 15306
+  },
+  {
+    "tag": "nationalizer Phasmidae",
+    "popularity": 15283
+  },
+  {
+    "tag": "laughingstock",
+    "popularity": 15261
+  },
+  {
+    "tag": "nondeferential",
+    "popularity": 15238
+  },
+  {
+    "tag": "uproariously",
+    "popularity": 15215
+  },
+  {
+    "tag": "manzanilla",
+    "popularity": 15193
+  },
+  {
+    "tag": "khahoon",
+    "popularity": 15170
+  },
+  {
+    "tag": "olericulturally longshanks",
+    "popularity": 15148
+  },
+  {
+    "tag": "enthusiastically methionic",
+    "popularity": 15125
+  },
+  {
+    "tag": "pobs",
+    "popularity": 15103
+  },
+  {
+    "tag": "tricarpellate",
+    "popularity": 15081
+  },
+  {
+    "tag": "souterrain",
+    "popularity": 15058
+  },
+  {
+    "tag": "tethelin",
+    "popularity": 15036
+  },
+  {
+    "tag": "tartle",
+    "popularity": 15014
+  },
+  {
+    "tag": "tidelike",
+    "popularity": 14992
+  },
+  {
+    "tag": "cosmoramic",
+    "popularity": 14970
+  },
+  {
+    "tag": "pretardiness",
+    "popularity": 14948
+  },
+  {
+    "tag": "insoul",
+    "popularity": 14926
+  },
+  {
+    "tag": "anthroxan",
+    "popularity": 14904
+  },
+  {
+    "tag": "jilter",
+    "popularity": 14882
+  },
+  {
+    "tag": "pectinibranchian trematode",
+    "popularity": 14860
+  },
+  {
+    "tag": "Renaissancist",
+    "popularity": 14838
+  },
+  {
+    "tag": "imaginant",
+    "popularity": 14817
+  },
+  {
+    "tag": "supercensure",
+    "popularity": 14795
+  },
+  {
+    "tag": "festilogy",
+    "popularity": 14773
+  },
+  {
+    "tag": "regression",
+    "popularity": 14752
+  },
+  {
+    "tag": "mesobregmate languorously",
+    "popularity": 14730
+  },
+  {
+    "tag": "unsupernaturalized",
+    "popularity": 14709
+  },
+  {
+    "tag": "boobyish",
+    "popularity": 14687
+  },
+  {
+    "tag": "scopolamine",
+    "popularity": 14666
+  },
+  {
+    "tag": "reamputation unchristianly",
+    "popularity": 14645
+  },
+  {
+    "tag": "cuneatic",
+    "popularity": 14623
+  },
+  {
+    "tag": "heathberry",
+    "popularity": 14602
+  },
+  {
+    "tag": "hate",
+    "popularity": 14581
+  },
+  {
+    "tag": "redeemableness",
+    "popularity": 14560
+  },
+  {
+    "tag": "damasse",
+    "popularity": 14539
+  },
+  {
+    "tag": "thrillsome",
+    "popularity": 14518
+  },
+  {
+    "tag": "disseverment",
+    "popularity": 14497
+  },
+  {
+    "tag": "underbishopric Ostyak",
+    "popularity": 14476
+  },
+  {
+    "tag": "Exoascales",
+    "popularity": 14455
+  },
+  {
+    "tag": "soiled",
+    "popularity": 14434
+  },
+  {
+    "tag": "Cain",
+    "popularity": 14413
+  },
+  {
+    "tag": "mismanageable arenae",
+    "popularity": 14392
+  },
+  {
+    "tag": "manducate unhinderably",
+    "popularity": 14372
+  },
+  {
+    "tag": "peregrin",
+    "popularity": 14351
+  },
+  {
+    "tag": "musicianly",
+    "popularity": 14330
+  },
+  {
+    "tag": "aln",
+    "popularity": 14310
+  },
+  {
+    "tag": "intercentrum",
+    "popularity": 14289
+  },
+  {
+    "tag": "roothold",
+    "popularity": 14269
+  },
+  {
+    "tag": "jane aneurism",
+    "popularity": 14248
+  },
+  {
+    "tag": "insinuatively forefeel phytolatrous",
+    "popularity": 14228
+  },
+  {
+    "tag": "kanchil",
+    "popularity": 14208
+  },
+  {
+    "tag": "Austrophile",
+    "popularity": 14187
+  },
+  {
+    "tag": "unterrorized",
+    "popularity": 14167
+  },
+  {
+    "tag": "admeasure",
+    "popularity": 14147
+  },
+  {
+    "tag": "electrodissolution",
+    "popularity": 14127
+  },
+  {
+    "tag": "unweddedly",
+    "popularity": 14107
+  },
+  {
+    "tag": "unannoying",
+    "popularity": 14087
+  },
+  {
+    "tag": "uningenuous",
+    "popularity": 14067
+  },
+  {
+    "tag": "omnibenevolent",
+    "popularity": 14047
+  },
+  {
+    "tag": "commissure",
+    "popularity": 14027
+  },
+  {
+    "tag": "tellureted",
+    "popularity": 14007
+  },
+  {
+    "tag": "suffragan",
+    "popularity": 13987
+  },
+  {
+    "tag": "sphaeriaceous",
+    "popularity": 13967
+  },
+  {
+    "tag": "unfearing",
+    "popularity": 13947
+  },
+  {
+    "tag": "stentoriousness precounsellor",
+    "popularity": 13928
+  },
+  {
+    "tag": "haemaspectroscope",
+    "popularity": 13908
+  },
+  {
+    "tag": "teras",
+    "popularity": 13888
+  },
+  {
+    "tag": "pulicine",
+    "popularity": 13869
+  },
+  {
+    "tag": "colicystopyelitis",
+    "popularity": 13849
+  },
+  {
+    "tag": "Physalia",
+    "popularity": 13830
+  },
+  {
+    "tag": "Saxicolidae",
+    "popularity": 13810
+  },
+  {
+    "tag": "peritonital",
+    "popularity": 13791
+  },
+  {
+    "tag": "dysphotic",
+    "popularity": 13771
+  },
+  {
+    "tag": "unabandoned",
+    "popularity": 13752
+  },
+  {
+    "tag": "rashful",
+    "popularity": 13733
+  },
+  {
+    "tag": "goodyness Manobo",
+    "popularity": 13714
+  },
+  {
+    "tag": "glaring",
+    "popularity": 13694
+  },
+  {
+    "tag": "horrorful",
+    "popularity": 13675
+  },
+  {
+    "tag": "intercepting",
+    "popularity": 13656
+  },
+  {
+    "tag": "semifine",
+    "popularity": 13637
+  },
+  {
+    "tag": "Gaypoo",
+    "popularity": 13618
+  },
+  {
+    "tag": "Metrosideros",
+    "popularity": 13599
+  },
+  {
+    "tag": "thoracicolumbar",
+    "popularity": 13580
+  },
+  {
+    "tag": "unserried",
+    "popularity": 13561
+  },
+  {
+    "tag": "keeperess cauterization",
+    "popularity": 13542
+  },
+  {
+    "tag": "administrant",
+    "popularity": 13523
+  },
+  {
+    "tag": "unpropitiatedness",
+    "popularity": 13505
+  },
+  {
+    "tag": "pensileness",
+    "popularity": 13486
+  },
+  {
+    "tag": "quinaldic unreceivable",
+    "popularity": 13467
+  },
+  {
+    "tag": "Carnaria",
+    "popularity": 13448
+  },
+  {
+    "tag": "azothionium wurrus",
+    "popularity": 13430
+  },
+  {
+    "tag": "mistresshood",
+    "popularity": 13411
+  },
+  {
+    "tag": "Savara",
+    "popularity": 13393
+  },
+  {
+    "tag": "dasyurine",
+    "popularity": 13374
+  },
+  {
+    "tag": "superideal",
+    "popularity": 13356
+  },
+  {
+    "tag": "Parisianize",
+    "popularity": 13337
+  },
+  {
+    "tag": "underearth",
+    "popularity": 13319
+  },
+  {
+    "tag": "athrogenic",
+    "popularity": 13301
+  },
+  {
+    "tag": "communicate",
+    "popularity": 13282
+  },
+  {
+    "tag": "denervation enworthed",
+    "popularity": 13264
+  },
+  {
+    "tag": "subbromide",
+    "popularity": 13246
+  },
+  {
+    "tag": "stenocoriasis",
+    "popularity": 13228
+  },
+  {
+    "tag": "facetiousness",
+    "popularity": 13209
+  },
+  {
+    "tag": "twaddling",
+    "popularity": 13191
+  },
+  {
+    "tag": "tetartoconid",
+    "popularity": 13173
+  },
+  {
+    "tag": "audiophile",
+    "popularity": 13155
+  },
+  {
+    "tag": "fustigate",
+    "popularity": 13137
+  },
+  {
+    "tag": "Sorbian cacophonia",
+    "popularity": 13119
+  },
+  {
+    "tag": "fondish",
+    "popularity": 13101
+  },
+  {
+    "tag": "endomastoiditis",
+    "popularity": 13084
+  },
+  {
+    "tag": "sniptious",
+    "popularity": 13066
+  },
+  {
+    "tag": "glochidiate",
+    "popularity": 13048
+  },
+  {
+    "tag": "polycarboxylic",
+    "popularity": 13030
+  },
+  {
+    "tag": "stamp",
+    "popularity": 13012
+  },
+  {
+    "tag": "tritonymph endotoxoid",
+    "popularity": 12995
+  },
+  {
+    "tag": "wolfskin",
+    "popularity": 12977
+  },
+  {
+    "tag": "oncosimeter",
+    "popularity": 12959
+  },
+  {
+    "tag": "outward",
+    "popularity": 12942
+  },
+  {
+    "tag": "circumscribed",
+    "popularity": 12924
+  },
+  {
+    "tag": "autohemolytic",
+    "popularity": 12907
+  },
+  {
+    "tag": "isorhamnose",
+    "popularity": 12889
+  },
+  {
+    "tag": "monarchomachic",
+    "popularity": 12872
+  },
+  {
+    "tag": "phaenomenon",
+    "popularity": 12855
+  },
+  {
+    "tag": "angiopressure",
+    "popularity": 12837
+  },
+  {
+    "tag": "similarize",
+    "popularity": 12820
+  },
+  {
+    "tag": "unseeable",
+    "popularity": 12803
+  },
+  {
+    "tag": "Toryize",
+    "popularity": 12785
+  },
+  {
+    "tag": "fruitling",
+    "popularity": 12768
+  },
+  {
+    "tag": "axle",
+    "popularity": 12751
+  },
+  {
+    "tag": "priestal cocked",
+    "popularity": 12734
+  },
+  {
+    "tag": "serotoxin",
+    "popularity": 12717
+  },
+  {
+    "tag": "unmovably",
+    "popularity": 12700
+  },
+  {
+    "tag": "darbha",
+    "popularity": 12683
+  },
+  {
+    "tag": "Mongolize",
+    "popularity": 12666
+  },
+  {
+    "tag": "clusteringly",
+    "popularity": 12649
+  },
+  {
+    "tag": "tendence",
+    "popularity": 12632
+  },
+  {
+    "tag": "foziness",
+    "popularity": 12615
+  },
+  {
+    "tag": "brickkiln lithify",
+    "popularity": 12598
+  },
+  {
+    "tag": "unpriest",
+    "popularity": 12581
+  },
+  {
+    "tag": "convincer",
+    "popularity": 12564
+  },
+  {
+    "tag": "mornlike",
+    "popularity": 12548
+  },
+  {
+    "tag": "overaddiction ostentatiousness",
+    "popularity": 12531
+  },
+  {
+    "tag": "diffusively moccasin pendom",
+    "popularity": 12514
+  },
+  {
+    "tag": "boose",
+    "popularity": 12498
+  },
+  {
+    "tag": "myonosus",
+    "popularity": 12481
+  },
+  {
+    "tag": "handsome",
+    "popularity": 12464
+  },
+  {
+    "tag": "paroxysmic",
+    "popularity": 12448
+  },
+  {
+    "tag": "Ulidian",
+    "popularity": 12431
+  },
+  {
+    "tag": "heartache",
+    "popularity": 12415
+  },
+  {
+    "tag": "torporize",
+    "popularity": 12398
+  },
+  {
+    "tag": "hippish",
+    "popularity": 12382
+  },
+  {
+    "tag": "stigmal militation",
+    "popularity": 12366
+  },
+  {
+    "tag": "matmaker",
+    "popularity": 12349
+  },
+  {
+    "tag": "marantaceous bivoluminous",
+    "popularity": 12333
+  },
+  {
+    "tag": "Uraniidae",
+    "popularity": 12317
+  },
+  {
+    "tag": "risper",
+    "popularity": 12301
+  },
+  {
+    "tag": "tintinnabulation",
+    "popularity": 12284
+  },
+  {
+    "tag": "tributorian",
+    "popularity": 12268
+  },
+  {
+    "tag": "ashamedly",
+    "popularity": 12252
+  },
+  {
+    "tag": "Macrourus",
+    "popularity": 12236
+  },
+  {
+    "tag": "Chora",
+    "popularity": 12220
+  },
+  {
+    "tag": "caul",
+    "popularity": 12204
+  },
+  {
+    "tag": "exsector",
+    "popularity": 12188
+  },
+  {
+    "tag": "acutish",
+    "popularity": 12172
+  },
+  {
+    "tag": "amphichrome",
+    "popularity": 12156
+  },
+  {
+    "tag": "guarder",
+    "popularity": 12140
+  },
+  {
+    "tag": "sculpturally",
+    "popularity": 12124
+  },
+  {
+    "tag": "benightmare",
+    "popularity": 12108
+  },
+  {
+    "tag": "chucky",
+    "popularity": 12093
+  },
+  {
+    "tag": "Venetian",
+    "popularity": 12077
+  },
+  {
+    "tag": "autotheater",
+    "popularity": 12061
+  },
+  {
+    "tag": "planarioid",
+    "popularity": 12045
+  },
+  {
+    "tag": "handkerchiefful",
+    "popularity": 12030
+  },
+  {
+    "tag": "fuliginousness potentize",
+    "popularity": 12014
+  },
+  {
+    "tag": "pantheum",
+    "popularity": 11998
+  },
+  {
+    "tag": "heavyweight",
+    "popularity": 11983
+  },
+  {
+    "tag": "unbrick",
+    "popularity": 11967
+  },
+  {
+    "tag": "duomachy",
+    "popularity": 11952
+  },
+  {
+    "tag": "polyphyodont",
+    "popularity": 11936
+  },
+  {
+    "tag": "hibernacle",
+    "popularity": 11921
+  },
+  {
+    "tag": "undistend",
+    "popularity": 11905
+  },
+  {
+    "tag": "hystericky",
+    "popularity": 11890
+  },
+  {
+    "tag": "paleolimnology",
+    "popularity": 11875
+  },
+  {
+    "tag": "cedarware",
+    "popularity": 11859
+  },
+  {
+    "tag": "overwrested",
+    "popularity": 11844
+  },
+  {
+    "tag": "Syriacism",
+    "popularity": 11829
+  },
+  {
+    "tag": "pretan",
+    "popularity": 11813
+  },
+  {
+    "tag": "formant",
+    "popularity": 11798
+  },
+  {
+    "tag": "pharmacopoeist Fedia",
+    "popularity": 11783
+  },
+  {
+    "tag": "exorcist eerisome",
+    "popularity": 11768
+  },
+  {
+    "tag": "separation",
+    "popularity": 11753
+  },
+  {
+    "tag": "infancy",
+    "popularity": 11738
+  },
+  {
+    "tag": "ecrasite",
+    "popularity": 11723
+  },
+  {
+    "tag": "propolize",
+    "popularity": 11708
+  },
+  {
+    "tag": "uncram phyllin",
+    "popularity": 11693
+  },
+  {
+    "tag": "thymopathy",
+    "popularity": 11678
+  },
+  {
+    "tag": "omniscient",
+    "popularity": 11663
+  },
+  {
+    "tag": "coussinet hazer",
+    "popularity": 11648
+  },
+  {
+    "tag": "contributiveness",
+    "popularity": 11633
+  },
+  {
+    "tag": "septifluous",
+    "popularity": 11618
+  },
+  {
+    "tag": "halfness",
+    "popularity": 11603
+  },
+  {
+    "tag": "tocher",
+    "popularity": 11589
+  },
+  {
+    "tag": "monotonist",
+    "popularity": 11574
+  },
+  {
+    "tag": "headchair",
+    "popularity": 11559
+  },
+  {
+    "tag": "everywhence",
+    "popularity": 11544
+  },
+  {
+    "tag": "gerate",
+    "popularity": 11530
+  },
+  {
+    "tag": "unrepellent",
+    "popularity": 11515
+  },
+  {
+    "tag": "inidoneous",
+    "popularity": 11500
+  },
+  {
+    "tag": "Rifi",
+    "popularity": 11486
+  },
+  {
+    "tag": "unstop",
+    "popularity": 11471
+  },
+  {
+    "tag": "conformer",
+    "popularity": 11457
+  },
+  {
+    "tag": "vivisectionally",
+    "popularity": 11442
+  },
+  {
+    "tag": "nonfinishing",
+    "popularity": 11428
+  },
+  {
+    "tag": "tyranness",
+    "popularity": 11413
+  },
+  {
+    "tag": "shepherdage havoc",
+    "popularity": 11399
+  },
+  {
+    "tag": "coronale",
+    "popularity": 11385
+  },
+  {
+    "tag": "airmarker",
+    "popularity": 11370
+  },
+  {
+    "tag": "subpanel",
+    "popularity": 11356
+  },
+  {
+    "tag": "conciliation",
+    "popularity": 11342
+  },
+  {
+    "tag": "supergun",
+    "popularity": 11327
+  },
+  {
+    "tag": "photoheliography",
+    "popularity": 11313
+  },
+  {
+    "tag": "cacosmia",
+    "popularity": 11299
+  },
+  {
+    "tag": "caressant",
+    "popularity": 11285
+  },
+  {
+    "tag": "swivet",
+    "popularity": 11270
+  },
+  {
+    "tag": "coddler",
+    "popularity": 11256
+  },
+  {
+    "tag": "rakehellish",
+    "popularity": 11242
+  },
+  {
+    "tag": "recohabitation",
+    "popularity": 11228
+  },
+  {
+    "tag": "postillator",
+    "popularity": 11214
+  },
+  {
+    "tag": "receipt",
+    "popularity": 11200
+  },
+  {
+    "tag": "nonconformistical",
+    "popularity": 11186
+  },
+  {
+    "tag": "unglorified",
+    "popularity": 11172
+  },
+  {
+    "tag": "unordinariness",
+    "popularity": 11158
+  },
+  {
+    "tag": "tetrahydroxy",
+    "popularity": 11144
+  },
+  {
+    "tag": "haploperistomic corporeity",
+    "popularity": 11130
+  },
+  {
+    "tag": "varical",
+    "popularity": 11117
+  },
+  {
+    "tag": "pilferment",
+    "popularity": 11103
+  },
+  {
+    "tag": "reverentially playcraft",
+    "popularity": 11089
+  },
+  {
+    "tag": "unretentive",
+    "popularity": 11075
+  },
+  {
+    "tag": "readiness",
+    "popularity": 11061
+  },
+  {
+    "tag": "thermomagnetism",
+    "popularity": 11048
+  },
+  {
+    "tag": "spotless",
+    "popularity": 11034
+  },
+  {
+    "tag": "semishrubby",
+    "popularity": 11020
+  },
+  {
+    "tag": "metrotomy",
+    "popularity": 11007
+  },
+  {
+    "tag": "hocker",
+    "popularity": 10993
+  },
+  {
+    "tag": "anecdotal",
+    "popularity": 10979
+  },
+  {
+    "tag": "tetrabelodont",
+    "popularity": 10966
+  },
+  {
+    "tag": "Ramillied",
+    "popularity": 10952
+  },
+  {
+    "tag": "sympatheticism",
+    "popularity": 10939
+  },
+  {
+    "tag": "kiskatom",
+    "popularity": 10925
+  },
+  {
+    "tag": "concyclically",
+    "popularity": 10912
+  },
+  {
+    "tag": "tunicless",
+    "popularity": 10899
+  },
+  {
+    "tag": "formalistic",
+    "popularity": 10885
+  },
+  {
+    "tag": "thermacogenesis",
+    "popularity": 10872
+  },
+  {
+    "tag": "multimotored",
+    "popularity": 10858
+  },
+  {
+    "tag": "inversive",
+    "popularity": 10845
+  },
+  {
+    "tag": "Jatki",
+    "popularity": 10832
+  },
+  {
+    "tag": "highest",
+    "popularity": 10818
+  },
+  {
+    "tag": "rubidic",
+    "popularity": 10805
+  },
+  {
+    "tag": "acranial",
+    "popularity": 10792
+  },
+  {
+    "tag": "pulvinulus",
+    "popularity": 10779
+  },
+  {
+    "tag": "nattiness",
+    "popularity": 10766
+  },
+  {
+    "tag": "antisimoniacal",
+    "popularity": 10752
+  },
+  {
+    "tag": "tetanize",
+    "popularity": 10739
+  },
+  {
+    "tag": "spectrophobia",
+    "popularity": 10726
+  },
+  {
+    "tag": "monopolitical",
+    "popularity": 10713
+  },
+  {
+    "tag": "teallite",
+    "popularity": 10700
+  },
+  {
+    "tag": "alicyclic interpellator",
+    "popularity": 10687
+  },
+  {
+    "tag": "nonsynthesized",
+    "popularity": 10674
+  },
+  {
+    "tag": "wheelwrighting",
+    "popularity": 10661
+  },
+  {
+    "tag": "pelliculate",
+    "popularity": 10648
+  },
+  {
+    "tag": "Euphyllopoda",
+    "popularity": 10635
+  },
+  {
+    "tag": "graver",
+    "popularity": 10622
+  },
+  {
+    "tag": "automorph",
+    "popularity": 10609
+  },
+  {
+    "tag": "underhanded",
+    "popularity": 10597
+  },
+  {
+    "tag": "causal",
+    "popularity": 10584
+  },
+  {
+    "tag": "odoom",
+    "popularity": 10571
+  },
+  {
+    "tag": "apodictical",
+    "popularity": 10558
+  },
+  {
+    "tag": "foundery",
+    "popularity": 10545
+  },
+  {
+    "tag": "unneighbored",
+    "popularity": 10533
+  },
+  {
+    "tag": "woolshearing",
+    "popularity": 10520
+  },
+  {
+    "tag": "boschveld",
+    "popularity": 10507
+  },
+  {
+    "tag": "unhardened lipopod",
+    "popularity": 10495
+  },
+  {
+    "tag": "unenriching",
+    "popularity": 10482
+  },
+  {
+    "tag": "spak",
+    "popularity": 10469
+  },
+  {
+    "tag": "yogasana",
+    "popularity": 10457
+  },
+  {
+    "tag": "depoetize",
+    "popularity": 10444
+  },
+  {
+    "tag": "parousiamania",
+    "popularity": 10432
+  },
+  {
+    "tag": "longlegs",
+    "popularity": 10419
+  },
+  {
+    "tag": "gelatinizability",
+    "popularity": 10407
+  },
+  {
+    "tag": "edeology",
+    "popularity": 10394
+  },
+  {
+    "tag": "sodwork",
+    "popularity": 10382
+  },
+  {
+    "tag": "somnambule",
+    "popularity": 10369
+  },
+  {
+    "tag": "antiquing",
+    "popularity": 10357
+  },
+  {
+    "tag": "intaker",
+    "popularity": 10344
+  },
+  {
+    "tag": "Gerberia",
+    "popularity": 10332
+  },
+  {
+    "tag": "preadmit",
+    "popularity": 10320
+  },
+  {
+    "tag": "bullhorn",
+    "popularity": 10307
+  },
+  {
+    "tag": "sororal",
+    "popularity": 10295
+  },
+  {
+    "tag": "phaeophyceous",
+    "popularity": 10283
+  },
+  {
+    "tag": "omphalopsychite",
+    "popularity": 10271
+  },
+  {
+    "tag": "substantious",
+    "popularity": 10258
+  },
+  {
+    "tag": "undemonstratively",
+    "popularity": 10246
+  },
+  {
+    "tag": "corallike blackit",
+    "popularity": 10234
+  },
+  {
+    "tag": "amoebous",
+    "popularity": 10222
+  },
+  {
+    "tag": "Polypodium",
+    "popularity": 10210
+  },
+  {
+    "tag": "blodite",
+    "popularity": 10198
+  },
+  {
+    "tag": "hordarian",
+    "popularity": 10186
+  },
+  {
+    "tag": "nonmoral",
+    "popularity": 10174
+  },
+  {
+    "tag": "dredgeful",
+    "popularity": 10162
+  },
+  {
+    "tag": "nourishingly",
+    "popularity": 10150
+  },
+  {
+    "tag": "seamy",
+    "popularity": 10138
+  },
+  {
+    "tag": "vara",
+    "popularity": 10126
+  },
+  {
+    "tag": "incorruptibleness",
+    "popularity": 10114
+  },
+  {
+    "tag": "manipulator",
+    "popularity": 10102
+  },
+  {
+    "tag": "chromodiascope uncountably",
+    "popularity": 10090
+  },
+  {
+    "tag": "typhemia",
+    "popularity": 10078
+  },
+  {
+    "tag": "Smalcaldic",
+    "popularity": 10066
+  },
+  {
+    "tag": "precontrive",
+    "popularity": 10054
+  },
+  {
+    "tag": "sowarry",
+    "popularity": 10042
+  },
+  {
+    "tag": "monopodic",
+    "popularity": 10031
+  },
+  {
+    "tag": "recodify",
+    "popularity": 10019
+  },
+  {
+    "tag": "phosphowolframic rimple",
+    "popularity": 10007
+  },
+  {
+    "tag": "triconch",
+    "popularity": 9995
+  },
+  {
+    "tag": "pycnodontoid",
+    "popularity": 9984
+  },
+  {
+    "tag": "bradyspermatism",
+    "popularity": 9972
+  },
+  {
+    "tag": "extensionist",
+    "popularity": 9960
+  },
+  {
+    "tag": "characterize",
+    "popularity": 9949
+  },
+  {
+    "tag": "anatreptic proteolytic",
+    "popularity": 9937
+  },
+  {
+    "tag": "waterboard",
+    "popularity": 9925
+  },
+  {
+    "tag": "allopathically",
+    "popularity": 9914
+  },
+  {
+    "tag": "arithmetician",
+    "popularity": 9902
+  },
+  {
+    "tag": "subsist",
+    "popularity": 9891
+  },
+  {
+    "tag": "Islamitish",
+    "popularity": 9879
+  },
+  {
+    "tag": "biddy",
+    "popularity": 9868
+  },
+  {
+    "tag": "reverberation",
+    "popularity": 9856
+  },
+  {
+    "tag": "Zaporogue",
+    "popularity": 9845
+  },
+  {
+    "tag": "soapberry",
+    "popularity": 9833
+  },
+  {
+    "tag": "physiognomics",
+    "popularity": 9822
+  },
+  {
+    "tag": "hospitalization",
+    "popularity": 9810
+  },
+  {
+    "tag": "dissembler",
+    "popularity": 9799
+  },
+  {
+    "tag": "festinate",
+    "popularity": 9788
+  },
+  {
+    "tag": "angiectopia",
+    "popularity": 9776
+  },
+  {
+    "tag": "Pulicidae",
+    "popularity": 9765
+  },
+  {
+    "tag": "beslimer",
+    "popularity": 9754
+  },
+  {
+    "tag": "nontreaty",
+    "popularity": 9743
+  },
+  {
+    "tag": "unhaggled",
+    "popularity": 9731
+  },
+  {
+    "tag": "catfall",
+    "popularity": 9720
+  },
+  {
+    "tag": "stola",
+    "popularity": 9709
+  },
+  {
+    "tag": "pataco",
+    "popularity": 9698
+  },
+  {
+    "tag": "ontologistic",
+    "popularity": 9686
+  },
+  {
+    "tag": "aerosphere",
+    "popularity": 9675
+  },
+  {
+    "tag": "deobstruent",
+    "popularity": 9664
+  },
+  {
+    "tag": "threepence",
+    "popularity": 9653
+  },
+  {
+    "tag": "cyprinoid",
+    "popularity": 9642
+  },
+  {
+    "tag": "overbank",
+    "popularity": 9631
+  },
+  {
+    "tag": "prostyle",
+    "popularity": 9620
+  },
+  {
+    "tag": "photoactivation",
+    "popularity": 9609
+  },
+  {
+    "tag": "homothetic",
+    "popularity": 9598
+  },
+  {
+    "tag": "roguedom",
+    "popularity": 9587
+  },
+  {
+    "tag": "underschool",
+    "popularity": 9576
+  },
+  {
+    "tag": "tractility",
+    "popularity": 9565
+  },
+  {
+    "tag": "gardenin",
+    "popularity": 9554
+  },
+  {
+    "tag": "Micromastictora",
+    "popularity": 9543
+  },
+  {
+    "tag": "gossypine",
+    "popularity": 9532
+  },
+  {
+    "tag": "amylodyspepsia",
+    "popularity": 9521
+  },
+  {
+    "tag": "Luciana",
+    "popularity": 9510
+  },
+  {
+    "tag": "meetly nonfisherman",
+    "popularity": 9500
+  },
+  {
+    "tag": "backhanded",
+    "popularity": 9489
+  },
+  {
+    "tag": "decrustation",
+    "popularity": 9478
+  },
+  {
+    "tag": "pinrail",
+    "popularity": 9467
+  },
+  {
+    "tag": "Mahori",
+    "popularity": 9456
+  },
+  {
+    "tag": "unsizable",
+    "popularity": 9446
+  },
+  {
+    "tag": "disawa",
+    "popularity": 9435
+  },
+  {
+    "tag": "launderability inconsidered",
+    "popularity": 9424
+  },
+  {
+    "tag": "unclassical",
+    "popularity": 9414
+  },
+  {
+    "tag": "inobtrusiveness",
+    "popularity": 9403
+  },
+  {
+    "tag": "sialogenous",
+    "popularity": 9392
+  },
+  {
+    "tag": "sulphonamide",
+    "popularity": 9382
+  },
+  {
+    "tag": "diluvion",
+    "popularity": 9371
+  },
+  {
+    "tag": "deuteranope",
+    "popularity": 9361
+  },
+  {
+    "tag": "addition",
+    "popularity": 9350
+  },
+  {
+    "tag": "bockeret",
+    "popularity": 9339
+  },
+  {
+    "tag": "unidentified",
+    "popularity": 9329
+  },
+  {
+    "tag": "caryatic",
+    "popularity": 9318
+  },
+  {
+    "tag": "misattribution",
+    "popularity": 9308
+  },
+  {
+    "tag": "outray",
+    "popularity": 9297
+  },
+  {
+    "tag": "areometrical",
+    "popularity": 9287
+  },
+  {
+    "tag": "antilogism",
+    "popularity": 9277
+  },
+  {
+    "tag": "inadjustable",
+    "popularity": 9266
+  },
+  {
+    "tag": "byssus",
+    "popularity": 9256
+  },
+  {
+    "tag": "trun",
+    "popularity": 9245
+  },
+  {
+    "tag": "thereology",
+    "popularity": 9235
+  },
+  {
+    "tag": "extort",
+    "popularity": 9225
+  },
+  {
+    "tag": "bumpkin",
+    "popularity": 9214
+  },
+  {
+    "tag": "sulphobenzide",
+    "popularity": 9204
+  },
+  {
+    "tag": "hydrogeology",
+    "popularity": 9194
+  },
+  {
+    "tag": "nidulariaceous",
+    "popularity": 9183
+  },
+  {
+    "tag": "propodiale",
+    "popularity": 9173
+  },
+  {
+    "tag": "fierily",
+    "popularity": 9163
+  },
+  {
+    "tag": "aerotonometry",
+    "popularity": 9153
+  },
+  {
+    "tag": "pelobatid oversuperstitious",
+    "popularity": 9142
+  },
+  {
+    "tag": "restringent",
+    "popularity": 9132
+  },
+  {
+    "tag": "tetrapodic",
+    "popularity": 9122
+  },
+  {
+    "tag": "heroicness Vendidad",
+    "popularity": 9112
+  },
+  {
+    "tag": "Sphingurus",
+    "popularity": 9102
+  },
+  {
+    "tag": "sclerote",
+    "popularity": 9092
+  },
+  {
+    "tag": "unkeyed",
+    "popularity": 9082
+  },
+  {
+    "tag": "superparliamentary",
+    "popularity": 9072
+  },
+  {
+    "tag": "hetericism",
+    "popularity": 9061
+  },
+  {
+    "tag": "hucklebone",
+    "popularity": 9051
+  },
+  {
+    "tag": "yojan",
+    "popularity": 9041
+  },
+  {
+    "tag": "bossed",
+    "popularity": 9031
+  },
+  {
+    "tag": "spiderwork",
+    "popularity": 9021
+  },
+  {
+    "tag": "millfeed dullery",
+    "popularity": 9011
+  },
+  {
+    "tag": "adnoun",
+    "popularity": 9001
+  },
+  {
+    "tag": "mesometric",
+    "popularity": 8992
+  },
+  {
+    "tag": "doublehandedness",
+    "popularity": 8982
+  },
+  {
+    "tag": "suppurant",
+    "popularity": 8972
+  },
+  {
+    "tag": "Berlinize",
+    "popularity": 8962
+  },
+  {
+    "tag": "sontag",
+    "popularity": 8952
+  },
+  {
+    "tag": "biplane",
+    "popularity": 8942
+  },
+  {
+    "tag": "insula",
+    "popularity": 8932
+  },
+  {
+    "tag": "unbrand",
+    "popularity": 8922
+  },
+  {
+    "tag": "Basilosaurus",
+    "popularity": 8913
+  },
+  {
+    "tag": "prenomination",
+    "popularity": 8903
+  },
+  {
+    "tag": "untextual",
+    "popularity": 8893
+  },
+  {
+    "tag": "coleslaw",
+    "popularity": 8883
+  },
+  {
+    "tag": "langsyne",
+    "popularity": 8874
+  },
+  {
+    "tag": "impede",
+    "popularity": 8864
+  },
+  {
+    "tag": "irrigator",
+    "popularity": 8854
+  },
+  {
+    "tag": "deflocculation",
+    "popularity": 8844
+  },
+  {
+    "tag": "narghile",
+    "popularity": 8835
+  },
+  {
+    "tag": "unguardedly ebenaceous",
+    "popularity": 8825
+  },
+  {
+    "tag": "conversantly subocular",
+    "popularity": 8815
+  },
+  {
+    "tag": "hydroponic",
+    "popularity": 8806
+  },
+  {
+    "tag": "anthropopsychism",
+    "popularity": 8796
+  },
+  {
+    "tag": "panoptic",
+    "popularity": 8787
+  },
+  {
+    "tag": "insufferable",
+    "popularity": 8777
+  },
+  {
+    "tag": "salema",
+    "popularity": 8768
+  },
+  {
+    "tag": "Myriapoda",
+    "popularity": 8758
+  },
+  {
+    "tag": "regarrison",
+    "popularity": 8748
+  },
+  {
+    "tag": "overlearned",
+    "popularity": 8739
+  },
+  {
+    "tag": "ultraroyalist conventical bureaucratical",
+    "popularity": 8729
+  },
+  {
+    "tag": "epicaridan",
+    "popularity": 8720
+  },
+  {
+    "tag": "poetastress",
+    "popularity": 8711
+  },
+  {
+    "tag": "monophthalmus",
+    "popularity": 8701
+  },
+  {
+    "tag": "simnel",
+    "popularity": 8692
+  },
+  {
+    "tag": "compotor",
+    "popularity": 8682
+  },
+  {
+    "tag": "hydrolase",
+    "popularity": 8673
+  },
+  {
+    "tag": "attemptless",
+    "popularity": 8663
+  },
+  {
+    "tag": "visceroptosis",
+    "popularity": 8654
+  },
+  {
+    "tag": "unpreparedly",
+    "popularity": 8645
+  },
+  {
+    "tag": "mastage",
+    "popularity": 8635
+  },
+  {
+    "tag": "preinfluence",
+    "popularity": 8626
+  },
+  {
+    "tag": "Siwan",
+    "popularity": 8617
+  },
+  {
+    "tag": "ceratotheca belvedere",
+    "popularity": 8607
+  },
+  {
+    "tag": "disenablement",
+    "popularity": 8598
+  },
+  {
+    "tag": "nine",
+    "popularity": 8589
+  },
+  {
+    "tag": "spellingdown abridgment",
+    "popularity": 8580
+  },
+  {
+    "tag": "twilightless",
+    "popularity": 8571
+  },
+  {
+    "tag": "overflow",
+    "popularity": 8561
+  },
+  {
+    "tag": "mismeasurement",
+    "popularity": 8552
+  },
+  {
+    "tag": "nawabship",
+    "popularity": 8543
+  },
+  {
+    "tag": "Phrynosoma",
+    "popularity": 8534
+  },
+  {
+    "tag": "unanticipatingly",
+    "popularity": 8525
+  },
+  {
+    "tag": "blankite",
+    "popularity": 8516
+  },
+  {
+    "tag": "role",
+    "popularity": 8506
+  },
+  {
+    "tag": "peperine edelweiss",
+    "popularity": 8497
+  },
+  {
+    "tag": "unhysterical",
+    "popularity": 8488
+  },
+  {
+    "tag": "attentiveness",
+    "popularity": 8479
+  },
+  {
+    "tag": "scintillant",
+    "popularity": 8470
+  },
+  {
+    "tag": "stenostomatous",
+    "popularity": 8461
+  },
+  {
+    "tag": "pectinite",
+    "popularity": 8452
+  },
+  {
+    "tag": "herring",
+    "popularity": 8443
+  },
+  {
+    "tag": "interroom",
+    "popularity": 8434
+  },
+  {
+    "tag": "laccol",
+    "popularity": 8425
+  },
+  {
+    "tag": "unpartably kylite",
+    "popularity": 8416
+  },
+  {
+    "tag": "spirivalve",
+    "popularity": 8407
+  },
+  {
+    "tag": "hoosegow",
+    "popularity": 8398
+  },
+  {
+    "tag": "doat",
+    "popularity": 8389
+  },
+  {
+    "tag": "amphibian",
+    "popularity": 8380
+  },
+  {
+    "tag": "exposit",
+    "popularity": 8371
+  },
+  {
+    "tag": "canopy",
+    "popularity": 8363
+  },
+  {
+    "tag": "houndlike",
+    "popularity": 8354
+  },
+  {
+    "tag": "spikebill",
+    "popularity": 8345
+  },
+  {
+    "tag": "wiseacre pyrotechnic",
+    "popularity": 8336
+  },
+  {
+    "tag": "confessingly woodman",
+    "popularity": 8327
+  },
+  {
+    "tag": "overside",
+    "popularity": 8318
+  },
+  {
+    "tag": "oftwhiles",
+    "popularity": 8310
+  },
+  {
+    "tag": "Musophagidae",
+    "popularity": 8301
+  },
+  {
+    "tag": "slumberer",
+    "popularity": 8292
+  },
+  {
+    "tag": "leiotrichy",
+    "popularity": 8283
+  },
+  {
+    "tag": "Mantispidae",
+    "popularity": 8275
+  },
+  {
+    "tag": "perceptually",
+    "popularity": 8266
+  },
+  {
+    "tag": "biller",
+    "popularity": 8257
+  },
+  {
+    "tag": "eudaemonical",
+    "popularity": 8249
+  },
+  {
+    "tag": "underfiend",
+    "popularity": 8240
+  },
+  {
+    "tag": "impartible",
+    "popularity": 8231
+  },
+  {
+    "tag": "saxicavous",
+    "popularity": 8223
+  },
+  {
+    "tag": "yapster",
+    "popularity": 8214
+  },
+  {
+    "tag": "aliseptal",
+    "popularity": 8205
+  },
+  {
+    "tag": "omniparient",
+    "popularity": 8197
+  },
+  {
+    "tag": "nishiki",
+    "popularity": 8188
+  },
+  {
+    "tag": "yuzluk",
+    "popularity": 8180
+  },
+  {
+    "tag": "solderer",
+    "popularity": 8171
+  },
+  {
+    "tag": "Pinna",
+    "popularity": 8162
+  },
+  {
+    "tag": "reinterfere",
+    "popularity": 8154
+  },
+  {
+    "tag": "superepic",
+    "popularity": 8145
+  },
+  {
+    "tag": "ronquil",
+    "popularity": 8137
+  },
+  {
+    "tag": "bratstvo",
+    "popularity": 8128
+  },
+  {
+    "tag": "Thea",
+    "popularity": 8120
+  },
+  {
+    "tag": "hermaphroditical",
+    "popularity": 8111
+  },
+  {
+    "tag": "enlief",
+    "popularity": 8103
+  },
+  {
+    "tag": "Jesuate",
+    "popularity": 8095
+  },
+  {
+    "tag": "gaysome",
+    "popularity": 8086
+  },
+  {
+    "tag": "iliohypogastric",
+    "popularity": 8078
+  },
+  {
+    "tag": "regardance",
+    "popularity": 8069
+  },
+  {
+    "tag": "cumulately",
+    "popularity": 8061
+  },
+  {
+    "tag": "haustorial nucleolocentrosome",
+    "popularity": 8053
+  },
+  {
+    "tag": "cosmocrat",
+    "popularity": 8044
+  },
+  {
+    "tag": "onyxitis",
+    "popularity": 8036
+  },
+  {
+    "tag": "Cabinda",
+    "popularity": 8028
+  },
+  {
+    "tag": "coresort",
+    "popularity": 8019
+  },
+  {
+    "tag": "drusy preformant",
+    "popularity": 8011
+  },
+  {
+    "tag": "piningly",
+    "popularity": 8003
+  },
+  {
+    "tag": "bootlessly",
+    "popularity": 7994
+  },
+  {
+    "tag": "talari",
+    "popularity": 7986
+  },
+  {
+    "tag": "amidoacetal",
+    "popularity": 7978
+  },
+  {
+    "tag": "pschent",
+    "popularity": 7970
+  },
+  {
+    "tag": "consumptional scarer titivate",
+    "popularity": 7962
+  },
+  {
+    "tag": "Anserinae",
+    "popularity": 7953
+  },
+  {
+    "tag": "flaunter",
+    "popularity": 7945
+  },
+  {
+    "tag": "reindeer",
+    "popularity": 7937
+  },
+  {
+    "tag": "disparage",
+    "popularity": 7929
+  },
+  {
+    "tag": "superheat",
+    "popularity": 7921
+  },
+  {
+    "tag": "Chromatium",
+    "popularity": 7912
+  },
+  {
+    "tag": "Tina",
+    "popularity": 7904
+  },
+  {
+    "tag": "rededicatory",
+    "popularity": 7896
+  },
+  {
+    "tag": "nontransient",
+    "popularity": 7888
+  },
+  {
+    "tag": "Phocaean brinkless",
+    "popularity": 7880
+  },
+  {
+    "tag": "ventriculose",
+    "popularity": 7872
+  },
+  {
+    "tag": "upplough",
+    "popularity": 7864
+  },
+  {
+    "tag": "succorless",
+    "popularity": 7856
+  },
+  {
+    "tag": "hayrake",
+    "popularity": 7848
+  },
+  {
+    "tag": "merriness amorphia",
+    "popularity": 7840
+  },
+  {
+    "tag": "merycism",
+    "popularity": 7832
+  },
+  {
+    "tag": "checkrow",
+    "popularity": 7824
+  },
+  {
+    "tag": "scry",
+    "popularity": 7816
+  },
+  {
+    "tag": "obvolve",
+    "popularity": 7808
+  },
+  {
+    "tag": "orchard",
+    "popularity": 7800
+  },
+  {
+    "tag": "isomerize",
+    "popularity": 7792
+  },
+  {
+    "tag": "competitrix",
+    "popularity": 7784
+  },
+  {
+    "tag": "unbannered",
+    "popularity": 7776
+  },
+  {
+    "tag": "undoctrined",
+    "popularity": 7768
+  },
+  {
+    "tag": "theologian",
+    "popularity": 7760
+  },
+  {
+    "tag": "nebby",
+    "popularity": 7752
+  },
+  {
+    "tag": "Cardiazol",
+    "popularity": 7745
+  },
+  {
+    "tag": "phagedenic",
+    "popularity": 7737
+  },
+  {
+    "tag": "nostalgic",
+    "popularity": 7729
+  },
+  {
+    "tag": "orthodoxy",
+    "popularity": 7721
+  },
+  {
+    "tag": "oversanguine",
+    "popularity": 7713
+  },
+  {
+    "tag": "lish",
+    "popularity": 7705
+  },
+  {
+    "tag": "ketogenic",
+    "popularity": 7698
+  },
+  {
+    "tag": "syndicalize",
+    "popularity": 7690
+  },
+  {
+    "tag": "leeftail",
+    "popularity": 7682
+  },
+  {
+    "tag": "bulbomedullary",
+    "popularity": 7674
+  },
+  {
+    "tag": "reletter",
+    "popularity": 7667
+  },
+  {
+    "tag": "bitterly",
+    "popularity": 7659
+  },
+  {
+    "tag": "participatory",
+    "popularity": 7651
+  },
+  {
+    "tag": "baldberry",
+    "popularity": 7643
+  },
+  {
+    "tag": "prowaterpower",
+    "popularity": 7636
+  },
+  {
+    "tag": "lexicographical",
+    "popularity": 7628
+  },
+  {
+    "tag": "Anisodactyli",
+    "popularity": 7620
+  },
+  {
+    "tag": "amphipodous",
+    "popularity": 7613
+  },
+  {
+    "tag": "triglandular",
+    "popularity": 7605
+  },
+  {
+    "tag": "xanthopsin",
+    "popularity": 7597
+  },
+  {
+    "tag": "indefinitude",
+    "popularity": 7590
+  },
+  {
+    "tag": "bookworm",
+    "popularity": 7582
+  },
+  {
+    "tag": "suffocative",
+    "popularity": 7574
+  },
+  {
+    "tag": "uncongested tyrant",
+    "popularity": 7567
+  },
+  {
+    "tag": "alow harmoniously Pamir",
+    "popularity": 7559
+  },
+  {
+    "tag": "monander",
+    "popularity": 7552
+  },
+  {
+    "tag": "bagatelle",
+    "popularity": 7544
+  },
+  {
+    "tag": "membranology",
+    "popularity": 7537
+  },
+  {
+    "tag": "parturifacient",
+    "popularity": 7529
+  },
+  {
+    "tag": "excitovascular",
+    "popularity": 7522
+  },
+  {
+    "tag": "homopolar",
+    "popularity": 7514
+  },
+  {
+    "tag": "phobiac",
+    "popularity": 7507
+  },
+  {
+    "tag": "clype",
+    "popularity": 7499
+  },
+  {
+    "tag": "unsubversive",
+    "popularity": 7492
+  },
+  {
+    "tag": "bostrychoidal scorpionwort",
+    "popularity": 7484
+  },
+  {
+    "tag": "biliteralism",
+    "popularity": 7477
+  },
+  {
+    "tag": "dentatocostate",
+    "popularity": 7469
+  },
+  {
+    "tag": "Pici",
+    "popularity": 7462
+  },
+  {
+    "tag": "sideritic",
+    "popularity": 7454
+  },
+  {
+    "tag": "syntaxis",
+    "popularity": 7447
+  },
+  {
+    "tag": "ingest",
+    "popularity": 7440
+  },
+  {
+    "tag": "rigmarolish",
+    "popularity": 7432
+  },
+  {
+    "tag": "ocreaceous",
+    "popularity": 7425
+  },
+  {
+    "tag": "hyperbrachyskelic",
+    "popularity": 7418
+  },
+  {
+    "tag": "basophobia",
+    "popularity": 7410
+  },
+  {
+    "tag": "substantialness",
+    "popularity": 7403
+  },
+  {
+    "tag": "agglutinoid",
+    "popularity": 7396
+  },
+  {
+    "tag": "longleaf",
+    "popularity": 7388
+  },
+  {
+    "tag": "electroengraving",
+    "popularity": 7381
+  },
+  {
+    "tag": "laparoenterotomy",
+    "popularity": 7374
+  },
+  {
+    "tag": "oxalylurea",
+    "popularity": 7366
+  },
+  {
+    "tag": "unattaintedly",
+    "popularity": 7359
+  },
+  {
+    "tag": "pennystone",
+    "popularity": 7352
+  },
+  {
+    "tag": "Plumbaginaceae",
+    "popularity": 7345
+  },
+  {
+    "tag": "horntip",
+    "popularity": 7337
+  },
+  {
+    "tag": "begrudge",
+    "popularity": 7330
+  },
+  {
+    "tag": "bechignoned",
+    "popularity": 7323
+  },
+  {
+    "tag": "hologonidium",
+    "popularity": 7316
+  },
+  {
+    "tag": "Pulian",
+    "popularity": 7309
+  },
+  {
+    "tag": "gratulation",
+    "popularity": 7301
+  },
+  {
+    "tag": "Sebright",
+    "popularity": 7294
+  },
+  {
+    "tag": "coinstantaneous emotionally",
+    "popularity": 7287
+  },
+  {
+    "tag": "thoracostracan",
+    "popularity": 7280
+  },
+  {
+    "tag": "saurodont",
+    "popularity": 7273
+  },
+  {
+    "tag": "coseat",
+    "popularity": 7266
+  },
+  {
+    "tag": "irascibility",
+    "popularity": 7259
+  },
+  {
+    "tag": "occlude",
+    "popularity": 7251
+  },
+  {
+    "tag": "metallurgist",
+    "popularity": 7244
+  },
+  {
+    "tag": "extraviolet",
+    "popularity": 7237
+  },
+  {
+    "tag": "clinic",
+    "popularity": 7230
+  },
+  {
+    "tag": "skater",
+    "popularity": 7223
+  },
+  {
+    "tag": "linguistic",
+    "popularity": 7216
+  },
+  {
+    "tag": "attacheship",
+    "popularity": 7209
+  },
+  {
+    "tag": "Rachianectes",
+    "popularity": 7202
+  },
+  {
+    "tag": "foliolose",
+    "popularity": 7195
+  },
+  {
+    "tag": "claudetite",
+    "popularity": 7188
+  },
+  {
+    "tag": "aphidian scratching",
+    "popularity": 7181
+  },
+  {
+    "tag": "Carida",
+    "popularity": 7174
+  },
+  {
+    "tag": "tiepin polymicroscope",
+    "popularity": 7167
+  },
+  {
+    "tag": "telpherage",
+    "popularity": 7160
+  },
+  {
+    "tag": "meek",
+    "popularity": 7153
+  },
+  {
+    "tag": "swiftness",
+    "popularity": 7146
+  },
+  {
+    "tag": "gentes",
+    "popularity": 7139
+  },
+  {
+    "tag": "uncommemorated",
+    "popularity": 7132
+  },
+  {
+    "tag": "Lazarus",
+    "popularity": 7125
+  },
+  {
+    "tag": "redivive",
+    "popularity": 7119
+  },
+  {
+    "tag": "nonfebrile",
+    "popularity": 7112
+  },
+  {
+    "tag": "nymphet",
+    "popularity": 7105
+  },
+  {
+    "tag": "areologically",
+    "popularity": 7098
+  },
+  {
+    "tag": "undonkey",
+    "popularity": 7091
+  },
+  {
+    "tag": "projecting",
+    "popularity": 7084
+  },
+  {
+    "tag": "pinnigrade",
+    "popularity": 7077
+  },
+  {
+    "tag": "butylation",
+    "popularity": 7071
+  },
+  {
+    "tag": "philologistic lenticle",
+    "popularity": 7064
+  },
+  {
+    "tag": "nooky",
+    "popularity": 7057
+  },
+  {
+    "tag": "incestuousness",
+    "popularity": 7050
+  },
+  {
+    "tag": "palingenetically",
+    "popularity": 7043
+  },
+  {
+    "tag": "mitochondria",
+    "popularity": 7037
+  },
+  {
+    "tag": "truthify",
+    "popularity": 7030
+  },
+  {
+    "tag": "titanyl",
+    "popularity": 7023
+  },
+  {
+    "tag": "bestride",
+    "popularity": 7016
+  },
+  {
+    "tag": "chende",
+    "popularity": 7010
+  },
+  {
+    "tag": "Chaucerian monophote",
+    "popularity": 7003
+  },
+  {
+    "tag": "cutback",
+    "popularity": 6996
+  },
+  {
+    "tag": "unpatiently",
+    "popularity": 6989
+  },
+  {
+    "tag": "subvitreous",
+    "popularity": 6983
+  },
+  {
+    "tag": "organizable",
+    "popularity": 6976
+  },
+  {
+    "tag": "anniverse uncomprehensible",
+    "popularity": 6969
+  },
+  {
+    "tag": "hyalescence",
+    "popularity": 6963
+  },
+  {
+    "tag": "amniochorial",
+    "popularity": 6956
+  },
+  {
+    "tag": "Corybantian",
+    "popularity": 6949
+  },
+  {
+    "tag": "genocide Scaphitidae",
+    "popularity": 6943
+  },
+  {
+    "tag": "accordionist",
+    "popularity": 6936
+  },
+  {
+    "tag": "becheck",
+    "popularity": 6930
+  },
+  {
+    "tag": "overproduce",
+    "popularity": 6923
+  },
+  {
+    "tag": "unmaniac frijolillo",
+    "popularity": 6916
+  },
+  {
+    "tag": "multisulcated",
+    "popularity": 6910
+  },
+  {
+    "tag": "wennebergite",
+    "popularity": 6903
+  },
+  {
+    "tag": "tautousious mowth",
+    "popularity": 6897
+  },
+  {
+    "tag": "marigold",
+    "popularity": 6890
+  },
+  {
+    "tag": "affray",
+    "popularity": 6884
+  },
+  {
+    "tag": "nonidolatrous",
+    "popularity": 6877
+  },
+  {
+    "tag": "aphrasia",
+    "popularity": 6871
+  },
+  {
+    "tag": "muddlingly",
+    "popularity": 6864
+  },
+  {
+    "tag": "clear",
+    "popularity": 6858
+  },
+  {
+    "tag": "Clitoria",
+    "popularity": 6851
+  },
+  {
+    "tag": "apportionment underwaist",
+    "popularity": 6845
+  },
+  {
+    "tag": "kodakist",
+    "popularity": 6838
+  },
+  {
+    "tag": "Momotidae",
+    "popularity": 6832
+  },
+  {
+    "tag": "cryptovalency",
+    "popularity": 6825
+  },
+  {
+    "tag": "floe",
+    "popularity": 6819
+  },
+  {
+    "tag": "aphagia",
+    "popularity": 6812
+  },
+  {
+    "tag": "brontograph",
+    "popularity": 6806
+  },
+  {
+    "tag": "tubulous",
+    "popularity": 6799
+  },
+  {
+    "tag": "unhorse",
+    "popularity": 6793
+  },
+  {
+    "tag": "chlordane",
+    "popularity": 6787
+  },
+  {
+    "tag": "colloquy brochan",
+    "popularity": 6780
+  },
+  {
+    "tag": "sloosh",
+    "popularity": 6774
+  },
+  {
+    "tag": "battered",
+    "popularity": 6767
+  },
+  {
+    "tag": "monocularity pluriguttulate",
+    "popularity": 6761
+  },
+  {
+    "tag": "chiastoneury",
+    "popularity": 6755
+  },
+  {
+    "tag": "Sanguinaria",
+    "popularity": 6748
+  },
+  {
+    "tag": "confessionary",
+    "popularity": 6742
+  },
+  {
+    "tag": "enzymic",
+    "popularity": 6736
+  },
+  {
+    "tag": "cord",
+    "popularity": 6729
+  },
+  {
+    "tag": "oviducal",
+    "popularity": 6723
+  },
+  {
+    "tag": "crozzle outsea",
+    "popularity": 6717
+  },
+  {
+    "tag": "balladical",
+    "popularity": 6710
+  },
+  {
+    "tag": "uncollectibleness",
+    "popularity": 6704
+  },
+  {
+    "tag": "predorsal",
+    "popularity": 6698
+  },
+  {
+    "tag": "reauthenticate",
+    "popularity": 6692
+  },
+  {
+    "tag": "ravissant",
+    "popularity": 6685
+  },
+  {
+    "tag": "advantageousness",
+    "popularity": 6679
+  },
+  {
+    "tag": "rung",
+    "popularity": 6673
+  },
+  {
+    "tag": "duncedom",
+    "popularity": 6667
+  },
+  {
+    "tag": "hematolite",
+    "popularity": 6660
+  },
+  {
+    "tag": "thisness",
+    "popularity": 6654
+  },
+  {
+    "tag": "mapau",
+    "popularity": 6648
+  },
+  {
+    "tag": "Hecatic",
+    "popularity": 6642
+  },
+  {
+    "tag": "meningoencephalocele",
+    "popularity": 6636
+  },
+  {
+    "tag": "confection sorra",
+    "popularity": 6630
+  },
+  {
+    "tag": "unsedate",
+    "popularity": 6623
+  },
+  {
+    "tag": "meningocerebritis",
+    "popularity": 6617
+  },
+  {
+    "tag": "biopsychological",
+    "popularity": 6611
+  },
+  {
+    "tag": "clavicithern",
+    "popularity": 6605
+  },
+  {
+    "tag": "resun",
+    "popularity": 6599
+  },
+  {
+    "tag": "bayamo",
+    "popularity": 6593
+  },
+  {
+    "tag": "seeableness",
+    "popularity": 6587
+  },
+  {
+    "tag": "hypsidolichocephalism",
+    "popularity": 6581
+  },
+  {
+    "tag": "salivous",
+    "popularity": 6574
+  },
+  {
+    "tag": "neumatize",
+    "popularity": 6568
+  },
+  {
+    "tag": "stree",
+    "popularity": 6562
+  },
+  {
+    "tag": "markshot",
+    "popularity": 6556
+  },
+  {
+    "tag": "phraseologically",
+    "popularity": 6550
+  },
+  {
+    "tag": "yealing",
+    "popularity": 6544
+  },
+  {
+    "tag": "puggy",
+    "popularity": 6538
+  },
+  {
+    "tag": "sexadecimal",
+    "popularity": 6532
+  },
+  {
+    "tag": "unofficerlike",
+    "popularity": 6526
+  },
+  {
+    "tag": "curiosa",
+    "popularity": 6520
+  },
+  {
+    "tag": "pedomotor",
+    "popularity": 6514
+  },
+  {
+    "tag": "astrally",
+    "popularity": 6508
+  },
+  {
+    "tag": "prosomatic",
+    "popularity": 6502
+  },
+  {
+    "tag": "bulletheaded",
+    "popularity": 6496
+  },
+  {
+    "tag": "fortuned",
+    "popularity": 6490
+  },
+  {
+    "tag": "pixy",
+    "popularity": 6484
+  },
+  {
+    "tag": "protectrix",
+    "popularity": 6478
+  },
+  {
+    "tag": "arthritical",
+    "popularity": 6472
+  },
+  {
+    "tag": "coction",
+    "popularity": 6466
+  },
+  {
+    "tag": "Anthropos",
+    "popularity": 6460
+  },
+  {
+    "tag": "runer",
+    "popularity": 6454
+  },
+  {
+    "tag": "prenotify",
+    "popularity": 6449
+  },
+  {
+    "tag": "microspheric gastroparalysis",
+    "popularity": 6443
+  },
+  {
+    "tag": "Jovicentrical",
+    "popularity": 6437
+  },
+  {
+    "tag": "ceratopsid",
+    "popularity": 6431
+  },
+  {
+    "tag": "Theodoric",
+    "popularity": 6425
+  },
+  {
+    "tag": "Pactolus",
+    "popularity": 6419
+  },
+  {
+    "tag": "spawning",
+    "popularity": 6413
+  },
+  {
+    "tag": "nonconfidential",
+    "popularity": 6407
+  },
+  {
+    "tag": "halotrichite infumate",
+    "popularity": 6402
+  },
+  {
+    "tag": "undiscriminatingly",
+    "popularity": 6396
+  },
+  {
+    "tag": "unexasperated",
+    "popularity": 6390
+  },
+  {
+    "tag": "isoeugenol",
+    "popularity": 6384
+  },
+  {
+    "tag": "pressboard",
+    "popularity": 6378
+  },
+  {
+    "tag": "unshrew",
+    "popularity": 6372
+  },
+  {
+    "tag": "huffingly",
+    "popularity": 6367
+  },
+  {
+    "tag": "wagaun",
+    "popularity": 6361
+  },
+  {
+    "tag": "squirt Philistine",
+    "popularity": 6355
+  },
+  {
+    "tag": "kryptic",
+    "popularity": 6349
+  },
+  {
+    "tag": "paraform",
+    "popularity": 6344
+  },
+  {
+    "tag": "preverify",
+    "popularity": 6338
+  },
+  {
+    "tag": "dalar",
+    "popularity": 6332
+  },
+  {
+    "tag": "interdictor appraisingly",
+    "popularity": 6326
+  },
+  {
+    "tag": "chipped",
+    "popularity": 6321
+  },
+  {
+    "tag": "Pteropoda",
+    "popularity": 6315
+  },
+  {
+    "tag": "Bohairic",
+    "popularity": 6309
+  },
+  {
+    "tag": "felting",
+    "popularity": 6303
+  },
+  {
+    "tag": "compurgatorial",
+    "popularity": 6298
+  },
+  {
+    "tag": "unclead",
+    "popularity": 6292
+  },
+  {
+    "tag": "stockish",
+    "popularity": 6286
+  },
+  {
+    "tag": "mulligatawny",
+    "popularity": 6281
+  },
+  {
+    "tag": "Monotheletism",
+    "popularity": 6275
+  },
+  {
+    "tag": "lutanist",
+    "popularity": 6269
+  },
+  {
+    "tag": "gluttonize",
+    "popularity": 6264
+  },
+  {
+    "tag": "hackneyed",
+    "popularity": 6258
+  },
+  {
+    "tag": "yield",
+    "popularity": 6253
+  },
+  {
+    "tag": "sulphonamido",
+    "popularity": 6247
+  },
+  {
+    "tag": "granulative",
+    "popularity": 6241
+  },
+  {
+    "tag": "swingy",
+    "popularity": 6236
+  },
+  {
+    "tag": "Desmidiales",
+    "popularity": 6230
+  },
+  {
+    "tag": "tootlish",
+    "popularity": 6224
+  },
+  {
+    "tag": "unsatisfiedly",
+    "popularity": 6219
+  },
+  {
+    "tag": "burucha",
+    "popularity": 6213
+  },
+  {
+    "tag": "premeditatingly",
+    "popularity": 6208
+  },
+  {
+    "tag": "cowrie",
+    "popularity": 6202
+  },
+  {
+    "tag": "pleurolysis",
+    "popularity": 6197
+  },
+  {
+    "tag": "nationalist",
+    "popularity": 6191
+  },
+  {
+    "tag": "Pholadacea",
+    "popularity": 6186
+  },
+  {
+    "tag": "anakrousis",
+    "popularity": 6180
+  },
+  {
+    "tag": "proctorial",
+    "popularity": 6175
+  },
+  {
+    "tag": "cavillation",
+    "popularity": 6169
+  },
+  {
+    "tag": "cervicobregmatic",
+    "popularity": 6163
+  },
+  {
+    "tag": "interspecific",
+    "popularity": 6158
+  },
+  {
+    "tag": "Teutonity",
+    "popularity": 6152
+  },
+  {
+    "tag": "snakeholing",
+    "popularity": 6147
+  },
+  {
+    "tag": "balcony",
+    "popularity": 6142
+  },
+  {
+    "tag": "latchless",
+    "popularity": 6136
+  },
+  {
+    "tag": "Mithraea",
+    "popularity": 6131
+  },
+  {
+    "tag": "pseudepigraph",
+    "popularity": 6125
+  },
+  {
+    "tag": "flosser",
+    "popularity": 6120
+  },
+  {
+    "tag": "kotyle",
+    "popularity": 6114
+  },
+  {
+    "tag": "outdo",
+    "popularity": 6109
+  },
+  {
+    "tag": "interclerical",
+    "popularity": 6103
+  },
+  {
+    "tag": "aurar",
+    "popularity": 6098
+  },
+  {
+    "tag": "apophyseal",
+    "popularity": 6093
+  },
+  {
+    "tag": "Miro",
+    "popularity": 6087
+  },
+  {
+    "tag": "Priscillian",
+    "popularity": 6082
+  },
+  {
+    "tag": "alluvia",
+    "popularity": 6076
+  },
+  {
+    "tag": "exordize",
+    "popularity": 6071
+  },
+  {
+    "tag": "breakage",
+    "popularity": 6066
+  },
+  {
+    "tag": "unclosable",
+    "popularity": 6060
+  },
+  {
+    "tag": "monocondylous",
+    "popularity": 6055
+  },
+  {
+    "tag": "dyarchy",
+    "popularity": 6050
+  },
+  {
+    "tag": "subchelate",
+    "popularity": 6044
+  },
+  {
+    "tag": "hearsay",
+    "popularity": 6039
+  },
+  {
+    "tag": "prestigiously",
+    "popularity": 6034
+  },
+  {
+    "tag": "unimuscular",
+    "popularity": 6028
+  },
+  {
+    "tag": "lingwort",
+    "popularity": 6023
+  },
+  {
+    "tag": "jealous",
+    "popularity": 6018
+  },
+  {
+    "tag": "artilleryman",
+    "popularity": 6012
+  },
+  {
+    "tag": "phantasmagorially",
+    "popularity": 6007
+  },
+  {
+    "tag": "stagnum",
+    "popularity": 6002
+  },
+  {
+    "tag": "organotropism shatteringly",
+    "popularity": 5997
+  },
+  {
+    "tag": "Mytilus Hebraist",
+    "popularity": 5991
+  },
+  {
+    "tag": "returf",
+    "popularity": 5986
+  },
+  {
+    "tag": "townfolk",
+    "popularity": 5981
+  },
+  {
+    "tag": "propitiative",
+    "popularity": 5976
+  },
+  {
+    "tag": "Anita unsullied",
+    "popularity": 5970
+  },
+  {
+    "tag": "bandoleered",
+    "popularity": 5965
+  },
+  {
+    "tag": "cubby",
+    "popularity": 5960
+  },
+  {
+    "tag": "Hexanchus",
+    "popularity": 5955
+  },
+  {
+    "tag": "circuminsular",
+    "popularity": 5949
+  },
+  {
+    "tag": "chamberletted eumycete",
+    "popularity": 5944
+  },
+  {
+    "tag": "secure",
+    "popularity": 5939
+  },
+  {
+    "tag": "Edwardean",
+    "popularity": 5934
+  },
+  {
+    "tag": "strenth",
+    "popularity": 5929
+  },
+  {
+    "tag": "exhaustless",
+    "popularity": 5923
+  },
+  {
+    "tag": "electioneerer",
+    "popularity": 5918
+  },
+  {
+    "tag": "estoile",
+    "popularity": 5913
+  },
+  {
+    "tag": "redden",
+    "popularity": 5908
+  },
+  {
+    "tag": "solicitee",
+    "popularity": 5903
+  },
+  {
+    "tag": "nonpatented",
+    "popularity": 5898
+  },
+  {
+    "tag": "lemming",
+    "popularity": 5893
+  },
+  {
+    "tag": "marled subalate",
+    "popularity": 5887
+  },
+  {
+    "tag": "premial horizonward",
+    "popularity": 5882
+  },
+  {
+    "tag": "nonrefueling",
+    "popularity": 5877
+  },
+  {
+    "tag": "rupturewort",
+    "popularity": 5872
+  },
+  {
+    "tag": "unfed",
+    "popularity": 5867
+  },
+  {
+    "tag": "empanelment",
+    "popularity": 5862
+  },
+  {
+    "tag": "isoosmosis",
+    "popularity": 5857
+  },
+  {
+    "tag": "jipijapa",
+    "popularity": 5852
+  },
+  {
+    "tag": "Fiji",
+    "popularity": 5847
+  },
+  {
+    "tag": "interferant",
+    "popularity": 5842
+  },
+  {
+    "tag": "reconstitution",
+    "popularity": 5837
+  },
+  {
+    "tag": "dockyardman",
+    "popularity": 5832
+  },
+  {
+    "tag": "dolichopodous",
+    "popularity": 5826
+  },
+  {
+    "tag": "whiteworm",
+    "popularity": 5821
+  },
+  {
+    "tag": "atheistically",
+    "popularity": 5816
+  },
+  {
+    "tag": "nonconcern",
+    "popularity": 5811
+  },
+  {
+    "tag": "scarabaeidoid",
+    "popularity": 5806
+  },
+  {
+    "tag": "triumviri",
+    "popularity": 5801
+  },
+  {
+    "tag": "rakit",
+    "popularity": 5796
+  },
+  {
+    "tag": "leecheater",
+    "popularity": 5791
+  },
+  {
+    "tag": "Arthrostraca",
+    "popularity": 5786
+  },
+  {
+    "tag": "upknit",
+    "popularity": 5781
+  },
+  {
+    "tag": "tymbalon",
+    "popularity": 5776
+  },
+  {
+    "tag": "inventurous",
+    "popularity": 5771
+  },
+  {
+    "tag": "perradiate",
+    "popularity": 5766
+  },
+  {
+    "tag": "seer",
+    "popularity": 5762
+  },
+  {
+    "tag": "Auricularia",
+    "popularity": 5757
+  },
+  {
+    "tag": "wettish exclusivity",
+    "popularity": 5752
+  },
+  {
+    "tag": "arteriosympathectomy",
+    "popularity": 5747
+  },
+  {
+    "tag": "tunlike",
+    "popularity": 5742
+  },
+  {
+    "tag": "cephalocercal",
+    "popularity": 5737
+  },
+  {
+    "tag": "meaninglessness",
+    "popularity": 5732
+  },
+  {
+    "tag": "fountful",
+    "popularity": 5727
+  },
+  {
+    "tag": "appraisement",
+    "popularity": 5722
+  },
+  {
+    "tag": "geniculated",
+    "popularity": 5717
+  },
+  {
+    "tag": "rotator",
+    "popularity": 5712
+  },
+  {
+    "tag": "foremarch biography",
+    "popularity": 5707
+  },
+  {
+    "tag": "arid",
+    "popularity": 5703
+  },
+  {
+    "tag": "inapprehensible",
+    "popularity": 5698
+  },
+  {
+    "tag": "chlorosulphonic",
+    "popularity": 5693
+  },
+  {
+    "tag": "braguette",
+    "popularity": 5688
+  },
+  {
+    "tag": "panophthalmitis",
+    "popularity": 5683
+  },
+  {
+    "tag": "pro objurgatorily",
+    "popularity": 5678
+  },
+  {
+    "tag": "zooplasty",
+    "popularity": 5673
+  },
+  {
+    "tag": "Terebratulidae",
+    "popularity": 5669
+  },
+  {
+    "tag": "Mahran",
+    "popularity": 5664
+  },
+  {
+    "tag": "anthologize merocele",
+    "popularity": 5659
+  },
+  {
+    "tag": "firecracker chiropractic",
+    "popularity": 5654
+  },
+  {
+    "tag": "tenorist",
+    "popularity": 5649
+  },
+  {
+    "tag": "amphitene",
+    "popularity": 5645
+  },
+  {
+    "tag": "silverbush toadstone",
+    "popularity": 5640
+  },
+  {
+    "tag": "entozoological",
+    "popularity": 5635
+  },
+  {
+    "tag": "trustlessness",
+    "popularity": 5630
+  },
+  {
+    "tag": "reassay",
+    "popularity": 5625
+  },
+  {
+    "tag": "chrysalides",
+    "popularity": 5621
+  },
+  {
+    "tag": "truncation",
+    "popularity": 5616
+  },
+  {
+    "tag": "unwavered mausoleal",
+    "popularity": 5611
+  },
+  {
+    "tag": "unserrated",
+    "popularity": 5606
+  },
+  {
+    "tag": "frampler",
+    "popularity": 5602
+  },
+  {
+    "tag": "celestial",
+    "popularity": 5597
+  },
+  {
+    "tag": "depreter",
+    "popularity": 5592
+  },
+  {
+    "tag": "retaliate",
+    "popularity": 5588
+  },
+  {
+    "tag": "decempunctate",
+    "popularity": 5583
+  },
+  {
+    "tag": "submitter",
+    "popularity": 5578
+  },
+  {
+    "tag": "phenothiazine",
+    "popularity": 5573
+  },
+  {
+    "tag": "hobbledehoyish",
+    "popularity": 5569
+  },
+  {
+    "tag": "erraticness",
+    "popularity": 5564
+  },
+  {
+    "tag": "ovariodysneuria",
+    "popularity": 5559
+  },
+  {
+    "tag": "puja",
+    "popularity": 5555
+  },
+  {
+    "tag": "cesspool",
+    "popularity": 5550
+  },
+  {
+    "tag": "sonation",
+    "popularity": 5545
+  },
+  {
+    "tag": "moggan",
+    "popularity": 5541
+  },
+  {
+    "tag": "overjutting",
+    "popularity": 5536
+  },
+  {
+    "tag": "cohobate",
+    "popularity": 5531
+  },
+  {
+    "tag": "Distoma",
+    "popularity": 5527
+  },
+  {
+    "tag": "Plectognathi",
+    "popularity": 5522
+  },
+  {
+    "tag": "dumple caliphate",
+    "popularity": 5517
+  },
+  {
+    "tag": "shiko",
+    "popularity": 5513
+  },
+  {
+    "tag": "downness",
+    "popularity": 5508
+  },
+  {
+    "tag": "whippletree",
+    "popularity": 5504
+  },
+  {
+    "tag": "nymphaeum",
+    "popularity": 5499
+  },
+  {
+    "tag": "there trest",
+    "popularity": 5494
+  },
+  {
+    "tag": "psychrometer",
+    "popularity": 5490
+  },
+  {
+    "tag": "pyelograph",
+    "popularity": 5485
+  },
+  {
+    "tag": "unsalvable",
+    "popularity": 5481
+  },
+  {
+    "tag": "bescreen",
+    "popularity": 5476
+  },
+  {
+    "tag": "cushy",
+    "popularity": 5471
+  },
+  {
+    "tag": "plicatolobate",
+    "popularity": 5467
+  },
+  {
+    "tag": "lakie",
+    "popularity": 5462
+  },
+  {
+    "tag": "anthropodeoxycholic",
+    "popularity": 5458
+  },
+  {
+    "tag": "resatisfaction",
+    "popularity": 5453
+  },
+  {
+    "tag": "unravelment unaccidental",
+    "popularity": 5449
+  },
+  {
+    "tag": "telewriter monogeneous",
+    "popularity": 5444
+  },
+  {
+    "tag": "unsabred",
+    "popularity": 5440
+  },
+  {
+    "tag": "startlingly",
+    "popularity": 5435
+  },
+  {
+    "tag": "Aralia",
+    "popularity": 5431
+  },
+  {
+    "tag": "alamonti",
+    "popularity": 5426
+  },
+  {
+    "tag": "Franklinization",
+    "popularity": 5422
+  },
+  {
+    "tag": "parliament",
+    "popularity": 5417
+  },
+  {
+    "tag": "schoolkeeper",
+    "popularity": 5413
+  },
+  {
+    "tag": "nonsociety",
+    "popularity": 5408
+  },
+  {
+    "tag": "parenthetic",
+    "popularity": 5404
+  },
+  {
+    "tag": "stog",
+    "popularity": 5399
+  },
+  {
+    "tag": "Pristipomidae",
+    "popularity": 5395
+  },
+  {
+    "tag": "exocarp",
+    "popularity": 5390
+  },
+  {
+    "tag": "monaxonial",
+    "popularity": 5386
+  },
+  {
+    "tag": "tramroad",
+    "popularity": 5381
+  },
+  {
+    "tag": "hookah",
+    "popularity": 5377
+  },
+  {
+    "tag": "saccharonic",
+    "popularity": 5372
+  },
+  {
+    "tag": "perimetrium",
+    "popularity": 5368
+  },
+  {
+    "tag": "libelluloid",
+    "popularity": 5364
+  },
+  {
+    "tag": "overrunningly",
+    "popularity": 5359
+  },
+  {
+    "tag": "untwister",
+    "popularity": 5355
+  },
+  {
+    "tag": "ninnyhammer",
+    "popularity": 5350
+  },
+  {
+    "tag": "metranate",
+    "popularity": 5346
+  },
+  {
+    "tag": "sarcoblast",
+    "popularity": 5341
+  },
+  {
+    "tag": "porkish",
+    "popularity": 5337
+  },
+  {
+    "tag": "chauvinistic",
+    "popularity": 5333
+  },
+  {
+    "tag": "sexagesimal",
+    "popularity": 5328
+  },
+  {
+    "tag": "hematogenic",
+    "popularity": 5324
+  },
+  {
+    "tag": "selfpreservatory",
+    "popularity": 5320
+  },
+  {
+    "tag": "myelauxe",
+    "popularity": 5315
+  },
+  {
+    "tag": "triply",
+    "popularity": 5311
+  },
+  {
+    "tag": "metaphysicous",
+    "popularity": 5306
+  },
+  {
+    "tag": "vitrinoid",
+    "popularity": 5302
+  },
+  {
+    "tag": "glabellae",
+    "popularity": 5298
+  },
+  {
+    "tag": "moonlighter",
+    "popularity": 5293
+  },
+  {
+    "tag": "monotheistically epexegetical",
+    "popularity": 5289
+  },
+  {
+    "tag": "pseudolateral",
+    "popularity": 5285
+  },
+  {
+    "tag": "heptamethylene",
+    "popularity": 5280
+  },
+  {
+    "tag": "salvadora",
+    "popularity": 5276
+  },
+  {
+    "tag": "unjovial diphenylthiourea",
+    "popularity": 5272
+  },
+  {
+    "tag": "thievishness",
+    "popularity": 5268
+  },
+  {
+    "tag": "unridable",
+    "popularity": 5263
+  },
+  {
+    "tag": "underhandedly",
+    "popularity": 5259
+  },
+  {
+    "tag": "fungiform",
+    "popularity": 5255
+  },
+  {
+    "tag": "scruffle",
+    "popularity": 5250
+  },
+  {
+    "tag": "preindisposition",
+    "popularity": 5246
+  },
+  {
+    "tag": "Amadis",
+    "popularity": 5242
+  },
+  {
+    "tag": "Culex",
+    "popularity": 5238
+  },
+  {
+    "tag": "churning",
+    "popularity": 5233
+  },
+  {
+    "tag": "imperite",
+    "popularity": 5229
+  },
+  {
+    "tag": "levorotation",
+    "popularity": 5225
+  },
+  {
+    "tag": "barbate",
+    "popularity": 5221
+  },
+  {
+    "tag": "knotwort",
+    "popularity": 5216
+  },
+  {
+    "tag": "gypsiferous",
+    "popularity": 5212
+  },
+  {
+    "tag": "tourmalinic",
+    "popularity": 5208
+  },
+  {
+    "tag": "helleboric",
+    "popularity": 5204
+  },
+  {
+    "tag": "pneumograph",
+    "popularity": 5199
+  },
+  {
+    "tag": "Peltigeraceae",
+    "popularity": 5195
+  },
+  {
+    "tag": "busine",
+    "popularity": 5191
+  },
+  {
+    "tag": "Ailuridae",
+    "popularity": 5187
+  },
+  {
+    "tag": "azotate",
+    "popularity": 5183
+  },
+  {
+    "tag": "unlikable",
+    "popularity": 5178
+  },
+  {
+    "tag": "sloyd",
+    "popularity": 5174
+  },
+  {
+    "tag": "biblioclasm",
+    "popularity": 5170
+  },
+  {
+    "tag": "Seres",
+    "popularity": 5166
+  },
+  {
+    "tag": "unaccurateness",
+    "popularity": 5162
+  },
+  {
+    "tag": "scrollwise",
+    "popularity": 5157
+  },
+  {
+    "tag": "flandowser",
+    "popularity": 5153
+  },
+  {
+    "tag": "unblackened",
+    "popularity": 5149
+  },
+  {
+    "tag": "schistosternia",
+    "popularity": 5145
+  },
+  {
+    "tag": "fuse",
+    "popularity": 5141
+  },
+  {
+    "tag": "narthecal",
+    "popularity": 5137
+  },
+  {
+    "tag": "Cueva",
+    "popularity": 5133
+  },
+  {
+    "tag": "appositeness",
+    "popularity": 5128
+  },
+  {
+    "tag": "proindustrial",
+    "popularity": 5124
+  },
+  {
+    "tag": "dermatorrhoea",
+    "popularity": 5120
+  },
+  {
+    "tag": "oxyurous tendential",
+    "popularity": 5116
+  },
+  {
+    "tag": "isopurpurin",
+    "popularity": 5112
+  },
+  {
+    "tag": "impose",
+    "popularity": 5108
+  },
+  {
+    "tag": "wordsmanship",
+    "popularity": 5104
+  },
+  {
+    "tag": "saturator",
+    "popularity": 5100
+  },
+  {
+    "tag": "Nordicity",
+    "popularity": 5096
+  },
+  {
+    "tag": "interaccuse",
+    "popularity": 5092
+  },
+  {
+    "tag": "acridinic",
+    "popularity": 5087
+  },
+  {
+    "tag": "scholion",
+    "popularity": 5083
+  },
+  {
+    "tag": "pseudoaconitine",
+    "popularity": 5079
+  },
+  {
+    "tag": "doctorial",
+    "popularity": 5075
+  },
+  {
+    "tag": "Etchimin",
+    "popularity": 5071
+  },
+  {
+    "tag": "oliviform",
+    "popularity": 5067
+  },
+  {
+    "tag": "Pele",
+    "popularity": 5063
+  },
+  {
+    "tag": "Chiromantis Progymnasium",
+    "popularity": 5059
+  },
+  {
+    "tag": "toxosis",
+    "popularity": 5055
+  },
+  {
+    "tag": "spadilla",
+    "popularity": 5051
+  },
+  {
+    "tag": "Actinopterygii",
+    "popularity": 5047
+  },
+  {
+    "tag": "untiring",
+    "popularity": 5043
+  },
+  {
+    "tag": "butyral",
+    "popularity": 5039
+  },
+  {
+    "tag": "Gymnoderinae",
+    "popularity": 5035
+  },
+  {
+    "tag": "testudo",
+    "popularity": 5031
+  },
+  {
+    "tag": "frigorify",
+    "popularity": 5027
+  },
+  {
+    "tag": "aliency",
+    "popularity": 5023
+  },
+  {
+    "tag": "jargon",
+    "popularity": 5019
+  },
+  {
+    "tag": "counterservice",
+    "popularity": 5015
+  },
+  {
+    "tag": "isostrychnine",
+    "popularity": 5011
+  },
+  {
+    "tag": "tellership",
+    "popularity": 5007
+  },
+  {
+    "tag": "miscegenetic",
+    "popularity": 5003
+  },
+  {
+    "tag": "sorcer",
+    "popularity": 4999
+  },
+  {
+    "tag": "tilewright",
+    "popularity": 4995
+  },
+  {
+    "tag": "cyanoplastid",
+    "popularity": 4991
+  },
+  {
+    "tag": "fluxionally",
+    "popularity": 4987
+  },
+  {
+    "tag": "proudhearted",
+    "popularity": 4983
+  },
+  {
+    "tag": "blithely",
+    "popularity": 4979
+  },
+  {
+    "tag": "jestproof",
+    "popularity": 4975
+  },
+  {
+    "tag": "jestwise",
+    "popularity": 4971
+  },
+  {
+    "tag": "nonassimilable",
+    "popularity": 4967
+  },
+  {
+    "tag": "compurgation",
+    "popularity": 4964
+  },
+  {
+    "tag": "unhate",
+    "popularity": 4960
+  },
+  {
+    "tag": "haplodonty",
+    "popularity": 4956
+  },
+  {
+    "tag": "cardholder",
+    "popularity": 4952
+  },
+  {
+    "tag": "rainlight megohmmeter overstout",
+    "popularity": 4948
+  },
+  {
+    "tag": "itchless",
+    "popularity": 4944
+  },
+  {
+    "tag": "begiggle",
+    "popularity": 4940
+  },
+  {
+    "tag": "chromatosphere",
+    "popularity": 4936
+  },
+  {
+    "tag": "typicality",
+    "popularity": 4932
+  },
+  {
+    "tag": "overgrown",
+    "popularity": 4928
+  },
+  {
+    "tag": "envolume",
+    "popularity": 4925
+  },
+  {
+    "tag": "pachycholia",
+    "popularity": 4921
+  },
+  {
+    "tag": "passageable",
+    "popularity": 4917
+  },
+  {
+    "tag": "pathopoiesis",
+    "popularity": 4913
+  },
+  {
+    "tag": "overbreak",
+    "popularity": 4909
+  },
+  {
+    "tag": "satyric",
+    "popularity": 4905
+  },
+  {
+    "tag": "unaudited",
+    "popularity": 4901
+  },
+  {
+    "tag": "whimble",
+    "popularity": 4898
+  },
+  {
+    "tag": "pressureless",
+    "popularity": 4894
+  },
+  {
+    "tag": "Selene",
+    "popularity": 4890
+  },
+  {
+    "tag": "slithery",
+    "popularity": 4886
+  },
+  {
+    "tag": "nondisfigurement",
+    "popularity": 4882
+  },
+  {
+    "tag": "overdelicious",
+    "popularity": 4878
+  },
+  {
+    "tag": "Perca",
+    "popularity": 4875
+  },
+  {
+    "tag": "Palladium",
+    "popularity": 4871
+  },
+  {
+    "tag": "insagacity",
+    "popularity": 4867
+  },
+  {
+    "tag": "peristoma",
+    "popularity": 4863
+  },
+  {
+    "tag": "uncreativeness",
+    "popularity": 4859
+  },
+  {
+    "tag": "incomparability surfboarding",
+    "popularity": 4856
+  },
+  {
+    "tag": "bacillar",
+    "popularity": 4852
+  },
+  {
+    "tag": "ulcerative",
+    "popularity": 4848
+  },
+  {
+    "tag": "stychomythia",
+    "popularity": 4844
+  },
+  {
+    "tag": "sesma somatics nonentry",
+    "popularity": 4840
+  },
+  {
+    "tag": "unsepulchred",
+    "popularity": 4837
+  },
+  {
+    "tag": "cephalanthium",
+    "popularity": 4833
+  },
+  {
+    "tag": "Asiaticization",
+    "popularity": 4829
+  },
+  {
+    "tag": "killeen",
+    "popularity": 4825
+  },
+  {
+    "tag": "Pseudococcus",
+    "popularity": 4822
+  },
+  {
+    "tag": "untractable",
+    "popularity": 4818
+  },
+  {
+    "tag": "apolegamic",
+    "popularity": 4814
+  },
+  {
+    "tag": "hyperpnea",
+    "popularity": 4810
+  },
+  {
+    "tag": "martyrolatry",
+    "popularity": 4807
+  },
+  {
+    "tag": "Sarmatic",
+    "popularity": 4803
+  },
+  {
+    "tag": "nonsurface",
+    "popularity": 4799
+  },
+  {
+    "tag": "adjoined",
+    "popularity": 4796
+  },
+  {
+    "tag": "vasiform",
+    "popularity": 4792
+  },
+  {
+    "tag": "tastelessness",
+    "popularity": 4788
+  },
+  {
+    "tag": "rumbo",
+    "popularity": 4784
+  },
+  {
+    "tag": "subdititious",
+    "popularity": 4781
+  },
+  {
+    "tag": "reparticipation",
+    "popularity": 4777
+  },
+  {
+    "tag": "Yorkshireism",
+    "popularity": 4773
+  },
+  {
+    "tag": "outcrow",
+    "popularity": 4770
+  },
+  {
+    "tag": "casserole",
+    "popularity": 4766
+  },
+  {
+    "tag": "semideltaic",
+    "popularity": 4762
+  },
+  {
+    "tag": "freemason",
+    "popularity": 4759
+  },
+  {
+    "tag": "catkin",
+    "popularity": 4755
+  },
+  {
+    "tag": "conscient",
+    "popularity": 4751
+  },
+  {
+    "tag": "reliably",
+    "popularity": 4748
+  },
+  {
+    "tag": "Telembi",
+    "popularity": 4744
+  },
+  {
+    "tag": "hide",
+    "popularity": 4740
+  },
+  {
+    "tag": "social",
+    "popularity": 4737
+  },
+  {
+    "tag": "ichneutic",
+    "popularity": 4733
+  },
+  {
+    "tag": "polypotome blouse pentagrammatic",
+    "popularity": 4729
+  },
+  {
+    "tag": "airdrome pesthole",
+    "popularity": 4726
+  },
+  {
+    "tag": "unportended",
+    "popularity": 4722
+  },
+  {
+    "tag": "sheerly",
+    "popularity": 4719
+  },
+  {
+    "tag": "acardiac",
+    "popularity": 4715
+  },
+  {
+    "tag": "fetor",
+    "popularity": 4711
+  },
+  {
+    "tag": "storax",
+    "popularity": 4708
+  },
+  {
+    "tag": "syndactylic",
+    "popularity": 4704
+  },
+  {
+    "tag": "otiatrics",
+    "popularity": 4700
+  },
+  {
+    "tag": "range",
+    "popularity": 4697
+  },
+  {
+    "tag": "branchway",
+    "popularity": 4693
+  },
+  {
+    "tag": "beatific",
+    "popularity": 4690
+  },
+  {
+    "tag": "Rugosa",
+    "popularity": 4686
+  },
+  {
+    "tag": "rafty",
+    "popularity": 4682
+  },
+  {
+    "tag": "gapy",
+    "popularity": 4679
+  },
+  {
+    "tag": "heterocercal",
+    "popularity": 4675
+  },
+  {
+    "tag": "actinopterygious",
+    "popularity": 4672
+  },
+  {
+    "tag": "glauconite",
+    "popularity": 4668
+  },
+  {
+    "tag": "limbless priest",
+    "popularity": 4665
+  },
+  {
+    "tag": "chrysene",
+    "popularity": 4661
+  },
+  {
+    "tag": "isentropic",
+    "popularity": 4658
+  },
+  {
+    "tag": "lairdess",
+    "popularity": 4654
+  },
+  {
+    "tag": "butterhead choliambic",
+    "popularity": 4650
+  },
+  {
+    "tag": "hexaseme",
+    "popularity": 4647
+  },
+  {
+    "tag": "treeify",
+    "popularity": 4643
+  },
+  {
+    "tag": "coronetted fructify",
+    "popularity": 4640
+  },
+  {
+    "tag": "admiralty",
+    "popularity": 4636
+  },
+  {
+    "tag": "Flosculariidae",
+    "popularity": 4633
+  },
+  {
+    "tag": "limaceous",
+    "popularity": 4629
+  },
+  {
+    "tag": "subterconscious",
+    "popularity": 4626
+  },
+  {
+    "tag": "stayless",
+    "popularity": 4622
+  },
+  {
+    "tag": "psha",
+    "popularity": 4619
+  },
+  {
+    "tag": "Mediterraneanize",
+    "popularity": 4615
+  },
+  {
+    "tag": "impenetrably",
+    "popularity": 4612
+  },
+  {
+    "tag": "Myrmeleonidae",
+    "popularity": 4608
+  },
+  {
+    "tag": "germander",
+    "popularity": 4605
+  },
+  {
+    "tag": "Buri",
+    "popularity": 4601
+  },
+  {
+    "tag": "papyrotamia",
+    "popularity": 4598
+  },
+  {
+    "tag": "Toxylon",
+    "popularity": 4594
+  },
+  {
+    "tag": "batatilla",
+    "popularity": 4591
+  },
+  {
+    "tag": "fabella assumer",
+    "popularity": 4587
+  },
+  {
+    "tag": "macromethod",
+    "popularity": 4584
+  },
+  {
+    "tag": "Blechnum",
+    "popularity": 4580
+  },
+  {
+    "tag": "pantography",
+    "popularity": 4577
+  },
+  {
+    "tag": "seminovel",
+    "popularity": 4574
+  },
+  {
+    "tag": "disembarrassment",
+    "popularity": 4570
+  },
+  {
+    "tag": "bushmaking",
+    "popularity": 4567
+  },
+  {
+    "tag": "neurosis",
+    "popularity": 4563
+  },
+  {
+    "tag": "Animalia",
+    "popularity": 4560
+  },
+  {
+    "tag": "Bernice",
+    "popularity": 4556
+  },
+  {
+    "tag": "wisen",
+    "popularity": 4553
+  },
+  {
+    "tag": "subhymenium",
+    "popularity": 4549
+  },
+  {
+    "tag": "esophagomycosis",
+    "popularity": 4546
+  },
+  {
+    "tag": "wireworks",
+    "popularity": 4543
+  },
+  {
+    "tag": "Sabellidae",
+    "popularity": 4539
+  },
+  {
+    "tag": "fustianish",
+    "popularity": 4536
+  },
+  {
+    "tag": "professively",
+    "popularity": 4532
+  },
+  {
+    "tag": "overcorruptly",
+    "popularity": 4529
+  },
+  {
+    "tag": "overcreep",
+    "popularity": 4526
+  },
+  {
+    "tag": "Castilloa",
+    "popularity": 4522
+  },
+  {
+    "tag": "forelady Georgie",
+    "popularity": 4519
+  },
+  {
+    "tag": "outsider",
+    "popularity": 4515
+  },
+  {
+    "tag": "Enukki",
+    "popularity": 4512
+  },
+  {
+    "tag": "gypsy",
+    "popularity": 4509
+  },
+  {
+    "tag": "Passamaquoddy",
+    "popularity": 4505
+  },
+  {
+    "tag": "reposit",
+    "popularity": 4502
+  },
+  {
+    "tag": "overtenderness",
+    "popularity": 4499
+  },
+  {
+    "tag": "keratome",
+    "popularity": 4495
+  },
+  {
+    "tag": "interclavicular hypermonosyllable Susanna",
+    "popularity": 4492
+  },
+  {
+    "tag": "mispropose",
+    "popularity": 4489
+  },
+  {
+    "tag": "Membranipora",
+    "popularity": 4485
+  },
+  {
+    "tag": "lampad",
+    "popularity": 4482
+  },
+  {
+    "tag": "header",
+    "popularity": 4479
+  },
+  {
+    "tag": "triseriate",
+    "popularity": 4475
+  },
+  {
+    "tag": "distrainment",
+    "popularity": 4472
+  },
+  {
+    "tag": "staphyloplastic",
+    "popularity": 4469
+  },
+  {
+    "tag": "outscour",
+    "popularity": 4465
+  },
+  {
+    "tag": "tallowmaking",
+    "popularity": 4462
+  },
+  {
+    "tag": "plugger",
+    "popularity": 4459
+  },
+  {
+    "tag": "fashionize",
+    "popularity": 4455
+  },
+  {
+    "tag": "puzzle",
+    "popularity": 4452
+  },
+  {
+    "tag": "imbrue",
+    "popularity": 4449
+  },
+  {
+    "tag": "osteoblast",
+    "popularity": 4445
+  },
+  {
+    "tag": "Hydrocores",
+    "popularity": 4442
+  },
+  {
+    "tag": "Lutra",
+    "popularity": 4439
+  },
+  {
+    "tag": "upridge scarfy",
+    "popularity": 4435
+  },
+  {
+    "tag": "ancon taffle",
+    "popularity": 4432
+  },
+  {
+    "tag": "impest",
+    "popularity": 4429
+  },
+  {
+    "tag": "uncollatedness",
+    "popularity": 4426
+  },
+  {
+    "tag": "hypersensitize",
+    "popularity": 4422
+  },
+  {
+    "tag": "autographically",
+    "popularity": 4419
+  },
+  {
+    "tag": "louther",
+    "popularity": 4416
+  },
+  {
+    "tag": "Ollie",
+    "popularity": 4413
+  },
+  {
+    "tag": "recompensate",
+    "popularity": 4409
+  },
+  {
+    "tag": "Shan",
+    "popularity": 4406
+  },
+  {
+    "tag": "brachycnemic",
+    "popularity": 4403
+  },
+  {
+    "tag": "Carinatae",
+    "popularity": 4399
+  },
+  {
+    "tag": "geotherm",
+    "popularity": 4396
+  },
+  {
+    "tag": "sawback",
+    "popularity": 4393
+  },
+  {
+    "tag": "Novatianist",
+    "popularity": 4390
+  },
+  {
+    "tag": "reapproach",
+    "popularity": 4387
+  },
+  {
+    "tag": "myelopoietic",
+    "popularity": 4383
+  },
+  {
+    "tag": "cyanin",
+    "popularity": 4380
+  },
+  {
+    "tag": "unsmutted",
+    "popularity": 4377
+  },
+  {
+    "tag": "nonpapist",
+    "popularity": 4374
+  },
+  {
+    "tag": "transbaikalian",
+    "popularity": 4370
+  },
+  {
+    "tag": "connately",
+    "popularity": 4367
+  },
+  {
+    "tag": "tenderize iterance",
+    "popularity": 4364
+  },
+  {
+    "tag": "hydrostatical",
+    "popularity": 4361
+  },
+  {
+    "tag": "unflag",
+    "popularity": 4358
+  },
+  {
+    "tag": "translate",
+    "popularity": 4354
+  },
+  {
+    "tag": "Scorzonera",
+    "popularity": 4351
+  },
+  {
+    "tag": "uncomforted",
+    "popularity": 4348
+  },
+  {
+    "tag": "risser varied",
+    "popularity": 4345
+  },
+  {
+    "tag": "plumbate",
+    "popularity": 4342
+  },
+  {
+    "tag": "Usneaceae",
+    "popularity": 4338
+  },
+  {
+    "tag": "fohat",
+    "popularity": 4335
+  },
+  {
+    "tag": "slagging",
+    "popularity": 4332
+  },
+  {
+    "tag": "superserious",
+    "popularity": 4329
+  },
+  {
+    "tag": "theocracy",
+    "popularity": 4326
+  },
+  {
+    "tag": "valonia",
+    "popularity": 4323
+  },
+  {
+    "tag": "Sapindales",
+    "popularity": 4319
+  },
+  {
+    "tag": "palaeozoologist",
+    "popularity": 4316
+  },
+  {
+    "tag": "yalb",
+    "popularity": 4313
+  },
+  {
+    "tag": "unviewed",
+    "popularity": 4310
+  },
+  {
+    "tag": "polyarteritis",
+    "popularity": 4307
+  },
+  {
+    "tag": "vectorial",
+    "popularity": 4304
+  },
+  {
+    "tag": "skimpingly",
+    "popularity": 4301
+  },
+  {
+    "tag": "athort",
+    "popularity": 4297
+  },
+  {
+    "tag": "tribofluorescence",
+    "popularity": 4294
+  },
+  {
+    "tag": "benzonitrol",
+    "popularity": 4291
+  },
+  {
+    "tag": "swiller subobtuse subjacency",
+    "popularity": 4288
+  },
+  {
+    "tag": "uncompassed",
+    "popularity": 4285
+  },
+  {
+    "tag": "cacochymia",
+    "popularity": 4282
+  },
+  {
+    "tag": "commensalist butadiene",
+    "popularity": 4279
+  },
+  {
+    "tag": "culpable",
+    "popularity": 4276
+  },
+  {
+    "tag": "contributive",
+    "popularity": 4273
+  },
+  {
+    "tag": "attemperately",
+    "popularity": 4269
+  },
+  {
+    "tag": "spelt",
+    "popularity": 4266
+  },
+  {
+    "tag": "exoneration",
+    "popularity": 4263
+  },
+  {
+    "tag": "antivivisectionist",
+    "popularity": 4260
+  },
+  {
+    "tag": "granitification",
+    "popularity": 4257
+  },
+  {
+    "tag": "palladize",
+    "popularity": 4254
+  },
+  {
+    "tag": "marksmanship",
+    "popularity": 4251
+  },
+  {
+    "tag": "bullydom",
+    "popularity": 4248
+  },
+  {
+    "tag": "spirality",
+    "popularity": 4245
+  },
+  {
+    "tag": "caliginous",
+    "popularity": 4242
+  },
+  {
+    "tag": "reportedly",
+    "popularity": 4239
+  },
+  {
+    "tag": "polyad",
+    "popularity": 4236
+  },
+  {
+    "tag": "arthroempyesis",
+    "popularity": 4233
+  },
+  {
+    "tag": "semibay facultatively",
+    "popularity": 4229
+  },
+  {
+    "tag": "metastatically",
+    "popularity": 4226
+  },
+  {
+    "tag": "prophetically",
+    "popularity": 4223
+  },
+  {
+    "tag": "Linguatula elapid",
+    "popularity": 4220
+  },
+  {
+    "tag": "pyknatom",
+    "popularity": 4217
+  },
+  {
+    "tag": "centimeter",
+    "popularity": 4214
+  },
+  {
+    "tag": "mensurate",
+    "popularity": 4211
+  },
+  {
+    "tag": "migraine",
+    "popularity": 4208
+  },
+  {
+    "tag": "pentagamist",
+    "popularity": 4205
+  },
+  {
+    "tag": "querken",
+    "popularity": 4202
+  },
+  {
+    "tag": "ambulance",
+    "popularity": 4199
+  },
+  {
+    "tag": "Stokavian",
+    "popularity": 4196
+  },
+  {
+    "tag": "malvasian",
+    "popularity": 4193
+  },
+  {
+    "tag": "uncouthsome",
+    "popularity": 4190
+  },
+  {
+    "tag": "readable",
+    "popularity": 4187
+  },
+  {
+    "tag": "enlodge",
+    "popularity": 4184
+  },
+  {
+    "tag": "plasterwise Appendiculariidae perspectograph",
+    "popularity": 4181
+  },
+  {
+    "tag": "inkweed",
+    "popularity": 4178
+  },
+  {
+    "tag": "streep",
+    "popularity": 4175
+  },
+  {
+    "tag": "diadelphian cultured",
+    "popularity": 4172
+  },
+  {
+    "tag": "hymenopterous",
+    "popularity": 4169
+  },
+  {
+    "tag": "unexorableness",
+    "popularity": 4166
+  },
+  {
+    "tag": "cascaron",
+    "popularity": 4163
+  },
+  {
+    "tag": "undaintiness",
+    "popularity": 4160
+  },
+  {
+    "tag": "Curtana",
+    "popularity": 4157
+  },
+  {
+    "tag": "scurvied",
+    "popularity": 4154
+  },
+  {
+    "tag": "molluscoidal",
+    "popularity": 4151
+  },
+  {
+    "tag": "yurt",
+    "popularity": 4148
+  },
+  {
+    "tag": "deciduitis",
+    "popularity": 4145
+  },
+  {
+    "tag": "creephole",
+    "popularity": 4142
+  },
+  {
+    "tag": "quatrefeuille",
+    "popularity": 4139
+  },
+  {
+    "tag": "bicapitate adenomatome",
+    "popularity": 4136
+  },
+  {
+    "tag": "damassin",
+    "popularity": 4134
+  },
+  {
+    "tag": "planching",
+    "popularity": 4131
+  },
+  {
+    "tag": "dashedly inferential",
+    "popularity": 4128
+  },
+  {
+    "tag": "lobe",
+    "popularity": 4125
+  },
+  {
+    "tag": "Hyrachyus",
+    "popularity": 4122
+  },
+  {
+    "tag": "knab",
+    "popularity": 4119
+  },
+  {
+    "tag": "discohexaster",
+    "popularity": 4116
+  },
+  {
+    "tag": "malign",
+    "popularity": 4113
+  },
+  {
+    "tag": "pedagoguism",
+    "popularity": 4110
+  },
+  {
+    "tag": "shrubbery",
+    "popularity": 4107
+  },
+  {
+    "tag": "undershrub",
+    "popularity": 4104
+  },
+  {
+    "tag": "bureaucrat",
+    "popularity": 4101
+  },
+  {
+    "tag": "pantaleon",
+    "popularity": 4098
+  },
+  {
+    "tag": "mesoventral",
+    "popularity": 4096
+  }];
+  
+var entry = largeTable[1000];
+print(entry.tag, entry.popularity);
+
diff --git a/nashorn/test/script/basic/NASHORN-481.js.EXPECTED b/nashorn/test/script/basic/NASHORN-481.js.EXPECTED
new file mode 100644
index 0000000..436a2b4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-481.js.EXPECTED
@@ -0,0 +1 @@
+pantheonize prevalency 20733
diff --git a/nashorn/test/script/basic/NASHORN-482.js b/nashorn/test/script/basic/NASHORN-482.js
new file mode 100644
index 0000000..76afb59
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-482.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-482 : eval within 'with' does not receive correct 'this'
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    with ( {} ) {
+        return eval('this');
+    }
+}
+
+var obj = {};
+obj.foo = func;
+if (obj.foo() !== obj) {
+    fail("wrong 'this' returned from eval");
+}
diff --git a/nashorn/test/script/basic/NASHORN-484.js b/nashorn/test/script/basic/NASHORN-484.js
new file mode 100644
index 0000000..b1f0a0e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-484.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-484 : the name of an anonymous function is the empty string.
+ *
+ * @test
+ * @run
+ */
+
+var f = function f() {};
+var anon = function() {};
+print("f: '" + f.name + "'");
+print("anon: '" + anon.name + "'");
diff --git a/nashorn/test/script/basic/NASHORN-484.js.EXPECTED b/nashorn/test/script/basic/NASHORN-484.js.EXPECTED
new file mode 100644
index 0000000..5e14d55
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-484.js.EXPECTED
@@ -0,0 +1,2 @@
+f: 'f'
+anon: ''
diff --git a/nashorn/test/script/basic/NASHORN-486.js b/nashorn/test/script/basic/NASHORN-486.js
new file mode 100644
index 0000000..f03f096
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-486.js
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-486 : error reporting is inconsistent
+ *
+ * @test
+ * @run
+ */
+
+var fileName = __FILE__;
+
+try {
+    // save line number and force ReferenceError for 'foo'
+    var lineNumber = __LINE__; print(foo); 
+    fail("#1 should have thrown ReferenceError");
+} catch (e) {
+    if (! (e instanceof ReferenceError)) {
+        fail("#2 ReferenceError expected, got " + e);
+    }
+
+    if (e.lineNumber !== lineNumber) {
+        fail("#3 line number not correct");
+    }
+
+    if (e.fileName !== fileName) {
+        fail("#4 file name not correct");
+    }
+}
+
+try {
+    // try any library function on invalid self
+    // get line number again and force a TypeError
+    lineNumber = __LINE__; RegExp.prototype.exec.call(3);
+    fail("#5 should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#6 TypeError expected, got " + e);
+    }
+
+    if (e.lineNumber !== lineNumber) {
+        fail("#7 line number not correct");
+    }
+
+    if (e.fileName !== fileName) {
+        fail("#8 file name not correct");
+    }
+}
+
+// try explicit exception thrown from script
+try {
+    lineNumber = __LINE__; throw new Error();
+} catch (e) {
+    if (e.lineNumber !== lineNumber) {
+        fail("#9 line number not correct");
+    }
+
+    if (e.fileName !== fileName) {
+        fail("#10 file name not correct");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-487.js b/nashorn/test/script/basic/NASHORN-487.js
new file mode 100644
index 0000000..c568591
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-487.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-487 :  Object.prototype.toString(new TypeError) should be [object Error]
+ *
+ * @test
+ * @run
+ */
+
+function check(errorCons) {
+    if (Object.prototype.toString.call(new errorCons()) !== '[object Error]') {
+        fail("Object.prototype.toString.call(" + errorCons.name + ")");
+    }
+}
+
+check(Error);
+check(EvalError);
+check(RangeError);
+check(ReferenceError);
+check(SyntaxError);
+check(TypeError);
+check(URIError);
diff --git a/nashorn/test/script/basic/NASHORN-488.js b/nashorn/test/script/basic/NASHORN-488.js
new file mode 100644
index 0000000..53bb888
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-488.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-488 : Function.prototype does not have 'prototype' property
+ *
+ * @test
+ * @run
+ */
+
+var desc = Object.getOwnPropertyDescriptor(Function.prototype, "prototype");
+if (desc !== undefined) {
+    fail("Function.prototype has 'prototype'");
+}
+
+Object.defineProperty(Function.prototype, "prototype", {
+    set: undefined, get: function() { return 32; }, 
+    configurable: true
+});
+
+if (Function.prototype.prototype != 32) {
+    fail("Function.prototype.prototype != 32");
+}
+
+if (! (delete Function.prototype.prototype)) {
+    fail("can't delete Function.prototype.prototype");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-49.js b/nashorn/test/script/basic/NASHORN-49.js
new file mode 100644
index 0000000..1b4a68c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-49.js
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-49
+ *
+ * @test
+ * @run
+ */
+
+var x = 17;
+switch(x) {
+case 17:
+    print("17");
+    break;
+}
+
+switch (1) {
+default:
+    print("test");
+    break;
+}
+
+
+switch(1) {
+}
+
+print("done");
+
+var expr = Math.PI;
+switch(expr) {
+case 1:
+    print("one");
+    break;
+case 2:
+    print("two");
+    break;
+case 3:
+    print("three");
+    break;
+}
+
+print("done2");
diff --git a/nashorn/test/script/basic/NASHORN-49.js.EXPECTED b/nashorn/test/script/basic/NASHORN-49.js.EXPECTED
new file mode 100644
index 0000000..92eda71
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-49.js.EXPECTED
@@ -0,0 +1,4 @@
+17
+test
+done
+done2
diff --git a/nashorn/test/script/basic/NASHORN-490.js b/nashorn/test/script/basic/NASHORN-490.js
new file mode 100644
index 0000000..e9bdd93
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-490.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-490 : Inherited index properties is problematic for Array.prototype.pop function
+ *
+ * @test
+ * @run
+ */
+
+Array.prototype[1] = 1;
+var x = [0];
+x.length = 2;
+
+var obj = x.pop();
+if (obj !== 1) {
+  fail('Array.prototype[1] = 1; x=[0]; x.length = 2; x.pop() == 1. Actual: ' + (obj));
+}
+
+delete Array.prototype[1];
+
+Object.prototype[1] = 1;
+var y = [0];
+y.length = 2;
+var obj = y.pop();
+if (obj !== 1) {
+  fail('Object.prototype[1] = 1; y=[0]; y.length = 2; y.pop() == 1. Actual: ' + (obj));
+}
diff --git a/nashorn/test/script/basic/NASHORN-494.js b/nashorn/test/script/basic/NASHORN-494.js
new file mode 100644
index 0000000..18d19c8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-494.js
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-494 :  in strict mode \0 is not allowed as escape sequence
+ *
+ * @test
+ * @run
+ */
+
+'use strict';
+
+function expectNoError(str) {
+    try {
+        eval(str);
+    } catch (e) {
+        fail("failed", e);
+    }
+}
+
+function expectError(str) {
+    try {
+        eval(str);
+        fail("should have thrown SyntaxError for : " + str);
+    } catch (e) {
+        if (! (e instanceof SyntaxError)) {
+            fail("expected SyntaxError, got " + e);
+        }
+    }
+}
+
+expectNoError("var x = '\\0'");
+expectNoError("var x = '\\0xyz'");
+expectError("var x = '\\01'");
+expectError("var x = '\\08'");
+expectError("var x = '\\7'");
+expectError("var x = '\\563'");
diff --git a/nashorn/test/script/basic/NASHORN-497.js b/nashorn/test/script/basic/NASHORN-497.js
new file mode 100644
index 0000000..ad8b4eb
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-497.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-497 :  optional initialization expression of iterable variable in a for-in statement is not parsed
+ *
+ * @test
+ * @run
+ */
+
+for (var x = 3 in {}) {
+}
+
+if (x !== 3) {
+    fail("#1 x !== 3");
+}
+
+for (var y = false in { foo: 33 }) {
+}
+
+if (typeof y != 'string' || y !=  'foo') {
+    fail("y should be 'foo'");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-498.js b/nashorn/test/script/basic/NASHORN-498.js
new file mode 100644
index 0000000..6304788
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-498.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-498 :  'in' inside conditional expression middle term confuses parser when used in for statements
+ *
+ * @test
+ * @run
+ */
+
+// no syntax error expected for the following functions
+function func() {
+    // Parser thinks it is a for-in statement! But 'in' used in 
+    // cond. expression. This is a normal for statement
+    for (var x = a ? b in c : 3;;) {}
+}
+
+function func2() {
+    // for-in statement but init is cond. expression with 'in' 
+    // This is same as "for (var x = (a? b in c : e) in {} )"
+    for (var x = a ? b in c : e in {}) {}
+}
diff --git a/nashorn/test/script/basic/NASHORN-499.js b/nashorn/test/script/basic/NASHORN-499.js
new file mode 100644
index 0000000..bbedb05
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-499.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-499 :  for (3 in {}) crashes nashorn
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval("for (3 in {}) {}");
+    fail("SyntaxError expected with 'for (3 in obj)'");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("expected SyntaxError, got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-50.js b/nashorn/test/script/basic/NASHORN-50.js
new file mode 100644
index 0000000..7292b95
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-50.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-50 : various iteration issues with type widening and null/undefined according to $12.6.4
+ *
+ * @test
+ * @run
+ */
+
+try {
+    for (var y in null)  {
+	y = 2;
+    }
+} catch (e) {
+    print(e);
+}
+
+try {
+    for (var y in undefined) {
+	y = 2;
+    }
+} catch (e) {
+    print(e);
+}
+
+var arr = [1,2,3];
+for (var y in arr) {
+    y = 2;
+}
+for (var y in arr) {
+    y = "apa";
+}
+
+print("finished");
diff --git a/nashorn/test/script/basic/NASHORN-50.js.EXPECTED b/nashorn/test/script/basic/NASHORN-50.js.EXPECTED
new file mode 100644
index 0000000..f656398
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-50.js.EXPECTED
@@ -0,0 +1 @@
+finished
diff --git a/nashorn/test/script/basic/NASHORN-500.js b/nashorn/test/script/basic/NASHORN-500.js
new file mode 100644
index 0000000..30546e8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-500.js
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-500 :  Using ScriptRuntime.toString for error reporting from runtime is problematic
+ *
+ * @test
+ * @run
+ */
+
+var origToString = Object.prototype.toString;
+Object.prototype.toString = function () { 
+    return this.myStr();
+}
+
+try {
+    print({});
+    fail("#1 toString should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#2 TypeError expected, got " + e);
+    }
+} finally {
+    Object.prototype.toString = origToString;
+}
+
+try {
+    print({ toString: function() { return this.foo(); } });
+    fail("#3 toString should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#4 TypeError expected, got " + e);
+    }
+}
+
+try {
+    var e = new Error();
+    e.toString = function() { return this.foo(); }
+    var lineNumber = __LINE__;
+    throw e;
+} catch (e) {
+    if (e.nashornException.lineNumber !== lineNumber  + 1) {
+        fail("#5 exception throw line number is incorrect");
+    }
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-503.js b/nashorn/test/script/basic/NASHORN-503.js
new file mode 100644
index 0000000..5083881
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-503.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-503 : regression: closure loses context.
+ *
+ * @test
+ * @run
+ */
+
+function next(f) { f(); }
+
+try {
+    throw new TypeError('error');
+} catch (iox) {
+    print('catch ' + iox.message);
+    next(function() {
+        print('next ' + iox.message);
+    });
+}
+
+
+try {
+    throw new TypeError('error');
+} catch (iox) {
+    print('catch ' + iox.message);
+    next(function() {
+        var iox = {};
+        print(iox.message);
+    });
+    print('catch ' + iox.message);
+}
diff --git a/nashorn/test/script/basic/NASHORN-503.js.EXPECTED b/nashorn/test/script/basic/NASHORN-503.js.EXPECTED
new file mode 100644
index 0000000..a655ff5
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-503.js.EXPECTED
@@ -0,0 +1,5 @@
+catch error
+next error
+catch error
+undefined
+catch error
diff --git a/nashorn/test/script/basic/NASHORN-51.js b/nashorn/test/script/basic/NASHORN-51.js
new file mode 100644
index 0000000..044bce9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-51.js
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-51 :  Post/pre increment and decrement operators should only accept "left hand side" expression.
+ *
+ * @test
+ * @run
+ */
+
+var literals = [1, 0, 3.14, true, false, null];
+
+for (i in literals) {
+    try {
+        eval(literals[i] + "++");
+        print("ERROR!! post increment : " + literals[i]);
+    } catch (e) {
+        print(e);
+    }
+
+    try {
+        eval(literals[i] + "--");
+        print("ERROR!! post decrement : " + literals[i]);
+    } catch (e) {
+        print(e);
+    }
+
+    try {
+        eval("++" + literals[i]);
+        print("ERROR!! pre increment : " + literals[i]);
+    } catch (e) {
+        print(e);
+    }
+
+    try {
+        eval("--" + literals[i]);
+        print("ERROR!! pre decrement : " + literals[i]);
+    } catch (e) {
+        print(e);
+    }
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-51.js.EXPECTED b/nashorn/test/script/basic/NASHORN-51.js.EXPECTED
new file mode 100644
index 0000000..9fc05c3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-51.js.EXPECTED
@@ -0,0 +1,24 @@
+ReferenceError: "1" can not be used as the left-hand side of assignment
+ReferenceError: "1" can not be used as the left-hand side of assignment
+ReferenceError: "1" can not be used as the left-hand side of assignment
+ReferenceError: "1" can not be used as the left-hand side of assignment
+ReferenceError: "0" can not be used as the left-hand side of assignment
+ReferenceError: "0" can not be used as the left-hand side of assignment
+ReferenceError: "0" can not be used as the left-hand side of assignment
+ReferenceError: "0" can not be used as the left-hand side of assignment
+ReferenceError: "3.14" can not be used as the left-hand side of assignment
+ReferenceError: "3.14" can not be used as the left-hand side of assignment
+ReferenceError: "3.14" can not be used as the left-hand side of assignment
+ReferenceError: "3.14" can not be used as the left-hand side of assignment
+ReferenceError: "true" can not be used as the left-hand side of assignment
+ReferenceError: "true" can not be used as the left-hand side of assignment
+ReferenceError: "true" can not be used as the left-hand side of assignment
+ReferenceError: "true" can not be used as the left-hand side of assignment
+ReferenceError: "false" can not be used as the left-hand side of assignment
+ReferenceError: "false" can not be used as the left-hand side of assignment
+ReferenceError: "false" can not be used as the left-hand side of assignment
+ReferenceError: "false" can not be used as the left-hand side of assignment
+ReferenceError: "null" can not be used as the left-hand side of assignment
+ReferenceError: "null" can not be used as the left-hand side of assignment
+ReferenceError: "null" can not be used as the left-hand side of assignment
+ReferenceError: "null" can not be used as the left-hand side of assignment
diff --git a/nashorn/test/script/basic/NASHORN-511.js b/nashorn/test/script/basic/NASHORN-511.js
new file mode 100644
index 0000000..edac1a9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-511.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-511 : var has no effect on existing globals.
+ *
+ * @test
+ * @run
+ */
+
+var y = 23;
+if (delete y != false) {
+    fail('#1: can delete declared var y');
+}
+if (delete this.y != false) {
+    fail('#2: can delete declared var using this.y');
+}
+
+var parseInt = 23;
+if (delete parseInt !== true) {
+    fail('#3: delete parseInt !== true');
+}
+if (delete this.parseInt !== true) {
+    fail('#4: delete this.parseInt !== true');
+}
+
+z = 24;
+eval("var z = 25;\
+if (delete z !== true) {\
+    fail('#5: delete z !== true');\
+}\
+if (delete this.z !== true) {\
+    fail('#6: delete this.z !== true');\
+}\
+");
diff --git a/nashorn/test/script/basic/NASHORN-515.js b/nashorn/test/script/basic/NASHORN-515.js
new file mode 100644
index 0000000..198be1f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-515.js
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-515 : Switch default handling was broken.
+ *
+ * @test
+ * @run
+ */
+
+function a() {
+    var x = (3.14-2.14);
+    
+    switch (x) {
+    case 1:
+	print("--1"); 
+	break;
+    case 2:
+	print("--2"); 
+	break;
+    default:
+	print("default");
+	break;
+    }
+}
+
+//NASHORN-529 - original fix was incomplete for primitive types
+function b() {
+    var index = 256.3;
+    switch (index) {
+    case 0x00:
+    case 0x01:
+	print("one zero");
+	break;
+    default:
+	print("default");
+	break;
+    }
+}
+
+//NASHORN-529 - original fix was incomplete for primitive types
+function c() {
+    var index = 0x1fffffffff;
+    switch (index) {
+    case 0x00:
+    case 0x01:
+	print("one zero");
+	break;
+    default:
+	print("default");
+    }
+    --index;
+}
+
+function d() {
+    var x = (3.14-1.14);
+    
+    switch(x) {
+    case 1:
+	print("--1"); break;
+    case 2:
+	print("--2"); break;
+    case 3:
+	print("--3"); break;
+    case 4:
+	print("--4"); break;
+    default:
+	print("default");
+    }
+}
+
+function e() {
+    var y = 2147483647;
+    
+    switch(y) {
+    case -2147483648:
+	print("MIN_INT"); break;
+    case -2147483647:
+	print("MIN_INT+1"); break;
+    case 2147483647:
+	print("MAX_INT"); break;
+    case 1:
+	print("--1"); break;
+    case 2:
+	print("--2"); break;
+    case 3:
+	print("--3"); break;
+    case 4:
+	print("--4"); break;
+    default:
+	print("default");
+    }
+}
+
+function f() {
+    var z = 2;
+    
+    switch(z) {
+    case -2147483648:
+	print("MIN_INT"); break;
+    case -2147483647:
+	print("MIN_INT+1"); break;
+    case 2147483647:
+	print("MAX_INT"); break;
+    case 1:
+	print("--1"); break;
+    case 2:
+	print("--2 first"); break;
+    case 2:
+	print("--2 second"); break;
+    case 3:
+	print("--3"); break;
+    case 4:
+	print("--4"); break;
+    default:
+	print("default");
+    }
+}
+
+a();
+b();
+c();
+d();
+e();
+f();
diff --git a/nashorn/test/script/basic/NASHORN-515.js.EXPECTED b/nashorn/test/script/basic/NASHORN-515.js.EXPECTED
new file mode 100644
index 0000000..1ca9783
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-515.js.EXPECTED
@@ -0,0 +1,6 @@
+--1
+default
+default
+--2
+MAX_INT
+--2 first
diff --git a/nashorn/test/script/basic/NASHORN-516.js b/nashorn/test/script/basic/NASHORN-516.js
new file mode 100644
index 0000000..f369b9c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-516.js
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-516 : Modified NASHORN-500 test case fails.
+ *
+ * @test
+ * @run
+ */
+
+var origToString = Object.prototype.toString;
+Object.prototype.toString = function () {
+    return this.myStr();
+}
+
+try {
+    print({});
+    fail("#1 toString should have thrown TypeError");
+} catch (e) {
+    (function() {
+        if (! (e instanceof TypeError)) {
+            fail("#2 TypeError expected, got " + e);
+        }
+    })();
+} finally {
+    Object.prototype.toString = origToString;
+}
+
+var e = new Error();
diff --git a/nashorn/test/script/basic/NASHORN-52.js b/nashorn/test/script/basic/NASHORN-52.js
new file mode 100644
index 0000000..1727e02
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-52.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-52 :  \v escape sequence should be accepted by Lexer
+ *
+ * @test
+ * @run
+ */
+
+// The following used to result in ReferenceError.
+// but \v is escape sequence for vertical tab char.
+
+eval("\vvar\vx\v=\v1\v");
+if (x !== 1) {
+    print("ERROR: x should be 1");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-534.js b/nashorn/test/script/basic/NASHORN-534.js
new file mode 100644
index 0000000..ab7a9b9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-534.js
@@ -0,0 +1,30066 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-534 - Script Constant Pool.
+ *
+ * @test
+ * @run
+ */
+
+var largeInteger = [
+0,
+1,
+2,
+3,
+4,
+5,
+6,
+7,
+8,
+9,
+10,
+11,
+12,
+13,
+14,
+15,
+16,
+17,
+18,
+19,
+20,
+21,
+22,
+23,
+24,
+25,
+26,
+27,
+28,
+29,
+30,
+31,
+32,
+33,
+34,
+35,
+36,
+37,
+38,
+39,
+40,
+41,
+42,
+43,
+44,
+45,
+46,
+47,
+48,
+49,
+50,
+51,
+52,
+53,
+54,
+55,
+56,
+57,
+58,
+59,
+60,
+61,
+62,
+63,
+64,
+65,
+66,
+67,
+68,
+69,
+70,
+71,
+72,
+73,
+74,
+75,
+76,
+77,
+78,
+79,
+80,
+81,
+82,
+83,
+84,
+85,
+86,
+87,
+88,
+89,
+90,
+91,
+92,
+93,
+94,
+95,
+96,
+97,
+98,
+99,
+100,
+101,
+102,
+103,
+104,
+105,
+106,
+107,
+108,
+109,
+110,
+111,
+112,
+113,
+114,
+115,
+116,
+117,
+118,
+119,
+120,
+121,
+122,
+123,
+124,
+125,
+126,
+127,
+128,
+129,
+130,
+131,
+132,
+133,
+134,
+135,
+136,
+137,
+138,
+139,
+140,
+141,
+142,
+143,
+144,
+145,
+146,
+147,
+148,
+149,
+150,
+151,
+152,
+153,
+154,
+155,
+156,
+157,
+158,
+159,
+160,
+161,
+162,
+163,
+164,
+165,
+166,
+167,
+168,
+169,
+170,
+171,
+172,
+173,
+174,
+175,
+176,
+177,
+178,
+179,
+180,
+181,
+182,
+183,
+184,
+185,
+186,
+187,
+188,
+189,
+190,
+191,
+192,
+193,
+194,
+195,
+196,
+197,
+198,
+199,
+200,
+201,
+202,
+203,
+204,
+205,
+206,
+207,
+208,
+209,
+210,
+211,
+212,
+213,
+214,
+215,
+216,
+217,
+218,
+219,
+220,
+221,
+222,
+223,
+224,
+225,
+226,
+227,
+228,
+229,
+230,
+231,
+232,
+233,
+234,
+235,
+236,
+237,
+238,
+239,
+240,
+241,
+242,
+243,
+244,
+245,
+246,
+247,
+248,
+249,
+250,
+251,
+252,
+253,
+254,
+255,
+256,
+257,
+258,
+259,
+260,
+261,
+262,
+263,
+264,
+265,
+266,
+267,
+268,
+269,
+270,
+271,
+272,
+273,
+274,
+275,
+276,
+277,
+278,
+279,
+280,
+281,
+282,
+283,
+284,
+285,
+286,
+287,
+288,
+289,
+290,
+291,
+292,
+293,
+294,
+295,
+296,
+297,
+298,
+299,
+300,
+301,
+302,
+303,
+304,
+305,
+306,
+307,
+308,
+309,
+310,
+311,
+312,
+313,
+314,
+315,
+316,
+317,
+318,
+319,
+320,
+321,
+322,
+323,
+324,
+325,
+326,
+327,
+328,
+329,
+330,
+331,
+332,
+333,
+334,
+335,
+336,
+337,
+338,
+339,
+340,
+341,
+342,
+343,
+344,
+345,
+346,
+347,
+348,
+349,
+350,
+351,
+352,
+353,
+354,
+355,
+356,
+357,
+358,
+359,
+360,
+361,
+362,
+363,
+364,
+365,
+366,
+367,
+368,
+369,
+370,
+371,
+372,
+373,
+374,
+375,
+376,
+377,
+378,
+379,
+380,
+381,
+382,
+383,
+384,
+385,
+386,
+387,
+388,
+389,
+390,
+391,
+392,
+393,
+394,
+395,
+396,
+397,
+398,
+399,
+400,
+401,
+402,
+403,
+404,
+405,
+406,
+407,
+408,
+409,
+410,
+411,
+412,
+413,
+414,
+415,
+416,
+417,
+418,
+419,
+420,
+421,
+422,
+423,
+424,
+425,
+426,
+427,
+428,
+429,
+430,
+431,
+432,
+433,
+434,
+435,
+436,
+437,
+438,
+439,
+440,
+441,
+442,
+443,
+444,
+445,
+446,
+447,
+448,
+449,
+450,
+451,
+452,
+453,
+454,
+455,
+456,
+457,
+458,
+459,
+460,
+461,
+462,
+463,
+464,
+465,
+466,
+467,
+468,
+469,
+470,
+471,
+472,
+473,
+474,
+475,
+476,
+477,
+478,
+479,
+480,
+481,
+482,
+483,
+484,
+485,
+486,
+487,
+488,
+489,
+490,
+491,
+492,
+493,
+494,
+495,
+496,
+497,
+498,
+499,
+500,
+501,
+502,
+503,
+504,
+505,
+506,
+507,
+508,
+509,
+510,
+511,
+512,
+513,
+514,
+515,
+516,
+517,
+518,
+519,
+520,
+521,
+522,
+523,
+524,
+525,
+526,
+527,
+528,
+529,
+530,
+531,
+532,
+533,
+534,
+535,
+536,
+537,
+538,
+539,
+540,
+541,
+542,
+543,
+544,
+545,
+546,
+547,
+548,
+549,
+550,
+551,
+552,
+553,
+554,
+555,
+556,
+557,
+558,
+559,
+560,
+561,
+562,
+563,
+564,
+565,
+566,
+567,
+568,
+569,
+570,
+571,
+572,
+573,
+574,
+575,
+576,
+577,
+578,
+579,
+580,
+581,
+582,
+583,
+584,
+585,
+586,
+587,
+588,
+589,
+590,
+591,
+592,
+593,
+594,
+595,
+596,
+597,
+598,
+599,
+600,
+601,
+602,
+603,
+604,
+605,
+606,
+607,
+608,
+609,
+610,
+611,
+612,
+613,
+614,
+615,
+616,
+617,
+618,
+619,
+620,
+621,
+622,
+623,
+624,
+625,
+626,
+627,
+628,
+629,
+630,
+631,
+632,
+633,
+634,
+635,
+636,
+637,
+638,
+639,
+640,
+641,
+642,
+643,
+644,
+645,
+646,
+647,
+648,
+649,
+650,
+651,
+652,
+653,
+654,
+655,
+656,
+657,
+658,
+659,
+660,
+661,
+662,
+663,
+664,
+665,
+666,
+667,
+668,
+669,
+670,
+671,
+672,
+673,
+674,
+675,
+676,
+677,
+678,
+679,
+680,
+681,
+682,
+683,
+684,
+685,
+686,
+687,
+688,
+689,
+690,
+691,
+692,
+693,
+694,
+695,
+696,
+697,
+698,
+699,
+700,
+701,
+702,
+703,
+704,
+705,
+706,
+707,
+708,
+709,
+710,
+711,
+712,
+713,
+714,
+715,
+716,
+717,
+718,
+719,
+720,
+721,
+722,
+723,
+724,
+725,
+726,
+727,
+728,
+729,
+730,
+731,
+732,
+733,
+734,
+735,
+736,
+737,
+738,
+739,
+740,
+741,
+742,
+743,
+744,
+745,
+746,
+747,
+748,
+749,
+750,
+751,
+752,
+753,
+754,
+755,
+756,
+757,
+758,
+759,
+760,
+761,
+762,
+763,
+764,
+765,
+766,
+767,
+768,
+769,
+770,
+771,
+772,
+773,
+774,
+775,
+776,
+777,
+778,
+779,
+780,
+781,
+782,
+783,
+784,
+785,
+786,
+787,
+788,
+789,
+790,
+791,
+792,
+793,
+794,
+795,
+796,
+797,
+798,
+799,
+800,
+801,
+802,
+803,
+804,
+805,
+806,
+807,
+808,
+809,
+810,
+811,
+812,
+813,
+814,
+815,
+816,
+817,
+818,
+819,
+820,
+821,
+822,
+823,
+824,
+825,
+826,
+827,
+828,
+829,
+830,
+831,
+832,
+833,
+834,
+835,
+836,
+837,
+838,
+839,
+840,
+841,
+842,
+843,
+844,
+845,
+846,
+847,
+848,
+849,
+850,
+851,
+852,
+853,
+854,
+855,
+856,
+857,
+858,
+859,
+860,
+861,
+862,
+863,
+864,
+865,
+866,
+867,
+868,
+869,
+870,
+871,
+872,
+873,
+874,
+875,
+876,
+877,
+878,
+879,
+880,
+881,
+882,
+883,
+884,
+885,
+886,
+887,
+888,
+889,
+890,
+891,
+892,
+893,
+894,
+895,
+896,
+897,
+898,
+899,
+900,
+901,
+902,
+903,
+904,
+905,
+906,
+907,
+908,
+909,
+910,
+911,
+912,
+913,
+914,
+915,
+916,
+917,
+918,
+919,
+920,
+921,
+922,
+923,
+924,
+925,
+926,
+927,
+928,
+929,
+930,
+931,
+932,
+933,
+934,
+935,
+936,
+937,
+938,
+939,
+940,
+941,
+942,
+943,
+944,
+945,
+946,
+947,
+948,
+949,
+950,
+951,
+952,
+953,
+954,
+955,
+956,
+957,
+958,
+959,
+960,
+961,
+962,
+963,
+964,
+965,
+966,
+967,
+968,
+969,
+970,
+971,
+972,
+973,
+974,
+975,
+976,
+977,
+978,
+979,
+980,
+981,
+982,
+983,
+984,
+985,
+986,
+987,
+988,
+989,
+990,
+991,
+992,
+993,
+994,
+995,
+996,
+997,
+998,
+999,
+1000,
+1001,
+1002,
+1003,
+1004,
+1005,
+1006,
+1007,
+1008,
+1009,
+1010,
+1011,
+1012,
+1013,
+1014,
+1015,
+1016,
+1017,
+1018,
+1019,
+1020,
+1021,
+1022,
+1023,
+1024,
+1025,
+1026,
+1027,
+1028,
+1029,
+1030,
+1031,
+1032,
+1033,
+1034,
+1035,
+1036,
+1037,
+1038,
+1039,
+1040,
+1041,
+1042,
+1043,
+1044,
+1045,
+1046,
+1047,
+1048,
+1049,
+1050,
+1051,
+1052,
+1053,
+1054,
+1055,
+1056,
+1057,
+1058,
+1059,
+1060,
+1061,
+1062,
+1063,
+1064,
+1065,
+1066,
+1067,
+1068,
+1069,
+1070,
+1071,
+1072,
+1073,
+1074,
+1075,
+1076,
+1077,
+1078,
+1079,
+1080,
+1081,
+1082,
+1083,
+1084,
+1085,
+1086,
+1087,
+1088,
+1089,
+1090,
+1091,
+1092,
+1093,
+1094,
+1095,
+1096,
+1097,
+1098,
+1099,
+1100,
+1101,
+1102,
+1103,
+1104,
+1105,
+1106,
+1107,
+1108,
+1109,
+1110,
+1111,
+1112,
+1113,
+1114,
+1115,
+1116,
+1117,
+1118,
+1119,
+1120,
+1121,
+1122,
+1123,
+1124,
+1125,
+1126,
+1127,
+1128,
+1129,
+1130,
+1131,
+1132,
+1133,
+1134,
+1135,
+1136,
+1137,
+1138,
+1139,
+1140,
+1141,
+1142,
+1143,
+1144,
+1145,
+1146,
+1147,
+1148,
+1149,
+1150,
+1151,
+1152,
+1153,
+1154,
+1155,
+1156,
+1157,
+1158,
+1159,
+1160,
+1161,
+1162,
+1163,
+1164,
+1165,
+1166,
+1167,
+1168,
+1169,
+1170,
+1171,
+1172,
+1173,
+1174,
+1175,
+1176,
+1177,
+1178,
+1179,
+1180,
+1181,
+1182,
+1183,
+1184,
+1185,
+1186,
+1187,
+1188,
+1189,
+1190,
+1191,
+1192,
+1193,
+1194,
+1195,
+1196,
+1197,
+1198,
+1199,
+1200,
+1201,
+1202,
+1203,
+1204,
+1205,
+1206,
+1207,
+1208,
+1209,
+1210,
+1211,
+1212,
+1213,
+1214,
+1215,
+1216,
+1217,
+1218,
+1219,
+1220,
+1221,
+1222,
+1223,
+1224,
+1225,
+1226,
+1227,
+1228,
+1229,
+1230,
+1231,
+1232,
+1233,
+1234,
+1235,
+1236,
+1237,
+1238,
+1239,
+1240,
+1241,
+1242,
+1243,
+1244,
+1245,
+1246,
+1247,
+1248,
+1249,
+1250,
+1251,
+1252,
+1253,
+1254,
+1255,
+1256,
+1257,
+1258,
+1259,
+1260,
+1261,
+1262,
+1263,
+1264,
+1265,
+1266,
+1267,
+1268,
+1269,
+1270,
+1271,
+1272,
+1273,
+1274,
+1275,
+1276,
+1277,
+1278,
+1279,
+1280,
+1281,
+1282,
+1283,
+1284,
+1285,
+1286,
+1287,
+1288,
+1289,
+1290,
+1291,
+1292,
+1293,
+1294,
+1295,
+1296,
+1297,
+1298,
+1299,
+1300,
+1301,
+1302,
+1303,
+1304,
+1305,
+1306,
+1307,
+1308,
+1309,
+1310,
+1311,
+1312,
+1313,
+1314,
+1315,
+1316,
+1317,
+1318,
+1319,
+1320,
+1321,
+1322,
+1323,
+1324,
+1325,
+1326,
+1327,
+1328,
+1329,
+1330,
+1331,
+1332,
+1333,
+1334,
+1335,
+1336,
+1337,
+1338,
+1339,
+1340,
+1341,
+1342,
+1343,
+1344,
+1345,
+1346,
+1347,
+1348,
+1349,
+1350,
+1351,
+1352,
+1353,
+1354,
+1355,
+1356,
+1357,
+1358,
+1359,
+1360,
+1361,
+1362,
+1363,
+1364,
+1365,
+1366,
+1367,
+1368,
+1369,
+1370,
+1371,
+1372,
+1373,
+1374,
+1375,
+1376,
+1377,
+1378,
+1379,
+1380,
+1381,
+1382,
+1383,
+1384,
+1385,
+1386,
+1387,
+1388,
+1389,
+1390,
+1391,
+1392,
+1393,
+1394,
+1395,
+1396,
+1397,
+1398,
+1399,
+1400,
+1401,
+1402,
+1403,
+1404,
+1405,
+1406,
+1407,
+1408,
+1409,
+1410,
+1411,
+1412,
+1413,
+1414,
+1415,
+1416,
+1417,
+1418,
+1419,
+1420,
+1421,
+1422,
+1423,
+1424,
+1425,
+1426,
+1427,
+1428,
+1429,
+1430,
+1431,
+1432,
+1433,
+1434,
+1435,
+1436,
+1437,
+1438,
+1439,
+1440,
+1441,
+1442,
+1443,
+1444,
+1445,
+1446,
+1447,
+1448,
+1449,
+1450,
+1451,
+1452,
+1453,
+1454,
+1455,
+1456,
+1457,
+1458,
+1459,
+1460,
+1461,
+1462,
+1463,
+1464,
+1465,
+1466,
+1467,
+1468,
+1469,
+1470,
+1471,
+1472,
+1473,
+1474,
+1475,
+1476,
+1477,
+1478,
+1479,
+1480,
+1481,
+1482,
+1483,
+1484,
+1485,
+1486,
+1487,
+1488,
+1489,
+1490,
+1491,
+1492,
+1493,
+1494,
+1495,
+1496,
+1497,
+1498,
+1499,
+1500,
+1501,
+1502,
+1503,
+1504,
+1505,
+1506,
+1507,
+1508,
+1509,
+1510,
+1511,
+1512,
+1513,
+1514,
+1515,
+1516,
+1517,
+1518,
+1519,
+1520,
+1521,
+1522,
+1523,
+1524,
+1525,
+1526,
+1527,
+1528,
+1529,
+1530,
+1531,
+1532,
+1533,
+1534,
+1535,
+1536,
+1537,
+1538,
+1539,
+1540,
+1541,
+1542,
+1543,
+1544,
+1545,
+1546,
+1547,
+1548,
+1549,
+1550,
+1551,
+1552,
+1553,
+1554,
+1555,
+1556,
+1557,
+1558,
+1559,
+1560,
+1561,
+1562,
+1563,
+1564,
+1565,
+1566,
+1567,
+1568,
+1569,
+1570,
+1571,
+1572,
+1573,
+1574,
+1575,
+1576,
+1577,
+1578,
+1579,
+1580,
+1581,
+1582,
+1583,
+1584,
+1585,
+1586,
+1587,
+1588,
+1589,
+1590,
+1591,
+1592,
+1593,
+1594,
+1595,
+1596,
+1597,
+1598,
+1599,
+1600,
+1601,
+1602,
+1603,
+1604,
+1605,
+1606,
+1607,
+1608,
+1609,
+1610,
+1611,
+1612,
+1613,
+1614,
+1615,
+1616,
+1617,
+1618,
+1619,
+1620,
+1621,
+1622,
+1623,
+1624,
+1625,
+1626,
+1627,
+1628,
+1629,
+1630,
+1631,
+1632,
+1633,
+1634,
+1635,
+1636,
+1637,
+1638,
+1639,
+1640,
+1641,
+1642,
+1643,
+1644,
+1645,
+1646,
+1647,
+1648,
+1649,
+1650,
+1651,
+1652,
+1653,
+1654,
+1655,
+1656,
+1657,
+1658,
+1659,
+1660,
+1661,
+1662,
+1663,
+1664,
+1665,
+1666,
+1667,
+1668,
+1669,
+1670,
+1671,
+1672,
+1673,
+1674,
+1675,
+1676,
+1677,
+1678,
+1679,
+1680,
+1681,
+1682,
+1683,
+1684,
+1685,
+1686,
+1687,
+1688,
+1689,
+1690,
+1691,
+1692,
+1693,
+1694,
+1695,
+1696,
+1697,
+1698,
+1699,
+1700,
+1701,
+1702,
+1703,
+1704,
+1705,
+1706,
+1707,
+1708,
+1709,
+1710,
+1711,
+1712,
+1713,
+1714,
+1715,
+1716,
+1717,
+1718,
+1719,
+1720,
+1721,
+1722,
+1723,
+1724,
+1725,
+1726,
+1727,
+1728,
+1729,
+1730,
+1731,
+1732,
+1733,
+1734,
+1735,
+1736,
+1737,
+1738,
+1739,
+1740,
+1741,
+1742,
+1743,
+1744,
+1745,
+1746,
+1747,
+1748,
+1749,
+1750,
+1751,
+1752,
+1753,
+1754,
+1755,
+1756,
+1757,
+1758,
+1759,
+1760,
+1761,
+1762,
+1763,
+1764,
+1765,
+1766,
+1767,
+1768,
+1769,
+1770,
+1771,
+1772,
+1773,
+1774,
+1775,
+1776,
+1777,
+1778,
+1779,
+1780,
+1781,
+1782,
+1783,
+1784,
+1785,
+1786,
+1787,
+1788,
+1789,
+1790,
+1791,
+1792,
+1793,
+1794,
+1795,
+1796,
+1797,
+1798,
+1799,
+1800,
+1801,
+1802,
+1803,
+1804,
+1805,
+1806,
+1807,
+1808,
+1809,
+1810,
+1811,
+1812,
+1813,
+1814,
+1815,
+1816,
+1817,
+1818,
+1819,
+1820,
+1821,
+1822,
+1823,
+1824,
+1825,
+1826,
+1827,
+1828,
+1829,
+1830,
+1831,
+1832,
+1833,
+1834,
+1835,
+1836,
+1837,
+1838,
+1839,
+1840,
+1841,
+1842,
+1843,
+1844,
+1845,
+1846,
+1847,
+1848,
+1849,
+1850,
+1851,
+1852,
+1853,
+1854,
+1855,
+1856,
+1857,
+1858,
+1859,
+1860,
+1861,
+1862,
+1863,
+1864,
+1865,
+1866,
+1867,
+1868,
+1869,
+1870,
+1871,
+1872,
+1873,
+1874,
+1875,
+1876,
+1877,
+1878,
+1879,
+1880,
+1881,
+1882,
+1883,
+1884,
+1885,
+1886,
+1887,
+1888,
+1889,
+1890,
+1891,
+1892,
+1893,
+1894,
+1895,
+1896,
+1897,
+1898,
+1899,
+1900,
+1901,
+1902,
+1903,
+1904,
+1905,
+1906,
+1907,
+1908,
+1909,
+1910,
+1911,
+1912,
+1913,
+1914,
+1915,
+1916,
+1917,
+1918,
+1919,
+1920,
+1921,
+1922,
+1923,
+1924,
+1925,
+1926,
+1927,
+1928,
+1929,
+1930,
+1931,
+1932,
+1933,
+1934,
+1935,
+1936,
+1937,
+1938,
+1939,
+1940,
+1941,
+1942,
+1943,
+1944,
+1945,
+1946,
+1947,
+1948,
+1949,
+1950,
+1951,
+1952,
+1953,
+1954,
+1955,
+1956,
+1957,
+1958,
+1959,
+1960,
+1961,
+1962,
+1963,
+1964,
+1965,
+1966,
+1967,
+1968,
+1969,
+1970,
+1971,
+1972,
+1973,
+1974,
+1975,
+1976,
+1977,
+1978,
+1979,
+1980,
+1981,
+1982,
+1983,
+1984,
+1985,
+1986,
+1987,
+1988,
+1989,
+1990,
+1991,
+1992,
+1993,
+1994,
+1995,
+1996,
+1997,
+1998,
+1999,
+2000,
+2001,
+2002,
+2003,
+2004,
+2005,
+2006,
+2007,
+2008,
+2009,
+2010,
+2011,
+2012,
+2013,
+2014,
+2015,
+2016,
+2017,
+2018,
+2019,
+2020,
+2021,
+2022,
+2023,
+2024,
+2025,
+2026,
+2027,
+2028,
+2029,
+2030,
+2031,
+2032,
+2033,
+2034,
+2035,
+2036,
+2037,
+2038,
+2039,
+2040,
+2041,
+2042,
+2043,
+2044,
+2045,
+2046,
+2047,
+2048,
+2049,
+2050,
+2051,
+2052,
+2053,
+2054,
+2055,
+2056,
+2057,
+2058,
+2059,
+2060,
+2061,
+2062,
+2063,
+2064,
+2065,
+2066,
+2067,
+2068,
+2069,
+2070,
+2071,
+2072,
+2073,
+2074,
+2075,
+2076,
+2077,
+2078,
+2079,
+2080,
+2081,
+2082,
+2083,
+2084,
+2085,
+2086,
+2087,
+2088,
+2089,
+2090,
+2091,
+2092,
+2093,
+2094,
+2095,
+2096,
+2097,
+2098,
+2099,
+2100,
+2101,
+2102,
+2103,
+2104,
+2105,
+2106,
+2107,
+2108,
+2109,
+2110,
+2111,
+2112,
+2113,
+2114,
+2115,
+2116,
+2117,
+2118,
+2119,
+2120,
+2121,
+2122,
+2123,
+2124,
+2125,
+2126,
+2127,
+2128,
+2129,
+2130,
+2131,
+2132,
+2133,
+2134,
+2135,
+2136,
+2137,
+2138,
+2139,
+2140,
+2141,
+2142,
+2143,
+2144,
+2145,
+2146,
+2147,
+2148,
+2149,
+2150,
+2151,
+2152,
+2153,
+2154,
+2155,
+2156,
+2157,
+2158,
+2159,
+2160,
+2161,
+2162,
+2163,
+2164,
+2165,
+2166,
+2167,
+2168,
+2169,
+2170,
+2171,
+2172,
+2173,
+2174,
+2175,
+2176,
+2177,
+2178,
+2179,
+2180,
+2181,
+2182,
+2183,
+2184,
+2185,
+2186,
+2187,
+2188,
+2189,
+2190,
+2191,
+2192,
+2193,
+2194,
+2195,
+2196,
+2197,
+2198,
+2199,
+2200,
+2201,
+2202,
+2203,
+2204,
+2205,
+2206,
+2207,
+2208,
+2209,
+2210,
+2211,
+2212,
+2213,
+2214,
+2215,
+2216,
+2217,
+2218,
+2219,
+2220,
+2221,
+2222,
+2223,
+2224,
+2225,
+2226,
+2227,
+2228,
+2229,
+2230,
+2231,
+2232,
+2233,
+2234,
+2235,
+2236,
+2237,
+2238,
+2239,
+2240,
+2241,
+2242,
+2243,
+2244,
+2245,
+2246,
+2247,
+2248,
+2249,
+2250,
+2251,
+2252,
+2253,
+2254,
+2255,
+2256,
+2257,
+2258,
+2259,
+2260,
+2261,
+2262,
+2263,
+2264,
+2265,
+2266,
+2267,
+2268,
+2269,
+2270,
+2271,
+2272,
+2273,
+2274,
+2275,
+2276,
+2277,
+2278,
+2279,
+2280,
+2281,
+2282,
+2283,
+2284,
+2285,
+2286,
+2287,
+2288,
+2289,
+2290,
+2291,
+2292,
+2293,
+2294,
+2295,
+2296,
+2297,
+2298,
+2299,
+2300,
+2301,
+2302,
+2303,
+2304,
+2305,
+2306,
+2307,
+2308,
+2309,
+2310,
+2311,
+2312,
+2313,
+2314,
+2315,
+2316,
+2317,
+2318,
+2319,
+2320,
+2321,
+2322,
+2323,
+2324,
+2325,
+2326,
+2327,
+2328,
+2329,
+2330,
+2331,
+2332,
+2333,
+2334,
+2335,
+2336,
+2337,
+2338,
+2339,
+2340,
+2341,
+2342,
+2343,
+2344,
+2345,
+2346,
+2347,
+2348,
+2349,
+2350,
+2351,
+2352,
+2353,
+2354,
+2355,
+2356,
+2357,
+2358,
+2359,
+2360,
+2361,
+2362,
+2363,
+2364,
+2365,
+2366,
+2367,
+2368,
+2369,
+2370,
+2371,
+2372,
+2373,
+2374,
+2375,
+2376,
+2377,
+2378,
+2379,
+2380,
+2381,
+2382,
+2383,
+2384,
+2385,
+2386,
+2387,
+2388,
+2389,
+2390,
+2391,
+2392,
+2393,
+2394,
+2395,
+2396,
+2397,
+2398,
+2399,
+2400,
+2401,
+2402,
+2403,
+2404,
+2405,
+2406,
+2407,
+2408,
+2409,
+2410,
+2411,
+2412,
+2413,
+2414,
+2415,
+2416,
+2417,
+2418,
+2419,
+2420,
+2421,
+2422,
+2423,
+2424,
+2425,
+2426,
+2427,
+2428,
+2429,
+2430,
+2431,
+2432,
+2433,
+2434,
+2435,
+2436,
+2437,
+2438,
+2439,
+2440,
+2441,
+2442,
+2443,
+2444,
+2445,
+2446,
+2447,
+2448,
+2449,
+2450,
+2451,
+2452,
+2453,
+2454,
+2455,
+2456,
+2457,
+2458,
+2459,
+2460,
+2461,
+2462,
+2463,
+2464,
+2465,
+2466,
+2467,
+2468,
+2469,
+2470,
+2471,
+2472,
+2473,
+2474,
+2475,
+2476,
+2477,
+2478,
+2479,
+2480,
+2481,
+2482,
+2483,
+2484,
+2485,
+2486,
+2487,
+2488,
+2489,
+2490,
+2491,
+2492,
+2493,
+2494,
+2495,
+2496,
+2497,
+2498,
+2499,
+2500,
+2501,
+2502,
+2503,
+2504,
+2505,
+2506,
+2507,
+2508,
+2509,
+2510,
+2511,
+2512,
+2513,
+2514,
+2515,
+2516,
+2517,
+2518,
+2519,
+2520,
+2521,
+2522,
+2523,
+2524,
+2525,
+2526,
+2527,
+2528,
+2529,
+2530,
+2531,
+2532,
+2533,
+2534,
+2535,
+2536,
+2537,
+2538,
+2539,
+2540,
+2541,
+2542,
+2543,
+2544,
+2545,
+2546,
+2547,
+2548,
+2549,
+2550,
+2551,
+2552,
+2553,
+2554,
+2555,
+2556,
+2557,
+2558,
+2559,
+2560,
+2561,
+2562,
+2563,
+2564,
+2565,
+2566,
+2567,
+2568,
+2569,
+2570,
+2571,
+2572,
+2573,
+2574,
+2575,
+2576,
+2577,
+2578,
+2579,
+2580,
+2581,
+2582,
+2583,
+2584,
+2585,
+2586,
+2587,
+2588,
+2589,
+2590,
+2591,
+2592,
+2593,
+2594,
+2595,
+2596,
+2597,
+2598,
+2599,
+2600,
+2601,
+2602,
+2603,
+2604,
+2605,
+2606,
+2607,
+2608,
+2609,
+2610,
+2611,
+2612,
+2613,
+2614,
+2615,
+2616,
+2617,
+2618,
+2619,
+2620,
+2621,
+2622,
+2623,
+2624,
+2625,
+2626,
+2627,
+2628,
+2629,
+2630,
+2631,
+2632,
+2633,
+2634,
+2635,
+2636,
+2637,
+2638,
+2639,
+2640,
+2641,
+2642,
+2643,
+2644,
+2645,
+2646,
+2647,
+2648,
+2649,
+2650,
+2651,
+2652,
+2653,
+2654,
+2655,
+2656,
+2657,
+2658,
+2659,
+2660,
+2661,
+2662,
+2663,
+2664,
+2665,
+2666,
+2667,
+2668,
+2669,
+2670,
+2671,
+2672,
+2673,
+2674,
+2675,
+2676,
+2677,
+2678,
+2679,
+2680,
+2681,
+2682,
+2683,
+2684,
+2685,
+2686,
+2687,
+2688,
+2689,
+2690,
+2691,
+2692,
+2693,
+2694,
+2695,
+2696,
+2697,
+2698,
+2699,
+2700,
+2701,
+2702,
+2703,
+2704,
+2705,
+2706,
+2707,
+2708,
+2709,
+2710,
+2711,
+2712,
+2713,
+2714,
+2715,
+2716,
+2717,
+2718,
+2719,
+2720,
+2721,
+2722,
+2723,
+2724,
+2725,
+2726,
+2727,
+2728,
+2729,
+2730,
+2731,
+2732,
+2733,
+2734,
+2735,
+2736,
+2737,
+2738,
+2739,
+2740,
+2741,
+2742,
+2743,
+2744,
+2745,
+2746,
+2747,
+2748,
+2749,
+2750,
+2751,
+2752,
+2753,
+2754,
+2755,
+2756,
+2757,
+2758,
+2759,
+2760,
+2761,
+2762,
+2763,
+2764,
+2765,
+2766,
+2767,
+2768,
+2769,
+2770,
+2771,
+2772,
+2773,
+2774,
+2775,
+2776,
+2777,
+2778,
+2779,
+2780,
+2781,
+2782,
+2783,
+2784,
+2785,
+2786,
+2787,
+2788,
+2789,
+2790,
+2791,
+2792,
+2793,
+2794,
+2795,
+2796,
+2797,
+2798,
+2799,
+2800,
+2801,
+2802,
+2803,
+2804,
+2805,
+2806,
+2807,
+2808,
+2809,
+2810,
+2811,
+2812,
+2813,
+2814,
+2815,
+2816,
+2817,
+2818,
+2819,
+2820,
+2821,
+2822,
+2823,
+2824,
+2825,
+2826,
+2827,
+2828,
+2829,
+2830,
+2831,
+2832,
+2833,
+2834,
+2835,
+2836,
+2837,
+2838,
+2839,
+2840,
+2841,
+2842,
+2843,
+2844,
+2845,
+2846,
+2847,
+2848,
+2849,
+2850,
+2851,
+2852,
+2853,
+2854,
+2855,
+2856,
+2857,
+2858,
+2859,
+2860,
+2861,
+2862,
+2863,
+2864,
+2865,
+2866,
+2867,
+2868,
+2869,
+2870,
+2871,
+2872,
+2873,
+2874,
+2875,
+2876,
+2877,
+2878,
+2879,
+2880,
+2881,
+2882,
+2883,
+2884,
+2885,
+2886,
+2887,
+2888,
+2889,
+2890,
+2891,
+2892,
+2893,
+2894,
+2895,
+2896,
+2897,
+2898,
+2899,
+2900,
+2901,
+2902,
+2903,
+2904,
+2905,
+2906,
+2907,
+2908,
+2909,
+2910,
+2911,
+2912,
+2913,
+2914,
+2915,
+2916,
+2917,
+2918,
+2919,
+2920,
+2921,
+2922,
+2923,
+2924,
+2925,
+2926,
+2927,
+2928,
+2929,
+2930,
+2931,
+2932,
+2933,
+2934,
+2935,
+2936,
+2937,
+2938,
+2939,
+2940,
+2941,
+2942,
+2943,
+2944,
+2945,
+2946,
+2947,
+2948,
+2949,
+2950,
+2951,
+2952,
+2953,
+2954,
+2955,
+2956,
+2957,
+2958,
+2959,
+2960,
+2961,
+2962,
+2963,
+2964,
+2965,
+2966,
+2967,
+2968,
+2969,
+2970,
+2971,
+2972,
+2973,
+2974,
+2975,
+2976,
+2977,
+2978,
+2979,
+2980,
+2981,
+2982,
+2983,
+2984,
+2985,
+2986,
+2987,
+2988,
+2989,
+2990,
+2991,
+2992,
+2993,
+2994,
+2995,
+2996,
+2997,
+2998,
+2999,
+3000,
+3001,
+3002,
+3003,
+3004,
+3005,
+3006,
+3007,
+3008,
+3009,
+3010,
+3011,
+3012,
+3013,
+3014,
+3015,
+3016,
+3017,
+3018,
+3019,
+3020,
+3021,
+3022,
+3023,
+3024,
+3025,
+3026,
+3027,
+3028,
+3029,
+3030,
+3031,
+3032,
+3033,
+3034,
+3035,
+3036,
+3037,
+3038,
+3039,
+3040,
+3041,
+3042,
+3043,
+3044,
+3045,
+3046,
+3047,
+3048,
+3049,
+3050,
+3051,
+3052,
+3053,
+3054,
+3055,
+3056,
+3057,
+3058,
+3059,
+3060,
+3061,
+3062,
+3063,
+3064,
+3065,
+3066,
+3067,
+3068,
+3069,
+3070,
+3071,
+3072,
+3073,
+3074,
+3075,
+3076,
+3077,
+3078,
+3079,
+3080,
+3081,
+3082,
+3083,
+3084,
+3085,
+3086,
+3087,
+3088,
+3089,
+3090,
+3091,
+3092,
+3093,
+3094,
+3095,
+3096,
+3097,
+3098,
+3099,
+3100,
+3101,
+3102,
+3103,
+3104,
+3105,
+3106,
+3107,
+3108,
+3109,
+3110,
+3111,
+3112,
+3113,
+3114,
+3115,
+3116,
+3117,
+3118,
+3119,
+3120,
+3121,
+3122,
+3123,
+3124,
+3125,
+3126,
+3127,
+3128,
+3129,
+3130,
+3131,
+3132,
+3133,
+3134,
+3135,
+3136,
+3137,
+3138,
+3139,
+3140,
+3141,
+3142,
+3143,
+3144,
+3145,
+3146,
+3147,
+3148,
+3149,
+3150,
+3151,
+3152,
+3153,
+3154,
+3155,
+3156,
+3157,
+3158,
+3159,
+3160,
+3161,
+3162,
+3163,
+3164,
+3165,
+3166,
+3167,
+3168,
+3169,
+3170,
+3171,
+3172,
+3173,
+3174,
+3175,
+3176,
+3177,
+3178,
+3179,
+3180,
+3181,
+3182,
+3183,
+3184,
+3185,
+3186,
+3187,
+3188,
+3189,
+3190,
+3191,
+3192,
+3193,
+3194,
+3195,
+3196,
+3197,
+3198,
+3199,
+3200,
+3201,
+3202,
+3203,
+3204,
+3205,
+3206,
+3207,
+3208,
+3209,
+3210,
+3211,
+3212,
+3213,
+3214,
+3215,
+3216,
+3217,
+3218,
+3219,
+3220,
+3221,
+3222,
+3223,
+3224,
+3225,
+3226,
+3227,
+3228,
+3229,
+3230,
+3231,
+3232,
+3233,
+3234,
+3235,
+3236,
+3237,
+3238,
+3239,
+3240,
+3241,
+3242,
+3243,
+3244,
+3245,
+3246,
+3247,
+3248,
+3249,
+3250,
+3251,
+3252,
+3253,
+3254,
+3255,
+3256,
+3257,
+3258,
+3259,
+3260,
+3261,
+3262,
+3263,
+3264,
+3265,
+3266,
+3267,
+3268,
+3269,
+3270,
+3271,
+3272,
+3273,
+3274,
+3275,
+3276,
+3277,
+3278,
+3279,
+3280,
+3281,
+3282,
+3283,
+3284,
+3285,
+3286,
+3287,
+3288,
+3289,
+3290,
+3291,
+3292,
+3293,
+3294,
+3295,
+3296,
+3297,
+3298,
+3299,
+3300,
+3301,
+3302,
+3303,
+3304,
+3305,
+3306,
+3307,
+3308,
+3309,
+3310,
+3311,
+3312,
+3313,
+3314,
+3315,
+3316,
+3317,
+3318,
+3319,
+3320,
+3321,
+3322,
+3323,
+3324,
+3325,
+3326,
+3327,
+3328,
+3329,
+3330,
+3331,
+3332,
+3333,
+3334,
+3335,
+3336,
+3337,
+3338,
+3339,
+3340,
+3341,
+3342,
+3343,
+3344,
+3345,
+3346,
+3347,
+3348,
+3349,
+3350,
+3351,
+3352,
+3353,
+3354,
+3355,
+3356,
+3357,
+3358,
+3359,
+3360,
+3361,
+3362,
+3363,
+3364,
+3365,
+3366,
+3367,
+3368,
+3369,
+3370,
+3371,
+3372,
+3373,
+3374,
+3375,
+3376,
+3377,
+3378,
+3379,
+3380,
+3381,
+3382,
+3383,
+3384,
+3385,
+3386,
+3387,
+3388,
+3389,
+3390,
+3391,
+3392,
+3393,
+3394,
+3395,
+3396,
+3397,
+3398,
+3399,
+3400,
+3401,
+3402,
+3403,
+3404,
+3405,
+3406,
+3407,
+3408,
+3409,
+3410,
+3411,
+3412,
+3413,
+3414,
+3415,
+3416,
+3417,
+3418,
+3419,
+3420,
+3421,
+3422,
+3423,
+3424,
+3425,
+3426,
+3427,
+3428,
+3429,
+3430,
+3431,
+3432,
+3433,
+3434,
+3435,
+3436,
+3437,
+3438,
+3439,
+3440,
+3441,
+3442,
+3443,
+3444,
+3445,
+3446,
+3447,
+3448,
+3449,
+3450,
+3451,
+3452,
+3453,
+3454,
+3455,
+3456,
+3457,
+3458,
+3459,
+3460,
+3461,
+3462,
+3463,
+3464,
+3465,
+3466,
+3467,
+3468,
+3469,
+3470,
+3471,
+3472,
+3473,
+3474,
+3475,
+3476,
+3477,
+3478,
+3479,
+3480,
+3481,
+3482,
+3483,
+3484,
+3485,
+3486,
+3487,
+3488,
+3489,
+3490,
+3491,
+3492,
+3493,
+3494,
+3495,
+3496,
+3497,
+3498,
+3499,
+3500,
+3501,
+3502,
+3503,
+3504,
+3505,
+3506,
+3507,
+3508,
+3509,
+3510,
+3511,
+3512,
+3513,
+3514,
+3515,
+3516,
+3517,
+3518,
+3519,
+3520,
+3521,
+3522,
+3523,
+3524,
+3525,
+3526,
+3527,
+3528,
+3529,
+3530,
+3531,
+3532,
+3533,
+3534,
+3535,
+3536,
+3537,
+3538,
+3539,
+3540,
+3541,
+3542,
+3543,
+3544,
+3545,
+3546,
+3547,
+3548,
+3549,
+3550,
+3551,
+3552,
+3553,
+3554,
+3555,
+3556,
+3557,
+3558,
+3559,
+3560,
+3561,
+3562,
+3563,
+3564,
+3565,
+3566,
+3567,
+3568,
+3569,
+3570,
+3571,
+3572,
+3573,
+3574,
+3575,
+3576,
+3577,
+3578,
+3579,
+3580,
+3581,
+3582,
+3583,
+3584,
+3585,
+3586,
+3587,
+3588,
+3589,
+3590,
+3591,
+3592,
+3593,
+3594,
+3595,
+3596,
+3597,
+3598,
+3599,
+3600,
+3601,
+3602,
+3603,
+3604,
+3605,
+3606,
+3607,
+3608,
+3609,
+3610,
+3611,
+3612,
+3613,
+3614,
+3615,
+3616,
+3617,
+3618,
+3619,
+3620,
+3621,
+3622,
+3623,
+3624,
+3625,
+3626,
+3627,
+3628,
+3629,
+3630,
+3631,
+3632,
+3633,
+3634,
+3635,
+3636,
+3637,
+3638,
+3639,
+3640,
+3641,
+3642,
+3643,
+3644,
+3645,
+3646,
+3647,
+3648,
+3649,
+3650,
+3651,
+3652,
+3653,
+3654,
+3655,
+3656,
+3657,
+3658,
+3659,
+3660,
+3661,
+3662,
+3663,
+3664,
+3665,
+3666,
+3667,
+3668,
+3669,
+3670,
+3671,
+3672,
+3673,
+3674,
+3675,
+3676,
+3677,
+3678,
+3679,
+3680,
+3681,
+3682,
+3683,
+3684,
+3685,
+3686,
+3687,
+3688,
+3689,
+3690,
+3691,
+3692,
+3693,
+3694,
+3695,
+3696,
+3697,
+3698,
+3699,
+3700,
+3701,
+3702,
+3703,
+3704,
+3705,
+3706,
+3707,
+3708,
+3709,
+3710,
+3711,
+3712,
+3713,
+3714,
+3715,
+3716,
+3717,
+3718,
+3719,
+3720,
+3721,
+3722,
+3723,
+3724,
+3725,
+3726,
+3727,
+3728,
+3729,
+3730,
+3731,
+3732,
+3733,
+3734,
+3735,
+3736,
+3737,
+3738,
+3739,
+3740,
+3741,
+3742,
+3743,
+3744,
+3745,
+3746,
+3747,
+3748,
+3749,
+3750,
+3751,
+3752,
+3753,
+3754,
+3755,
+3756,
+3757,
+3758,
+3759,
+3760,
+3761,
+3762,
+3763,
+3764,
+3765,
+3766,
+3767,
+3768,
+3769,
+3770,
+3771,
+3772,
+3773,
+3774,
+3775,
+3776,
+3777,
+3778,
+3779,
+3780,
+3781,
+3782,
+3783,
+3784,
+3785,
+3786,
+3787,
+3788,
+3789,
+3790,
+3791,
+3792,
+3793,
+3794,
+3795,
+3796,
+3797,
+3798,
+3799,
+3800,
+3801,
+3802,
+3803,
+3804,
+3805,
+3806,
+3807,
+3808,
+3809,
+3810,
+3811,
+3812,
+3813,
+3814,
+3815,
+3816,
+3817,
+3818,
+3819,
+3820,
+3821,
+3822,
+3823,
+3824,
+3825,
+3826,
+3827,
+3828,
+3829,
+3830,
+3831,
+3832,
+3833,
+3834,
+3835,
+3836,
+3837,
+3838,
+3839,
+3840,
+3841,
+3842,
+3843,
+3844,
+3845,
+3846,
+3847,
+3848,
+3849,
+3850,
+3851,
+3852,
+3853,
+3854,
+3855,
+3856,
+3857,
+3858,
+3859,
+3860,
+3861,
+3862,
+3863,
+3864,
+3865,
+3866,
+3867,
+3868,
+3869,
+3870,
+3871,
+3872,
+3873,
+3874,
+3875,
+3876,
+3877,
+3878,
+3879,
+3880,
+3881,
+3882,
+3883,
+3884,
+3885,
+3886,
+3887,
+3888,
+3889,
+3890,
+3891,
+3892,
+3893,
+3894,
+3895,
+3896,
+3897,
+3898,
+3899,
+3900,
+3901,
+3902,
+3903,
+3904,
+3905,
+3906,
+3907,
+3908,
+3909,
+3910,
+3911,
+3912,
+3913,
+3914,
+3915,
+3916,
+3917,
+3918,
+3919,
+3920,
+3921,
+3922,
+3923,
+3924,
+3925,
+3926,
+3927,
+3928,
+3929,
+3930,
+3931,
+3932,
+3933,
+3934,
+3935,
+3936,
+3937,
+3938,
+3939,
+3940,
+3941,
+3942,
+3943,
+3944,
+3945,
+3946,
+3947,
+3948,
+3949,
+3950,
+3951,
+3952,
+3953,
+3954,
+3955,
+3956,
+3957,
+3958,
+3959,
+3960,
+3961,
+3962,
+3963,
+3964,
+3965,
+3966,
+3967,
+3968,
+3969,
+3970,
+3971,
+3972,
+3973,
+3974,
+3975,
+3976,
+3977,
+3978,
+3979,
+3980,
+3981,
+3982,
+3983,
+3984,
+3985,
+3986,
+3987,
+3988,
+3989,
+3990,
+3991,
+3992,
+3993,
+3994,
+3995,
+3996,
+3997,
+3998,
+3999,
+4000,
+4001,
+4002,
+4003,
+4004,
+4005,
+4006,
+4007,
+4008,
+4009,
+4010,
+4011,
+4012,
+4013,
+4014,
+4015,
+4016,
+4017,
+4018,
+4019,
+4020,
+4021,
+4022,
+4023,
+4024,
+4025,
+4026,
+4027,
+4028,
+4029,
+4030,
+4031,
+4032,
+4033,
+4034,
+4035,
+4036,
+4037,
+4038,
+4039,
+4040,
+4041,
+4042,
+4043,
+4044,
+4045,
+4046,
+4047,
+4048,
+4049,
+4050,
+4051,
+4052,
+4053,
+4054,
+4055,
+4056,
+4057,
+4058,
+4059,
+4060,
+4061,
+4062,
+4063,
+4064,
+4065,
+4066,
+4067,
+4068,
+4069,
+4070,
+4071,
+4072,
+4073,
+4074,
+4075,
+4076,
+4077,
+4078,
+4079,
+4080,
+4081,
+4082,
+4083,
+4084,
+4085,
+4086,
+4087,
+4088,
+4089,
+4090,
+4091,
+4092,
+4093,
+4094,
+4095,
+4096,
+4097,
+4098,
+4099,
+4100,
+4101,
+4102,
+4103,
+4104,
+4105,
+4106,
+4107,
+4108,
+4109,
+4110,
+4111,
+4112,
+4113,
+4114,
+4115,
+4116,
+4117,
+4118,
+4119,
+4120,
+4121,
+4122,
+4123,
+4124,
+4125,
+4126,
+4127,
+4128,
+4129,
+4130,
+4131,
+4132,
+4133,
+4134,
+4135,
+4136,
+4137,
+4138,
+4139,
+4140,
+4141,
+4142,
+4143,
+4144,
+4145,
+4146,
+4147,
+4148,
+4149,
+4150,
+4151,
+4152,
+4153,
+4154,
+4155,
+4156,
+4157,
+4158,
+4159,
+4160,
+4161,
+4162,
+4163,
+4164,
+4165,
+4166,
+4167,
+4168,
+4169,
+4170,
+4171,
+4172,
+4173,
+4174,
+4175,
+4176,
+4177,
+4178,
+4179,
+4180,
+4181,
+4182,
+4183,
+4184,
+4185,
+4186,
+4187,
+4188,
+4189,
+4190,
+4191,
+4192,
+4193,
+4194,
+4195,
+4196,
+4197,
+4198,
+4199,
+4200,
+4201,
+4202,
+4203,
+4204,
+4205,
+4206,
+4207,
+4208,
+4209,
+4210,
+4211,
+4212,
+4213,
+4214,
+4215,
+4216,
+4217,
+4218,
+4219,
+4220,
+4221,
+4222,
+4223,
+4224,
+4225,
+4226,
+4227,
+4228,
+4229,
+4230,
+4231,
+4232,
+4233,
+4234,
+4235,
+4236,
+4237,
+4238,
+4239,
+4240,
+4241,
+4242,
+4243,
+4244,
+4245,
+4246,
+4247,
+4248,
+4249,
+4250,
+4251,
+4252,
+4253,
+4254,
+4255,
+4256,
+4257,
+4258,
+4259,
+4260,
+4261,
+4262,
+4263,
+4264,
+4265,
+4266,
+4267,
+4268,
+4269,
+4270,
+4271,
+4272,
+4273,
+4274,
+4275,
+4276,
+4277,
+4278,
+4279,
+4280,
+4281,
+4282,
+4283,
+4284,
+4285,
+4286,
+4287,
+4288,
+4289,
+4290,
+4291,
+4292,
+4293,
+4294,
+4295,
+4296,
+4297,
+4298,
+4299,
+4300,
+4301,
+4302,
+4303,
+4304,
+4305,
+4306,
+4307,
+4308,
+4309,
+4310,
+4311,
+4312,
+4313,
+4314,
+4315,
+4316,
+4317,
+4318,
+4319,
+4320,
+4321,
+4322,
+4323,
+4324,
+4325,
+4326,
+4327,
+4328,
+4329,
+4330,
+4331,
+4332,
+4333,
+4334,
+4335,
+4336,
+4337,
+4338,
+4339,
+4340,
+4341,
+4342,
+4343,
+4344,
+4345,
+4346,
+4347,
+4348,
+4349,
+4350,
+4351,
+4352,
+4353,
+4354,
+4355,
+4356,
+4357,
+4358,
+4359,
+4360,
+4361,
+4362,
+4363,
+4364,
+4365,
+4366,
+4367,
+4368,
+4369,
+4370,
+4371,
+4372,
+4373,
+4374,
+4375,
+4376,
+4377,
+4378,
+4379,
+4380,
+4381,
+4382,
+4383,
+4384,
+4385,
+4386,
+4387,
+4388,
+4389,
+4390,
+4391,
+4392,
+4393,
+4394,
+4395,
+4396,
+4397,
+4398,
+4399,
+4400,
+4401,
+4402,
+4403,
+4404,
+4405,
+4406,
+4407,
+4408,
+4409,
+4410,
+4411,
+4412,
+4413,
+4414,
+4415,
+4416,
+4417,
+4418,
+4419,
+4420,
+4421,
+4422,
+4423,
+4424,
+4425,
+4426,
+4427,
+4428,
+4429,
+4430,
+4431,
+4432,
+4433,
+4434,
+4435,
+4436,
+4437,
+4438,
+4439,
+4440,
+4441,
+4442,
+4443,
+4444,
+4445,
+4446,
+4447,
+4448,
+4449,
+4450,
+4451,
+4452,
+4453,
+4454,
+4455,
+4456,
+4457,
+4458,
+4459,
+4460,
+4461,
+4462,
+4463,
+4464,
+4465,
+4466,
+4467,
+4468,
+4469,
+4470,
+4471,
+4472,
+4473,
+4474,
+4475,
+4476,
+4477,
+4478,
+4479,
+4480,
+4481,
+4482,
+4483,
+4484,
+4485,
+4486,
+4487,
+4488,
+4489,
+4490,
+4491,
+4492,
+4493,
+4494,
+4495,
+4496,
+4497,
+4498,
+4499,
+4500,
+4501,
+4502,
+4503,
+4504,
+4505,
+4506,
+4507,
+4508,
+4509,
+4510,
+4511,
+4512,
+4513,
+4514,
+4515,
+4516,
+4517,
+4518,
+4519,
+4520,
+4521,
+4522,
+4523,
+4524,
+4525,
+4526,
+4527,
+4528,
+4529,
+4530,
+4531,
+4532,
+4533,
+4534,
+4535,
+4536,
+4537,
+4538,
+4539,
+4540,
+4541,
+4542,
+4543,
+4544,
+4545,
+4546,
+4547,
+4548,
+4549,
+4550,
+4551,
+4552,
+4553,
+4554,
+4555,
+4556,
+4557,
+4558,
+4559,
+4560,
+4561,
+4562,
+4563,
+4564,
+4565,
+4566,
+4567,
+4568,
+4569,
+4570,
+4571,
+4572,
+4573,
+4574,
+4575,
+4576,
+4577,
+4578,
+4579,
+4580,
+4581,
+4582,
+4583,
+4584,
+4585,
+4586,
+4587,
+4588,
+4589,
+4590,
+4591,
+4592,
+4593,
+4594,
+4595,
+4596,
+4597,
+4598,
+4599,
+4600,
+4601,
+4602,
+4603,
+4604,
+4605,
+4606,
+4607,
+4608,
+4609,
+4610,
+4611,
+4612,
+4613,
+4614,
+4615,
+4616,
+4617,
+4618,
+4619,
+4620,
+4621,
+4622,
+4623,
+4624,
+4625,
+4626,
+4627,
+4628,
+4629,
+4630,
+4631,
+4632,
+4633,
+4634,
+4635,
+4636,
+4637,
+4638,
+4639,
+4640,
+4641,
+4642,
+4643,
+4644,
+4645,
+4646,
+4647,
+4648,
+4649,
+4650,
+4651,
+4652,
+4653,
+4654,
+4655,
+4656,
+4657,
+4658,
+4659,
+4660,
+4661,
+4662,
+4663,
+4664,
+4665,
+4666,
+4667,
+4668,
+4669,
+4670,
+4671,
+4672,
+4673,
+4674,
+4675,
+4676,
+4677,
+4678,
+4679,
+4680,
+4681,
+4682,
+4683,
+4684,
+4685,
+4686,
+4687,
+4688,
+4689,
+4690,
+4691,
+4692,
+4693,
+4694,
+4695,
+4696,
+4697,
+4698,
+4699,
+4700,
+4701,
+4702,
+4703,
+4704,
+4705,
+4706,
+4707,
+4708,
+4709,
+4710,
+4711,
+4712,
+4713,
+4714,
+4715,
+4716,
+4717,
+4718,
+4719,
+4720,
+4721,
+4722,
+4723,
+4724,
+4725,
+4726,
+4727,
+4728,
+4729,
+4730,
+4731,
+4732,
+4733,
+4734,
+4735,
+4736,
+4737,
+4738,
+4739,
+4740,
+4741,
+4742,
+4743,
+4744,
+4745,
+4746,
+4747,
+4748,
+4749,
+4750,
+4751,
+4752,
+4753,
+4754,
+4755,
+4756,
+4757,
+4758,
+4759,
+4760,
+4761,
+4762,
+4763,
+4764,
+4765,
+4766,
+4767,
+4768,
+4769,
+4770,
+4771,
+4772,
+4773,
+4774,
+4775,
+4776,
+4777,
+4778,
+4779,
+4780,
+4781,
+4782,
+4783,
+4784,
+4785,
+4786,
+4787,
+4788,
+4789,
+4790,
+4791,
+4792,
+4793,
+4794,
+4795,
+4796,
+4797,
+4798,
+4799,
+4800,
+4801,
+4802,
+4803,
+4804,
+4805,
+4806,
+4807,
+4808,
+4809,
+4810,
+4811,
+4812,
+4813,
+4814,
+4815,
+4816,
+4817,
+4818,
+4819,
+4820,
+4821,
+4822,
+4823,
+4824,
+4825,
+4826,
+4827,
+4828,
+4829,
+4830,
+4831,
+4832,
+4833,
+4834,
+4835,
+4836,
+4837,
+4838,
+4839,
+4840,
+4841,
+4842,
+4843,
+4844,
+4845,
+4846,
+4847,
+4848,
+4849,
+4850,
+4851,
+4852,
+4853,
+4854,
+4855,
+4856,
+4857,
+4858,
+4859,
+4860,
+4861,
+4862,
+4863,
+4864,
+4865,
+4866,
+4867,
+4868,
+4869,
+4870,
+4871,
+4872,
+4873,
+4874,
+4875,
+4876,
+4877,
+4878,
+4879,
+4880,
+4881,
+4882,
+4883,
+4884,
+4885,
+4886,
+4887,
+4888,
+4889,
+4890,
+4891,
+4892,
+4893,
+4894,
+4895,
+4896,
+4897,
+4898,
+4899,
+4900,
+4901,
+4902,
+4903,
+4904,
+4905,
+4906,
+4907,
+4908,
+4909,
+4910,
+4911,
+4912,
+4913,
+4914,
+4915,
+4916,
+4917,
+4918,
+4919,
+4920,
+4921,
+4922,
+4923,
+4924,
+4925,
+4926,
+4927,
+4928,
+4929,
+4930,
+4931,
+4932,
+4933,
+4934,
+4935,
+4936,
+4937,
+4938,
+4939,
+4940,
+4941,
+4942,
+4943,
+4944,
+4945,
+4946,
+4947,
+4948,
+4949,
+4950,
+4951,
+4952,
+4953,
+4954,
+4955,
+4956,
+4957,
+4958,
+4959,
+4960,
+4961,
+4962,
+4963,
+4964,
+4965,
+4966,
+4967,
+4968,
+4969,
+4970,
+4971,
+4972,
+4973,
+4974,
+4975,
+4976,
+4977,
+4978,
+4979,
+4980,
+4981,
+4982,
+4983,
+4984,
+4985,
+4986,
+4987,
+4988,
+4989,
+4990,
+4991,
+4992,
+4993,
+4994,
+4995,
+4996,
+4997,
+4998,
+4999,
+5000,
+5001,
+5002,
+5003,
+5004,
+5005,
+5006,
+5007,
+5008,
+5009,
+5010,
+5011,
+5012,
+5013,
+5014,
+5015,
+5016,
+5017,
+5018,
+5019,
+5020,
+5021,
+5022,
+5023,
+5024,
+5025,
+5026,
+5027,
+5028,
+5029,
+5030,
+5031,
+5032,
+5033,
+5034,
+5035,
+5036,
+5037,
+5038,
+5039,
+5040,
+5041,
+5042,
+5043,
+5044,
+5045,
+5046,
+5047,
+5048,
+5049,
+5050,
+5051,
+5052,
+5053,
+5054,
+5055,
+5056,
+5057,
+5058,
+5059,
+5060,
+5061,
+5062,
+5063,
+5064,
+5065,
+5066,
+5067,
+5068,
+5069,
+5070,
+5071,
+5072,
+5073,
+5074,
+5075,
+5076,
+5077,
+5078,
+5079,
+5080,
+5081,
+5082,
+5083,
+5084,
+5085,
+5086,
+5087,
+5088,
+5089,
+5090,
+5091,
+5092,
+5093,
+5094,
+5095,
+5096,
+5097,
+5098,
+5099,
+5100,
+5101,
+5102,
+5103,
+5104,
+5105,
+5106,
+5107,
+5108,
+5109,
+5110,
+5111,
+5112,
+5113,
+5114,
+5115,
+5116,
+5117,
+5118,
+5119,
+5120,
+5121,
+5122,
+5123,
+5124,
+5125,
+5126,
+5127,
+5128,
+5129,
+5130,
+5131,
+5132,
+5133,
+5134,
+5135,
+5136,
+5137,
+5138,
+5139,
+5140,
+5141,
+5142,
+5143,
+5144,
+5145,
+5146,
+5147,
+5148,
+5149,
+5150,
+5151,
+5152,
+5153,
+5154,
+5155,
+5156,
+5157,
+5158,
+5159,
+5160,
+5161,
+5162,
+5163,
+5164,
+5165,
+5166,
+5167,
+5168,
+5169,
+5170,
+5171,
+5172,
+5173,
+5174,
+5175,
+5176,
+5177,
+5178,
+5179,
+5180,
+5181,
+5182,
+5183,
+5184,
+5185,
+5186,
+5187,
+5188,
+5189,
+5190,
+5191,
+5192,
+5193,
+5194,
+5195,
+5196,
+5197,
+5198,
+5199,
+5200,
+5201,
+5202,
+5203,
+5204,
+5205,
+5206,
+5207,
+5208,
+5209,
+5210,
+5211,
+5212,
+5213,
+5214,
+5215,
+5216,
+5217,
+5218,
+5219,
+5220,
+5221,
+5222,
+5223,
+5224,
+5225,
+5226,
+5227,
+5228,
+5229,
+5230,
+5231,
+5232,
+5233,
+5234,
+5235,
+5236,
+5237,
+5238,
+5239,
+5240,
+5241,
+5242,
+5243,
+5244,
+5245,
+5246,
+5247,
+5248,
+5249,
+5250,
+5251,
+5252,
+5253,
+5254,
+5255,
+5256,
+5257,
+5258,
+5259,
+5260,
+5261,
+5262,
+5263,
+5264,
+5265,
+5266,
+5267,
+5268,
+5269,
+5270,
+5271,
+5272,
+5273,
+5274,
+5275,
+5276,
+5277,
+5278,
+5279,
+5280,
+5281,
+5282,
+5283,
+5284,
+5285,
+5286,
+5287,
+5288,
+5289,
+5290,
+5291,
+5292,
+5293,
+5294,
+5295,
+5296,
+5297,
+5298,
+5299,
+5300,
+5301,
+5302,
+5303,
+5304,
+5305,
+5306,
+5307,
+5308,
+5309,
+5310,
+5311,
+5312,
+5313,
+5314,
+5315,
+5316,
+5317,
+5318,
+5319,
+5320,
+5321,
+5322,
+5323,
+5324,
+5325,
+5326,
+5327,
+5328,
+5329,
+5330,
+5331,
+5332,
+5333,
+5334,
+5335,
+5336,
+5337,
+5338,
+5339,
+5340,
+5341,
+5342,
+5343,
+5344,
+5345,
+5346,
+5347,
+5348,
+5349,
+5350,
+5351,
+5352,
+5353,
+5354,
+5355,
+5356,
+5357,
+5358,
+5359,
+5360,
+5361,
+5362,
+5363,
+5364,
+5365,
+5366,
+5367,
+5368,
+5369,
+5370,
+5371,
+5372,
+5373,
+5374,
+5375,
+5376,
+5377,
+5378,
+5379,
+5380,
+5381,
+5382,
+5383,
+5384,
+5385,
+5386,
+5387,
+5388,
+5389,
+5390,
+5391,
+5392,
+5393,
+5394,
+5395,
+5396,
+5397,
+5398,
+5399,
+5400,
+5401,
+5402,
+5403,
+5404,
+5405,
+5406,
+5407,
+5408,
+5409,
+5410,
+5411,
+5412,
+5413,
+5414,
+5415,
+5416,
+5417,
+5418,
+5419,
+5420,
+5421,
+5422,
+5423,
+5424,
+5425,
+5426,
+5427,
+5428,
+5429,
+5430,
+5431,
+5432,
+5433,
+5434,
+5435,
+5436,
+5437,
+5438,
+5439,
+5440,
+5441,
+5442,
+5443,
+5444,
+5445,
+5446,
+5447,
+5448,
+5449,
+5450,
+5451,
+5452,
+5453,
+5454,
+5455,
+5456,
+5457,
+5458,
+5459,
+5460,
+5461,
+5462,
+5463,
+5464,
+5465,
+5466,
+5467,
+5468,
+5469,
+5470,
+5471,
+5472,
+5473,
+5474,
+5475,
+5476,
+5477,
+5478,
+5479,
+5480,
+5481,
+5482,
+5483,
+5484,
+5485,
+5486,
+5487,
+5488,
+5489,
+5490,
+5491,
+5492,
+5493,
+5494,
+5495,
+5496,
+5497,
+5498,
+5499,
+5500,
+5501,
+5502,
+5503,
+5504,
+5505,
+5506,
+5507,
+5508,
+5509,
+5510,
+5511,
+5512,
+5513,
+5514,
+5515,
+5516,
+5517,
+5518,
+5519,
+5520,
+5521,
+5522,
+5523,
+5524,
+5525,
+5526,
+5527,
+5528,
+5529,
+5530,
+5531,
+5532,
+5533,
+5534,
+5535,
+5536,
+5537,
+5538,
+5539,
+5540,
+5541,
+5542,
+5543,
+5544,
+5545,
+5546,
+5547,
+5548,
+5549,
+5550,
+5551,
+5552,
+5553,
+5554,
+5555,
+5556,
+5557,
+5558,
+5559,
+5560,
+5561,
+5562,
+5563,
+5564,
+5565,
+5566,
+5567,
+5568,
+5569,
+5570,
+5571,
+5572,
+5573,
+5574,
+5575,
+5576,
+5577,
+5578,
+5579,
+5580,
+5581,
+5582,
+5583,
+5584,
+5585,
+5586,
+5587,
+5588,
+5589,
+5590,
+5591,
+5592,
+5593,
+5594,
+5595,
+5596,
+5597,
+5598,
+5599,
+5600,
+5601,
+5602,
+5603,
+5604,
+5605,
+5606,
+5607,
+5608,
+5609,
+5610,
+5611,
+5612,
+5613,
+5614,
+5615,
+5616,
+5617,
+5618,
+5619,
+5620,
+5621,
+5622,
+5623,
+5624,
+5625,
+5626,
+5627,
+5628,
+5629,
+5630,
+5631,
+5632,
+5633,
+5634,
+5635,
+5636,
+5637,
+5638,
+5639,
+5640,
+5641,
+5642,
+5643,
+5644,
+5645,
+5646,
+5647,
+5648,
+5649,
+5650,
+5651,
+5652,
+5653,
+5654,
+5655,
+5656,
+5657,
+5658,
+5659,
+5660,
+5661,
+5662,
+5663,
+5664,
+5665,
+5666,
+5667,
+5668,
+5669,
+5670,
+5671,
+5672,
+5673,
+5674,
+5675,
+5676,
+5677,
+5678,
+5679,
+5680,
+5681,
+5682,
+5683,
+5684,
+5685,
+5686,
+5687,
+5688,
+5689,
+5690,
+5691,
+5692,
+5693,
+5694,
+5695,
+5696,
+5697,
+5698,
+5699,
+5700,
+5701,
+5702,
+5703,
+5704,
+5705,
+5706,
+5707,
+5708,
+5709,
+5710,
+5711,
+5712,
+5713,
+5714,
+5715,
+5716,
+5717,
+5718,
+5719,
+5720,
+5721,
+5722,
+5723,
+5724,
+5725,
+5726,
+5727,
+5728,
+5729,
+5730,
+5731,
+5732,
+5733,
+5734,
+5735,
+5736,
+5737,
+5738,
+5739,
+5740,
+5741,
+5742,
+5743,
+5744,
+5745,
+5746,
+5747,
+5748,
+5749,
+5750,
+5751,
+5752,
+5753,
+5754,
+5755,
+5756,
+5757,
+5758,
+5759,
+5760,
+5761,
+5762,
+5763,
+5764,
+5765,
+5766,
+5767,
+5768,
+5769,
+5770,
+5771,
+5772,
+5773,
+5774,
+5775,
+5776,
+5777,
+5778,
+5779,
+5780,
+5781,
+5782,
+5783,
+5784,
+5785,
+5786,
+5787,
+5788,
+5789,
+5790,
+5791,
+5792,
+5793,
+5794,
+5795,
+5796,
+5797,
+5798,
+5799,
+5800,
+5801,
+5802,
+5803,
+5804,
+5805,
+5806,
+5807,
+5808,
+5809,
+5810,
+5811,
+5812,
+5813,
+5814,
+5815,
+5816,
+5817,
+5818,
+5819,
+5820,
+5821,
+5822,
+5823,
+5824,
+5825,
+5826,
+5827,
+5828,
+5829,
+5830,
+5831,
+5832,
+5833,
+5834,
+5835,
+5836,
+5837,
+5838,
+5839,
+5840,
+5841,
+5842,
+5843,
+5844,
+5845,
+5846,
+5847,
+5848,
+5849,
+5850,
+5851,
+5852,
+5853,
+5854,
+5855,
+5856,
+5857,
+5858,
+5859,
+5860,
+5861,
+5862,
+5863,
+5864,
+5865,
+5866,
+5867,
+5868,
+5869,
+5870,
+5871,
+5872,
+5873,
+5874,
+5875,
+5876,
+5877,
+5878,
+5879,
+5880,
+5881,
+5882,
+5883,
+5884,
+5885,
+5886,
+5887,
+5888,
+5889,
+5890,
+5891,
+5892,
+5893,
+5894,
+5895,
+5896,
+5897,
+5898,
+5899,
+5900,
+5901,
+5902,
+5903,
+5904,
+5905,
+5906,
+5907,
+5908,
+5909,
+5910,
+5911,
+5912,
+5913,
+5914,
+5915,
+5916,
+5917,
+5918,
+5919,
+5920,
+5921,
+5922,
+5923,
+5924,
+5925,
+5926,
+5927,
+5928,
+5929,
+5930,
+5931,
+5932,
+5933,
+5934,
+5935,
+5936,
+5937,
+5938,
+5939,
+5940,
+5941,
+5942,
+5943,
+5944,
+5945,
+5946,
+5947,
+5948,
+5949,
+5950,
+5951,
+5952,
+5953,
+5954,
+5955,
+5956,
+5957,
+5958,
+5959,
+5960,
+5961,
+5962,
+5963,
+5964,
+5965,
+5966,
+5967,
+5968,
+5969,
+5970,
+5971,
+5972,
+5973,
+5974,
+5975,
+5976,
+5977,
+5978,
+5979,
+5980,
+5981,
+5982,
+5983,
+5984,
+5985,
+5986,
+5987,
+5988,
+5989,
+5990,
+5991,
+5992,
+5993,
+5994,
+5995,
+5996,
+5997,
+5998,
+5999,
+6000,
+6001,
+6002,
+6003,
+6004,
+6005,
+6006,
+6007,
+6008,
+6009,
+6010,
+6011,
+6012,
+6013,
+6014,
+6015,
+6016,
+6017,
+6018,
+6019,
+6020,
+6021,
+6022,
+6023,
+6024,
+6025,
+6026,
+6027,
+6028,
+6029,
+6030,
+6031,
+6032,
+6033,
+6034,
+6035,
+6036,
+6037,
+6038,
+6039,
+6040,
+6041,
+6042,
+6043,
+6044,
+6045,
+6046,
+6047,
+6048,
+6049,
+6050,
+6051,
+6052,
+6053,
+6054,
+6055,
+6056,
+6057,
+6058,
+6059,
+6060,
+6061,
+6062,
+6063,
+6064,
+6065,
+6066,
+6067,
+6068,
+6069,
+6070,
+6071,
+6072,
+6073,
+6074,
+6075,
+6076,
+6077,
+6078,
+6079,
+6080,
+6081,
+6082,
+6083,
+6084,
+6085,
+6086,
+6087,
+6088,
+6089,
+6090,
+6091,
+6092,
+6093,
+6094,
+6095,
+6096,
+6097,
+6098,
+6099,
+6100,
+6101,
+6102,
+6103,
+6104,
+6105,
+6106,
+6107,
+6108,
+6109,
+6110,
+6111,
+6112,
+6113,
+6114,
+6115,
+6116,
+6117,
+6118,
+6119,
+6120,
+6121,
+6122,
+6123,
+6124,
+6125,
+6126,
+6127,
+6128,
+6129,
+6130,
+6131,
+6132,
+6133,
+6134,
+6135,
+6136,
+6137,
+6138,
+6139,
+6140,
+6141,
+6142,
+6143,
+6144,
+6145,
+6146,
+6147,
+6148,
+6149,
+6150,
+6151,
+6152,
+6153,
+6154,
+6155,
+6156,
+6157,
+6158,
+6159,
+6160,
+6161,
+6162,
+6163,
+6164,
+6165,
+6166,
+6167,
+6168,
+6169,
+6170,
+6171,
+6172,
+6173,
+6174,
+6175,
+6176,
+6177,
+6178,
+6179,
+6180,
+6181,
+6182,
+6183,
+6184,
+6185,
+6186,
+6187,
+6188,
+6189,
+6190,
+6191,
+6192,
+6193,
+6194,
+6195,
+6196,
+6197,
+6198,
+6199,
+6200,
+6201,
+6202,
+6203,
+6204,
+6205,
+6206,
+6207,
+6208,
+6209,
+6210,
+6211,
+6212,
+6213,
+6214,
+6215,
+6216,
+6217,
+6218,
+6219,
+6220,
+6221,
+6222,
+6223,
+6224,
+6225,
+6226,
+6227,
+6228,
+6229,
+6230,
+6231,
+6232,
+6233,
+6234,
+6235,
+6236,
+6237,
+6238,
+6239,
+6240,
+6241,
+6242,
+6243,
+6244,
+6245,
+6246,
+6247,
+6248,
+6249,
+6250,
+6251,
+6252,
+6253,
+6254,
+6255,
+6256,
+6257,
+6258,
+6259,
+6260,
+6261,
+6262,
+6263,
+6264,
+6265,
+6266,
+6267,
+6268,
+6269,
+6270,
+6271,
+6272,
+6273,
+6274,
+6275,
+6276,
+6277,
+6278,
+6279,
+6280,
+6281,
+6282,
+6283,
+6284,
+6285,
+6286,
+6287,
+6288,
+6289,
+6290,
+6291,
+6292,
+6293,
+6294,
+6295,
+6296,
+6297,
+6298,
+6299,
+6300,
+6301,
+6302,
+6303,
+6304,
+6305,
+6306,
+6307,
+6308,
+6309,
+6310,
+6311,
+6312,
+6313,
+6314,
+6315,
+6316,
+6317,
+6318,
+6319,
+6320,
+6321,
+6322,
+6323,
+6324,
+6325,
+6326,
+6327,
+6328,
+6329,
+6330,
+6331,
+6332,
+6333,
+6334,
+6335,
+6336,
+6337,
+6338,
+6339,
+6340,
+6341,
+6342,
+6343,
+6344,
+6345,
+6346,
+6347,
+6348,
+6349,
+6350,
+6351,
+6352,
+6353,
+6354,
+6355,
+6356,
+6357,
+6358,
+6359,
+6360,
+6361,
+6362,
+6363,
+6364,
+6365,
+6366,
+6367,
+6368,
+6369,
+6370,
+6371,
+6372,
+6373,
+6374,
+6375,
+6376,
+6377,
+6378,
+6379,
+6380,
+6381,
+6382,
+6383,
+6384,
+6385,
+6386,
+6387,
+6388,
+6389,
+6390,
+6391,
+6392,
+6393,
+6394,
+6395,
+6396,
+6397,
+6398,
+6399,
+6400,
+6401,
+6402,
+6403,
+6404,
+6405,
+6406,
+6407,
+6408,
+6409,
+6410,
+6411,
+6412,
+6413,
+6414,
+6415,
+6416,
+6417,
+6418,
+6419,
+6420,
+6421,
+6422,
+6423,
+6424,
+6425,
+6426,
+6427,
+6428,
+6429,
+6430,
+6431,
+6432,
+6433,
+6434,
+6435,
+6436,
+6437,
+6438,
+6439,
+6440,
+6441,
+6442,
+6443,
+6444,
+6445,
+6446,
+6447,
+6448,
+6449,
+6450,
+6451,
+6452,
+6453,
+6454,
+6455,
+6456,
+6457,
+6458,
+6459,
+6460,
+6461,
+6462,
+6463,
+6464,
+6465,
+6466,
+6467,
+6468,
+6469,
+6470,
+6471,
+6472,
+6473,
+6474,
+6475,
+6476,
+6477,
+6478,
+6479,
+6480,
+6481,
+6482,
+6483,
+6484,
+6485,
+6486,
+6487,
+6488,
+6489,
+6490,
+6491,
+6492,
+6493,
+6494,
+6495,
+6496,
+6497,
+6498,
+6499,
+6500,
+6501,
+6502,
+6503,
+6504,
+6505,
+6506,
+6507,
+6508,
+6509,
+6510,
+6511,
+6512,
+6513,
+6514,
+6515,
+6516,
+6517,
+6518,
+6519,
+6520,
+6521,
+6522,
+6523,
+6524,
+6525,
+6526,
+6527,
+6528,
+6529,
+6530,
+6531,
+6532,
+6533,
+6534,
+6535,
+6536,
+6537,
+6538,
+6539,
+6540,
+6541,
+6542,
+6543,
+6544,
+6545,
+6546,
+6547,
+6548,
+6549,
+6550,
+6551,
+6552,
+6553,
+6554,
+6555,
+6556,
+6557,
+6558,
+6559,
+6560,
+6561,
+6562,
+6563,
+6564,
+6565,
+6566,
+6567,
+6568,
+6569,
+6570,
+6571,
+6572,
+6573,
+6574,
+6575,
+6576,
+6577,
+6578,
+6579,
+6580,
+6581,
+6582,
+6583,
+6584,
+6585,
+6586,
+6587,
+6588,
+6589,
+6590,
+6591,
+6592,
+6593,
+6594,
+6595,
+6596,
+6597,
+6598,
+6599,
+6600,
+6601,
+6602,
+6603,
+6604,
+6605,
+6606,
+6607,
+6608,
+6609,
+6610,
+6611,
+6612,
+6613,
+6614,
+6615,
+6616,
+6617,
+6618,
+6619,
+6620,
+6621,
+6622,
+6623,
+6624,
+6625,
+6626,
+6627,
+6628,
+6629,
+6630,
+6631,
+6632,
+6633,
+6634,
+6635,
+6636,
+6637,
+6638,
+6639,
+6640,
+6641,
+6642,
+6643,
+6644,
+6645,
+6646,
+6647,
+6648,
+6649,
+6650,
+6651,
+6652,
+6653,
+6654,
+6655,
+6656,
+6657,
+6658,
+6659,
+6660,
+6661,
+6662,
+6663,
+6664,
+6665,
+6666,
+6667,
+6668,
+6669,
+6670,
+6671,
+6672,
+6673,
+6674,
+6675,
+6676,
+6677,
+6678,
+6679,
+6680,
+6681,
+6682,
+6683,
+6684,
+6685,
+6686,
+6687,
+6688,
+6689,
+6690,
+6691,
+6692,
+6693,
+6694,
+6695,
+6696,
+6697,
+6698,
+6699,
+6700,
+6701,
+6702,
+6703,
+6704,
+6705,
+6706,
+6707,
+6708,
+6709,
+6710,
+6711,
+6712,
+6713,
+6714,
+6715,
+6716,
+6717,
+6718,
+6719,
+6720,
+6721,
+6722,
+6723,
+6724,
+6725,
+6726,
+6727,
+6728,
+6729,
+6730,
+6731,
+6732,
+6733,
+6734,
+6735,
+6736,
+6737,
+6738,
+6739,
+6740,
+6741,
+6742,
+6743,
+6744,
+6745,
+6746,
+6747,
+6748,
+6749,
+6750,
+6751,
+6752,
+6753,
+6754,
+6755,
+6756,
+6757,
+6758,
+6759,
+6760,
+6761,
+6762,
+6763,
+6764,
+6765,
+6766,
+6767,
+6768,
+6769,
+6770,
+6771,
+6772,
+6773,
+6774,
+6775,
+6776,
+6777,
+6778,
+6779,
+6780,
+6781,
+6782,
+6783,
+6784,
+6785,
+6786,
+6787,
+6788,
+6789,
+6790,
+6791,
+6792,
+6793,
+6794,
+6795,
+6796,
+6797,
+6798,
+6799,
+6800,
+6801,
+6802,
+6803,
+6804,
+6805,
+6806,
+6807,
+6808,
+6809,
+6810,
+6811,
+6812,
+6813,
+6814,
+6815,
+6816,
+6817,
+6818,
+6819,
+6820,
+6821,
+6822,
+6823,
+6824,
+6825,
+6826,
+6827,
+6828,
+6829,
+6830,
+6831,
+6832,
+6833,
+6834,
+6835,
+6836,
+6837,
+6838,
+6839,
+6840,
+6841,
+6842,
+6843,
+6844,
+6845,
+6846,
+6847,
+6848,
+6849,
+6850,
+6851,
+6852,
+6853,
+6854,
+6855,
+6856,
+6857,
+6858,
+6859,
+6860,
+6861,
+6862,
+6863,
+6864,
+6865,
+6866,
+6867,
+6868,
+6869,
+6870,
+6871,
+6872,
+6873,
+6874,
+6875,
+6876,
+6877,
+6878,
+6879,
+6880,
+6881,
+6882,
+6883,
+6884,
+6885,
+6886,
+6887,
+6888,
+6889,
+6890,
+6891,
+6892,
+6893,
+6894,
+6895,
+6896,
+6897,
+6898,
+6899,
+6900,
+6901,
+6902,
+6903,
+6904,
+6905,
+6906,
+6907,
+6908,
+6909,
+6910,
+6911,
+6912,
+6913,
+6914,
+6915,
+6916,
+6917,
+6918,
+6919,
+6920,
+6921,
+6922,
+6923,
+6924,
+6925,
+6926,
+6927,
+6928,
+6929,
+6930,
+6931,
+6932,
+6933,
+6934,
+6935,
+6936,
+6937,
+6938,
+6939,
+6940,
+6941,
+6942,
+6943,
+6944,
+6945,
+6946,
+6947,
+6948,
+6949,
+6950,
+6951,
+6952,
+6953,
+6954,
+6955,
+6956,
+6957,
+6958,
+6959,
+6960,
+6961,
+6962,
+6963,
+6964,
+6965,
+6966,
+6967,
+6968,
+6969,
+6970,
+6971,
+6972,
+6973,
+6974,
+6975,
+6976,
+6977,
+6978,
+6979,
+6980,
+6981,
+6982,
+6983,
+6984,
+6985,
+6986,
+6987,
+6988,
+6989,
+6990,
+6991,
+6992,
+6993,
+6994,
+6995,
+6996,
+6997,
+6998,
+6999,
+7000,
+7001,
+7002,
+7003,
+7004,
+7005,
+7006,
+7007,
+7008,
+7009,
+7010,
+7011,
+7012,
+7013,
+7014,
+7015,
+7016,
+7017,
+7018,
+7019,
+7020,
+7021,
+7022,
+7023,
+7024,
+7025,
+7026,
+7027,
+7028,
+7029,
+7030,
+7031,
+7032,
+7033,
+7034,
+7035,
+7036,
+7037,
+7038,
+7039,
+7040,
+7041,
+7042,
+7043,
+7044,
+7045,
+7046,
+7047,
+7048,
+7049,
+7050,
+7051,
+7052,
+7053,
+7054,
+7055,
+7056,
+7057,
+7058,
+7059,
+7060,
+7061,
+7062,
+7063,
+7064,
+7065,
+7066,
+7067,
+7068,
+7069,
+7070,
+7071,
+7072,
+7073,
+7074,
+7075,
+7076,
+7077,
+7078,
+7079,
+7080,
+7081,
+7082,
+7083,
+7084,
+7085,
+7086,
+7087,
+7088,
+7089,
+7090,
+7091,
+7092,
+7093,
+7094,
+7095,
+7096,
+7097,
+7098,
+7099,
+7100,
+7101,
+7102,
+7103,
+7104,
+7105,
+7106,
+7107,
+7108,
+7109,
+7110,
+7111,
+7112,
+7113,
+7114,
+7115,
+7116,
+7117,
+7118,
+7119,
+7120,
+7121,
+7122,
+7123,
+7124,
+7125,
+7126,
+7127,
+7128,
+7129,
+7130,
+7131,
+7132,
+7133,
+7134,
+7135,
+7136,
+7137,
+7138,
+7139,
+7140,
+7141,
+7142,
+7143,
+7144,
+7145,
+7146,
+7147,
+7148,
+7149,
+7150,
+7151,
+7152,
+7153,
+7154,
+7155,
+7156,
+7157,
+7158,
+7159,
+7160,
+7161,
+7162,
+7163,
+7164,
+7165,
+7166,
+7167,
+7168,
+7169,
+7170,
+7171,
+7172,
+7173,
+7174,
+7175,
+7176,
+7177,
+7178,
+7179,
+7180,
+7181,
+7182,
+7183,
+7184,
+7185,
+7186,
+7187,
+7188,
+7189,
+7190,
+7191,
+7192,
+7193,
+7194,
+7195,
+7196,
+7197,
+7198,
+7199,
+7200,
+7201,
+7202,
+7203,
+7204,
+7205,
+7206,
+7207,
+7208,
+7209,
+7210,
+7211,
+7212,
+7213,
+7214,
+7215,
+7216,
+7217,
+7218,
+7219,
+7220,
+7221,
+7222,
+7223,
+7224,
+7225,
+7226,
+7227,
+7228,
+7229,
+7230,
+7231,
+7232,
+7233,
+7234,
+7235,
+7236,
+7237,
+7238,
+7239,
+7240,
+7241,
+7242,
+7243,
+7244,
+7245,
+7246,
+7247,
+7248,
+7249,
+7250,
+7251,
+7252,
+7253,
+7254,
+7255,
+7256,
+7257,
+7258,
+7259,
+7260,
+7261,
+7262,
+7263,
+7264,
+7265,
+7266,
+7267,
+7268,
+7269,
+7270,
+7271,
+7272,
+7273,
+7274,
+7275,
+7276,
+7277,
+7278,
+7279,
+7280,
+7281,
+7282,
+7283,
+7284,
+7285,
+7286,
+7287,
+7288,
+7289,
+7290,
+7291,
+7292,
+7293,
+7294,
+7295,
+7296,
+7297,
+7298,
+7299,
+7300,
+7301,
+7302,
+7303,
+7304,
+7305,
+7306,
+7307,
+7308,
+7309,
+7310,
+7311,
+7312,
+7313,
+7314,
+7315,
+7316,
+7317,
+7318,
+7319,
+7320,
+7321,
+7322,
+7323,
+7324,
+7325,
+7326,
+7327,
+7328,
+7329,
+7330,
+7331,
+7332,
+7333,
+7334,
+7335,
+7336,
+7337,
+7338,
+7339,
+7340,
+7341,
+7342,
+7343,
+7344,
+7345,
+7346,
+7347,
+7348,
+7349,
+7350,
+7351,
+7352,
+7353,
+7354,
+7355,
+7356,
+7357,
+7358,
+7359,
+7360,
+7361,
+7362,
+7363,
+7364,
+7365,
+7366,
+7367,
+7368,
+7369,
+7370,
+7371,
+7372,
+7373,
+7374,
+7375,
+7376,
+7377,
+7378,
+7379,
+7380,
+7381,
+7382,
+7383,
+7384,
+7385,
+7386,
+7387,
+7388,
+7389,
+7390,
+7391,
+7392,
+7393,
+7394,
+7395,
+7396,
+7397,
+7398,
+7399,
+7400,
+7401,
+7402,
+7403,
+7404,
+7405,
+7406,
+7407,
+7408,
+7409,
+7410,
+7411,
+7412,
+7413,
+7414,
+7415,
+7416,
+7417,
+7418,
+7419,
+7420,
+7421,
+7422,
+7423,
+7424,
+7425,
+7426,
+7427,
+7428,
+7429,
+7430,
+7431,
+7432,
+7433,
+7434,
+7435,
+7436,
+7437,
+7438,
+7439,
+7440,
+7441,
+7442,
+7443,
+7444,
+7445,
+7446,
+7447,
+7448,
+7449,
+7450,
+7451,
+7452,
+7453,
+7454,
+7455,
+7456,
+7457,
+7458,
+7459,
+7460,
+7461,
+7462,
+7463,
+7464,
+7465,
+7466,
+7467,
+7468,
+7469,
+7470,
+7471,
+7472,
+7473,
+7474,
+7475,
+7476,
+7477,
+7478,
+7479,
+7480,
+7481,
+7482,
+7483,
+7484,
+7485,
+7486,
+7487,
+7488,
+7489,
+7490,
+7491,
+7492,
+7493,
+7494,
+7495,
+7496,
+7497,
+7498,
+7499,
+7500,
+7501,
+7502,
+7503,
+7504,
+7505,
+7506,
+7507,
+7508,
+7509,
+7510,
+7511,
+7512,
+7513,
+7514,
+7515,
+7516,
+7517,
+7518,
+7519,
+7520,
+7521,
+7522,
+7523,
+7524,
+7525,
+7526,
+7527,
+7528,
+7529,
+7530,
+7531,
+7532,
+7533,
+7534,
+7535,
+7536,
+7537,
+7538,
+7539,
+7540,
+7541,
+7542,
+7543,
+7544,
+7545,
+7546,
+7547,
+7548,
+7549,
+7550,
+7551,
+7552,
+7553,
+7554,
+7555,
+7556,
+7557,
+7558,
+7559,
+7560,
+7561,
+7562,
+7563,
+7564,
+7565,
+7566,
+7567,
+7568,
+7569,
+7570,
+7571,
+7572,
+7573,
+7574,
+7575,
+7576,
+7577,
+7578,
+7579,
+7580,
+7581,
+7582,
+7583,
+7584,
+7585,
+7586,
+7587,
+7588,
+7589,
+7590,
+7591,
+7592,
+7593,
+7594,
+7595,
+7596,
+7597,
+7598,
+7599,
+7600,
+7601,
+7602,
+7603,
+7604,
+7605,
+7606,
+7607,
+7608,
+7609,
+7610,
+7611,
+7612,
+7613,
+7614,
+7615,
+7616,
+7617,
+7618,
+7619,
+7620,
+7621,
+7622,
+7623,
+7624,
+7625,
+7626,
+7627,
+7628,
+7629,
+7630,
+7631,
+7632,
+7633,
+7634,
+7635,
+7636,
+7637,
+7638,
+7639,
+7640,
+7641,
+7642,
+7643,
+7644,
+7645,
+7646,
+7647,
+7648,
+7649,
+7650,
+7651,
+7652,
+7653,
+7654,
+7655,
+7656,
+7657,
+7658,
+7659,
+7660,
+7661,
+7662,
+7663,
+7664,
+7665,
+7666,
+7667,
+7668,
+7669,
+7670,
+7671,
+7672,
+7673,
+7674,
+7675,
+7676,
+7677,
+7678,
+7679,
+7680,
+7681,
+7682,
+7683,
+7684,
+7685,
+7686,
+7687,
+7688,
+7689,
+7690,
+7691,
+7692,
+7693,
+7694,
+7695,
+7696,
+7697,
+7698,
+7699,
+7700,
+7701,
+7702,
+7703,
+7704,
+7705,
+7706,
+7707,
+7708,
+7709,
+7710,
+7711,
+7712,
+7713,
+7714,
+7715,
+7716,
+7717,
+7718,
+7719,
+7720,
+7721,
+7722,
+7723,
+7724,
+7725,
+7726,
+7727,
+7728,
+7729,
+7730,
+7731,
+7732,
+7733,
+7734,
+7735,
+7736,
+7737,
+7738,
+7739,
+7740,
+7741,
+7742,
+7743,
+7744,
+7745,
+7746,
+7747,
+7748,
+7749,
+7750,
+7751,
+7752,
+7753,
+7754,
+7755,
+7756,
+7757,
+7758,
+7759,
+7760,
+7761,
+7762,
+7763,
+7764,
+7765,
+7766,
+7767,
+7768,
+7769,
+7770,
+7771,
+7772,
+7773,
+7774,
+7775,
+7776,
+7777,
+7778,
+7779,
+7780,
+7781,
+7782,
+7783,
+7784,
+7785,
+7786,
+7787,
+7788,
+7789,
+7790,
+7791,
+7792,
+7793,
+7794,
+7795,
+7796,
+7797,
+7798,
+7799,
+7800,
+7801,
+7802,
+7803,
+7804,
+7805,
+7806,
+7807,
+7808,
+7809,
+7810,
+7811,
+7812,
+7813,
+7814,
+7815,
+7816,
+7817,
+7818,
+7819,
+7820,
+7821,
+7822,
+7823,
+7824,
+7825,
+7826,
+7827,
+7828,
+7829,
+7830,
+7831,
+7832,
+7833,
+7834,
+7835,
+7836,
+7837,
+7838,
+7839,
+7840,
+7841,
+7842,
+7843,
+7844,
+7845,
+7846,
+7847,
+7848,
+7849,
+7850,
+7851,
+7852,
+7853,
+7854,
+7855,
+7856,
+7857,
+7858,
+7859,
+7860,
+7861,
+7862,
+7863,
+7864,
+7865,
+7866,
+7867,
+7868,
+7869,
+7870,
+7871,
+7872,
+7873,
+7874,
+7875,
+7876,
+7877,
+7878,
+7879,
+7880,
+7881,
+7882,
+7883,
+7884,
+7885,
+7886,
+7887,
+7888,
+7889,
+7890,
+7891,
+7892,
+7893,
+7894,
+7895,
+7896,
+7897,
+7898,
+7899,
+7900,
+7901,
+7902,
+7903,
+7904,
+7905,
+7906,
+7907,
+7908,
+7909,
+7910,
+7911,
+7912,
+7913,
+7914,
+7915,
+7916,
+7917,
+7918,
+7919,
+7920,
+7921,
+7922,
+7923,
+7924,
+7925,
+7926,
+7927,
+7928,
+7929,
+7930,
+7931,
+7932,
+7933,
+7934,
+7935,
+7936,
+7937,
+7938,
+7939,
+7940,
+7941,
+7942,
+7943,
+7944,
+7945,
+7946,
+7947,
+7948,
+7949,
+7950,
+7951,
+7952,
+7953,
+7954,
+7955,
+7956,
+7957,
+7958,
+7959,
+7960,
+7961,
+7962,
+7963,
+7964,
+7965,
+7966,
+7967,
+7968,
+7969,
+7970,
+7971,
+7972,
+7973,
+7974,
+7975,
+7976,
+7977,
+7978,
+7979,
+7980,
+7981,
+7982,
+7983,
+7984,
+7985,
+7986,
+7987,
+7988,
+7989,
+7990,
+7991,
+7992,
+7993,
+7994,
+7995,
+7996,
+7997,
+7998,
+7999,
+8000,
+8001,
+8002,
+8003,
+8004,
+8005,
+8006,
+8007,
+8008,
+8009,
+8010,
+8011,
+8012,
+8013,
+8014,
+8015,
+8016,
+8017,
+8018,
+8019,
+8020,
+8021,
+8022,
+8023,
+8024,
+8025,
+8026,
+8027,
+8028,
+8029,
+8030,
+8031,
+8032,
+8033,
+8034,
+8035,
+8036,
+8037,
+8038,
+8039,
+8040,
+8041,
+8042,
+8043,
+8044,
+8045,
+8046,
+8047,
+8048,
+8049,
+8050,
+8051,
+8052,
+8053,
+8054,
+8055,
+8056,
+8057,
+8058,
+8059,
+8060,
+8061,
+8062,
+8063,
+8064,
+8065,
+8066,
+8067,
+8068,
+8069,
+8070,
+8071,
+8072,
+8073,
+8074,
+8075,
+8076,
+8077,
+8078,
+8079,
+8080,
+8081,
+8082,
+8083,
+8084,
+8085,
+8086,
+8087,
+8088,
+8089,
+8090,
+8091,
+8092,
+8093,
+8094,
+8095,
+8096,
+8097,
+8098,
+8099,
+8100,
+8101,
+8102,
+8103,
+8104,
+8105,
+8106,
+8107,
+8108,
+8109,
+8110,
+8111,
+8112,
+8113,
+8114,
+8115,
+8116,
+8117,
+8118,
+8119,
+8120,
+8121,
+8122,
+8123,
+8124,
+8125,
+8126,
+8127,
+8128,
+8129,
+8130,
+8131,
+8132,
+8133,
+8134,
+8135,
+8136,
+8137,
+8138,
+8139,
+8140,
+8141,
+8142,
+8143,
+8144,
+8145,
+8146,
+8147,
+8148,
+8149,
+8150,
+8151,
+8152,
+8153,
+8154,
+8155,
+8156,
+8157,
+8158,
+8159,
+8160,
+8161,
+8162,
+8163,
+8164,
+8165,
+8166,
+8167,
+8168,
+8169,
+8170,
+8171,
+8172,
+8173,
+8174,
+8175,
+8176,
+8177,
+8178,
+8179,
+8180,
+8181,
+8182,
+8183,
+8184,
+8185,
+8186,
+8187,
+8188,
+8189,
+8190,
+8191,
+8192,
+8193,
+8194,
+8195,
+8196,
+8197,
+8198,
+8199,
+8200,
+8201,
+8202,
+8203,
+8204,
+8205,
+8206,
+8207,
+8208,
+8209,
+8210,
+8211,
+8212,
+8213,
+8214,
+8215,
+8216,
+8217,
+8218,
+8219,
+8220,
+8221,
+8222,
+8223,
+8224,
+8225,
+8226,
+8227,
+8228,
+8229,
+8230,
+8231,
+8232,
+8233,
+8234,
+8235,
+8236,
+8237,
+8238,
+8239,
+8240,
+8241,
+8242,
+8243,
+8244,
+8245,
+8246,
+8247,
+8248,
+8249,
+8250,
+8251,
+8252,
+8253,
+8254,
+8255,
+8256,
+8257,
+8258,
+8259,
+8260,
+8261,
+8262,
+8263,
+8264,
+8265,
+8266,
+8267,
+8268,
+8269,
+8270,
+8271,
+8272,
+8273,
+8274,
+8275,
+8276,
+8277,
+8278,
+8279,
+8280,
+8281,
+8282,
+8283,
+8284,
+8285,
+8286,
+8287,
+8288,
+8289,
+8290,
+8291,
+8292,
+8293,
+8294,
+8295,
+8296,
+8297,
+8298,
+8299,
+8300,
+8301,
+8302,
+8303,
+8304,
+8305,
+8306,
+8307,
+8308,
+8309,
+8310,
+8311,
+8312,
+8313,
+8314,
+8315,
+8316,
+8317,
+8318,
+8319,
+8320,
+8321,
+8322,
+8323,
+8324,
+8325,
+8326,
+8327,
+8328,
+8329,
+8330,
+8331,
+8332,
+8333,
+8334,
+8335,
+8336,
+8337,
+8338,
+8339,
+8340,
+8341,
+8342,
+8343,
+8344,
+8345,
+8346,
+8347,
+8348,
+8349,
+8350,
+8351,
+8352,
+8353,
+8354,
+8355,
+8356,
+8357,
+8358,
+8359,
+8360,
+8361,
+8362,
+8363,
+8364,
+8365,
+8366,
+8367,
+8368,
+8369,
+8370,
+8371,
+8372,
+8373,
+8374,
+8375,
+8376,
+8377,
+8378,
+8379,
+8380,
+8381,
+8382,
+8383,
+8384,
+8385,
+8386,
+8387,
+8388,
+8389,
+8390,
+8391,
+8392,
+8393,
+8394,
+8395,
+8396,
+8397,
+8398,
+8399,
+8400,
+8401,
+8402,
+8403,
+8404,
+8405,
+8406,
+8407,
+8408,
+8409,
+8410,
+8411,
+8412,
+8413,
+8414,
+8415,
+8416,
+8417,
+8418,
+8419,
+8420,
+8421,
+8422,
+8423,
+8424,
+8425,
+8426,
+8427,
+8428,
+8429,
+8430,
+8431,
+8432,
+8433,
+8434,
+8435,
+8436,
+8437,
+8438,
+8439,
+8440,
+8441,
+8442,
+8443,
+8444,
+8445,
+8446,
+8447,
+8448,
+8449,
+8450,
+8451,
+8452,
+8453,
+8454,
+8455,
+8456,
+8457,
+8458,
+8459,
+8460,
+8461,
+8462,
+8463,
+8464,
+8465,
+8466,
+8467,
+8468,
+8469,
+8470,
+8471,
+8472,
+8473,
+8474,
+8475,
+8476,
+8477,
+8478,
+8479,
+8480,
+8481,
+8482,
+8483,
+8484,
+8485,
+8486,
+8487,
+8488,
+8489,
+8490,
+8491,
+8492,
+8493,
+8494,
+8495,
+8496,
+8497,
+8498,
+8499,
+8500,
+8501,
+8502,
+8503,
+8504,
+8505,
+8506,
+8507,
+8508,
+8509,
+8510,
+8511,
+8512,
+8513,
+8514,
+8515,
+8516,
+8517,
+8518,
+8519,
+8520,
+8521,
+8522,
+8523,
+8524,
+8525,
+8526,
+8527,
+8528,
+8529,
+8530,
+8531,
+8532,
+8533,
+8534,
+8535,
+8536,
+8537,
+8538,
+8539,
+8540,
+8541,
+8542,
+8543,
+8544,
+8545,
+8546,
+8547,
+8548,
+8549,
+8550,
+8551,
+8552,
+8553,
+8554,
+8555,
+8556,
+8557,
+8558,
+8559,
+8560,
+8561,
+8562,
+8563,
+8564,
+8565,
+8566,
+8567,
+8568,
+8569,
+8570,
+8571,
+8572,
+8573,
+8574,
+8575,
+8576,
+8577,
+8578,
+8579,
+8580,
+8581,
+8582,
+8583,
+8584,
+8585,
+8586,
+8587,
+8588,
+8589,
+8590,
+8591,
+8592,
+8593,
+8594,
+8595,
+8596,
+8597,
+8598,
+8599,
+8600,
+8601,
+8602,
+8603,
+8604,
+8605,
+8606,
+8607,
+8608,
+8609,
+8610,
+8611,
+8612,
+8613,
+8614,
+8615,
+8616,
+8617,
+8618,
+8619,
+8620,
+8621,
+8622,
+8623,
+8624,
+8625,
+8626,
+8627,
+8628,
+8629,
+8630,
+8631,
+8632,
+8633,
+8634,
+8635,
+8636,
+8637,
+8638,
+8639,
+8640,
+8641,
+8642,
+8643,
+8644,
+8645,
+8646,
+8647,
+8648,
+8649,
+8650,
+8651,
+8652,
+8653,
+8654,
+8655,
+8656,
+8657,
+8658,
+8659,
+8660,
+8661,
+8662,
+8663,
+8664,
+8665,
+8666,
+8667,
+8668,
+8669,
+8670,
+8671,
+8672,
+8673,
+8674,
+8675,
+8676,
+8677,
+8678,
+8679,
+8680,
+8681,
+8682,
+8683,
+8684,
+8685,
+8686,
+8687,
+8688,
+8689,
+8690,
+8691,
+8692,
+8693,
+8694,
+8695,
+8696,
+8697,
+8698,
+8699,
+8700,
+8701,
+8702,
+8703,
+8704,
+8705,
+8706,
+8707,
+8708,
+8709,
+8710,
+8711,
+8712,
+8713,
+8714,
+8715,
+8716,
+8717,
+8718,
+8719,
+8720,
+8721,
+8722,
+8723,
+8724,
+8725,
+8726,
+8727,
+8728,
+8729,
+8730,
+8731,
+8732,
+8733,
+8734,
+8735,
+8736,
+8737,
+8738,
+8739,
+8740,
+8741,
+8742,
+8743,
+8744,
+8745,
+8746,
+8747,
+8748,
+8749,
+8750,
+8751,
+8752,
+8753,
+8754,
+8755,
+8756,
+8757,
+8758,
+8759,
+8760,
+8761,
+8762,
+8763,
+8764,
+8765,
+8766,
+8767,
+8768,
+8769,
+8770,
+8771,
+8772,
+8773,
+8774,
+8775,
+8776,
+8777,
+8778,
+8779,
+8780,
+8781,
+8782,
+8783,
+8784,
+8785,
+8786,
+8787,
+8788,
+8789,
+8790,
+8791,
+8792,
+8793,
+8794,
+8795,
+8796,
+8797,
+8798,
+8799,
+8800,
+8801,
+8802,
+8803,
+8804,
+8805,
+8806,
+8807,
+8808,
+8809,
+8810,
+8811,
+8812,
+8813,
+8814,
+8815,
+8816,
+8817,
+8818,
+8819,
+8820,
+8821,
+8822,
+8823,
+8824,
+8825,
+8826,
+8827,
+8828,
+8829,
+8830,
+8831,
+8832,
+8833,
+8834,
+8835,
+8836,
+8837,
+8838,
+8839,
+8840,
+8841,
+8842,
+8843,
+8844,
+8845,
+8846,
+8847,
+8848,
+8849,
+8850,
+8851,
+8852,
+8853,
+8854,
+8855,
+8856,
+8857,
+8858,
+8859,
+8860,
+8861,
+8862,
+8863,
+8864,
+8865,
+8866,
+8867,
+8868,
+8869,
+8870,
+8871,
+8872,
+8873,
+8874,
+8875,
+8876,
+8877,
+8878,
+8879,
+8880,
+8881,
+8882,
+8883,
+8884,
+8885,
+8886,
+8887,
+8888,
+8889,
+8890,
+8891,
+8892,
+8893,
+8894,
+8895,
+8896,
+8897,
+8898,
+8899,
+8900,
+8901,
+8902,
+8903,
+8904,
+8905,
+8906,
+8907,
+8908,
+8909,
+8910,
+8911,
+8912,
+8913,
+8914,
+8915,
+8916,
+8917,
+8918,
+8919,
+8920,
+8921,
+8922,
+8923,
+8924,
+8925,
+8926,
+8927,
+8928,
+8929,
+8930,
+8931,
+8932,
+8933,
+8934,
+8935,
+8936,
+8937,
+8938,
+8939,
+8940,
+8941,
+8942,
+8943,
+8944,
+8945,
+8946,
+8947,
+8948,
+8949,
+8950,
+8951,
+8952,
+8953,
+8954,
+8955,
+8956,
+8957,
+8958,
+8959,
+8960,
+8961,
+8962,
+8963,
+8964,
+8965,
+8966,
+8967,
+8968,
+8969,
+8970,
+8971,
+8972,
+8973,
+8974,
+8975,
+8976,
+8977,
+8978,
+8979,
+8980,
+8981,
+8982,
+8983,
+8984,
+8985,
+8986,
+8987,
+8988,
+8989,
+8990,
+8991,
+8992,
+8993,
+8994,
+8995,
+8996,
+8997,
+8998,
+8999,
+9000,
+9001,
+9002,
+9003,
+9004,
+9005,
+9006,
+9007,
+9008,
+9009,
+9010,
+9011,
+9012,
+9013,
+9014,
+9015,
+9016,
+9017,
+9018,
+9019,
+9020,
+9021,
+9022,
+9023,
+9024,
+9025,
+9026,
+9027,
+9028,
+9029,
+9030,
+9031,
+9032,
+9033,
+9034,
+9035,
+9036,
+9037,
+9038,
+9039,
+9040,
+9041,
+9042,
+9043,
+9044,
+9045,
+9046,
+9047,
+9048,
+9049,
+9050,
+9051,
+9052,
+9053,
+9054,
+9055,
+9056,
+9057,
+9058,
+9059,
+9060,
+9061,
+9062,
+9063,
+9064,
+9065,
+9066,
+9067,
+9068,
+9069,
+9070,
+9071,
+9072,
+9073,
+9074,
+9075,
+9076,
+9077,
+9078,
+9079,
+9080,
+9081,
+9082,
+9083,
+9084,
+9085,
+9086,
+9087,
+9088,
+9089,
+9090,
+9091,
+9092,
+9093,
+9094,
+9095,
+9096,
+9097,
+9098,
+9099,
+9100,
+9101,
+9102,
+9103,
+9104,
+9105,
+9106,
+9107,
+9108,
+9109,
+9110,
+9111,
+9112,
+9113,
+9114,
+9115,
+9116,
+9117,
+9118,
+9119,
+9120,
+9121,
+9122,
+9123,
+9124,
+9125,
+9126,
+9127,
+9128,
+9129,
+9130,
+9131,
+9132,
+9133,
+9134,
+9135,
+9136,
+9137,
+9138,
+9139,
+9140,
+9141,
+9142,
+9143,
+9144,
+9145,
+9146,
+9147,
+9148,
+9149,
+9150,
+9151,
+9152,
+9153,
+9154,
+9155,
+9156,
+9157,
+9158,
+9159,
+9160,
+9161,
+9162,
+9163,
+9164,
+9165,
+9166,
+9167,
+9168,
+9169,
+9170,
+9171,
+9172,
+9173,
+9174,
+9175,
+9176,
+9177,
+9178,
+9179,
+9180,
+9181,
+9182,
+9183,
+9184,
+9185,
+9186,
+9187,
+9188,
+9189,
+9190,
+9191,
+9192,
+9193,
+9194,
+9195,
+9196,
+9197,
+9198,
+9199,
+9200,
+9201,
+9202,
+9203,
+9204,
+9205,
+9206,
+9207,
+9208,
+9209,
+9210,
+9211,
+9212,
+9213,
+9214,
+9215,
+9216,
+9217,
+9218,
+9219,
+9220,
+9221,
+9222,
+9223,
+9224,
+9225,
+9226,
+9227,
+9228,
+9229,
+9230,
+9231,
+9232,
+9233,
+9234,
+9235,
+9236,
+9237,
+9238,
+9239,
+9240,
+9241,
+9242,
+9243,
+9244,
+9245,
+9246,
+9247,
+9248,
+9249,
+9250,
+9251,
+9252,
+9253,
+9254,
+9255,
+9256,
+9257,
+9258,
+9259,
+9260,
+9261,
+9262,
+9263,
+9264,
+9265,
+9266,
+9267,
+9268,
+9269,
+9270,
+9271,
+9272,
+9273,
+9274,
+9275,
+9276,
+9277,
+9278,
+9279,
+9280,
+9281,
+9282,
+9283,
+9284,
+9285,
+9286,
+9287,
+9288,
+9289,
+9290,
+9291,
+9292,
+9293,
+9294,
+9295,
+9296,
+9297,
+9298,
+9299,
+9300,
+9301,
+9302,
+9303,
+9304,
+9305,
+9306,
+9307,
+9308,
+9309,
+9310,
+9311,
+9312,
+9313,
+9314,
+9315,
+9316,
+9317,
+9318,
+9319,
+9320,
+9321,
+9322,
+9323,
+9324,
+9325,
+9326,
+9327,
+9328,
+9329,
+9330,
+9331,
+9332,
+9333,
+9334,
+9335,
+9336,
+9337,
+9338,
+9339,
+9340,
+9341,
+9342,
+9343,
+9344,
+9345,
+9346,
+9347,
+9348,
+9349,
+9350,
+9351,
+9352,
+9353,
+9354,
+9355,
+9356,
+9357,
+9358,
+9359,
+9360,
+9361,
+9362,
+9363,
+9364,
+9365,
+9366,
+9367,
+9368,
+9369,
+9370,
+9371,
+9372,
+9373,
+9374,
+9375,
+9376,
+9377,
+9378,
+9379,
+9380,
+9381,
+9382,
+9383,
+9384,
+9385,
+9386,
+9387,
+9388,
+9389,
+9390,
+9391,
+9392,
+9393,
+9394,
+9395,
+9396,
+9397,
+9398,
+9399,
+9400,
+9401,
+9402,
+9403,
+9404,
+9405,
+9406,
+9407,
+9408,
+9409,
+9410,
+9411,
+9412,
+9413,
+9414,
+9415,
+9416,
+9417,
+9418,
+9419,
+9420,
+9421,
+9422,
+9423,
+9424,
+9425,
+9426,
+9427,
+9428,
+9429,
+9430,
+9431,
+9432,
+9433,
+9434,
+9435,
+9436,
+9437,
+9438,
+9439,
+9440,
+9441,
+9442,
+9443,
+9444,
+9445,
+9446,
+9447,
+9448,
+9449,
+9450,
+9451,
+9452,
+9453,
+9454,
+9455,
+9456,
+9457,
+9458,
+9459,
+9460,
+9461,
+9462,
+9463,
+9464,
+9465,
+9466,
+9467,
+9468,
+9469,
+9470,
+9471,
+9472,
+9473,
+9474,
+9475,
+9476,
+9477,
+9478,
+9479,
+9480,
+9481,
+9482,
+9483,
+9484,
+9485,
+9486,
+9487,
+9488,
+9489,
+9490,
+9491,
+9492,
+9493,
+9494,
+9495,
+9496,
+9497,
+9498,
+9499,
+9500,
+9501,
+9502,
+9503,
+9504,
+9505,
+9506,
+9507,
+9508,
+9509,
+9510,
+9511,
+9512,
+9513,
+9514,
+9515,
+9516,
+9517,
+9518,
+9519,
+9520,
+9521,
+9522,
+9523,
+9524,
+9525,
+9526,
+9527,
+9528,
+9529,
+9530,
+9531,
+9532,
+9533,
+9534,
+9535,
+9536,
+9537,
+9538,
+9539,
+9540,
+9541,
+9542,
+9543,
+9544,
+9545,
+9546,
+9547,
+9548,
+9549,
+9550,
+9551,
+9552,
+9553,
+9554,
+9555,
+9556,
+9557,
+9558,
+9559,
+9560,
+9561,
+9562,
+9563,
+9564,
+9565,
+9566,
+9567,
+9568,
+9569,
+9570,
+9571,
+9572,
+9573,
+9574,
+9575,
+9576,
+9577,
+9578,
+9579,
+9580,
+9581,
+9582,
+9583,
+9584,
+9585,
+9586,
+9587,
+9588,
+9589,
+9590,
+9591,
+9592,
+9593,
+9594,
+9595,
+9596,
+9597,
+9598,
+9599,
+9600,
+9601,
+9602,
+9603,
+9604,
+9605,
+9606,
+9607,
+9608,
+9609,
+9610,
+9611,
+9612,
+9613,
+9614,
+9615,
+9616,
+9617,
+9618,
+9619,
+9620,
+9621,
+9622,
+9623,
+9624,
+9625,
+9626,
+9627,
+9628,
+9629,
+9630,
+9631,
+9632,
+9633,
+9634,
+9635,
+9636,
+9637,
+9638,
+9639,
+9640,
+9641,
+9642,
+9643,
+9644,
+9645,
+9646,
+9647,
+9648,
+9649,
+9650,
+9651,
+9652,
+9653,
+9654,
+9655,
+9656,
+9657,
+9658,
+9659,
+9660,
+9661,
+9662,
+9663,
+9664,
+9665,
+9666,
+9667,
+9668,
+9669,
+9670,
+9671,
+9672,
+9673,
+9674,
+9675,
+9676,
+9677,
+9678,
+9679,
+9680,
+9681,
+9682,
+9683,
+9684,
+9685,
+9686,
+9687,
+9688,
+9689,
+9690,
+9691,
+9692,
+9693,
+9694,
+9695,
+9696,
+9697,
+9698,
+9699,
+9700,
+9701,
+9702,
+9703,
+9704,
+9705,
+9706,
+9707,
+9708,
+9709,
+9710,
+9711,
+9712,
+9713,
+9714,
+9715,
+9716,
+9717,
+9718,
+9719,
+9720,
+9721,
+9722,
+9723,
+9724,
+9725,
+9726,
+9727,
+9728,
+9729,
+9730,
+9731,
+9732,
+9733,
+9734,
+9735,
+9736,
+9737,
+9738,
+9739,
+9740,
+9741,
+9742,
+9743,
+9744,
+9745,
+9746,
+9747,
+9748,
+9749,
+9750,
+9751,
+9752,
+9753,
+9754,
+9755,
+9756,
+9757,
+9758,
+9759,
+9760,
+9761,
+9762,
+9763,
+9764,
+9765,
+9766,
+9767,
+9768,
+9769,
+9770,
+9771,
+9772,
+9773,
+9774,
+9775,
+9776,
+9777,
+9778,
+9779,
+9780,
+9781,
+9782,
+9783,
+9784,
+9785,
+9786,
+9787,
+9788,
+9789,
+9790,
+9791,
+9792,
+9793,
+9794,
+9795,
+9796,
+9797,
+9798,
+9799,
+9800,
+9801,
+9802,
+9803,
+9804,
+9805,
+9806,
+9807,
+9808,
+9809,
+9810,
+9811,
+9812,
+9813,
+9814,
+9815,
+9816,
+9817,
+9818,
+9819,
+9820,
+9821,
+9822,
+9823,
+9824,
+9825,
+9826,
+9827,
+9828,
+9829,
+9830,
+9831,
+9832,
+9833,
+9834,
+9835,
+9836,
+9837,
+9838,
+9839,
+9840,
+9841,
+9842,
+9843,
+9844,
+9845,
+9846,
+9847,
+9848,
+9849,
+9850,
+9851,
+9852,
+9853,
+9854,
+9855,
+9856,
+9857,
+9858,
+9859,
+9860,
+9861,
+9862,
+9863,
+9864,
+9865,
+9866,
+9867,
+9868,
+9869,
+9870,
+9871,
+9872,
+9873,
+9874,
+9875,
+9876,
+9877,
+9878,
+9879,
+9880,
+9881,
+9882,
+9883,
+9884,
+9885,
+9886,
+9887,
+9888,
+9889,
+9890,
+9891,
+9892,
+9893,
+9894,
+9895,
+9896,
+9897,
+9898,
+9899,
+9900,
+9901,
+9902,
+9903,
+9904,
+9905,
+9906,
+9907,
+9908,
+9909,
+9910,
+9911,
+9912,
+9913,
+9914,
+9915,
+9916,
+9917,
+9918,
+9919,
+9920,
+9921,
+9922,
+9923,
+9924,
+9925,
+9926,
+9927,
+9928,
+9929,
+9930,
+9931,
+9932,
+9933,
+9934,
+9935,
+9936,
+9937,
+9938,
+9939,
+9940,
+9941,
+9942,
+9943,
+9944,
+9945,
+9946,
+9947,
+9948,
+9949,
+9950,
+9951,
+9952,
+9953,
+9954,
+9955,
+9956,
+9957,
+9958,
+9959,
+9960,
+9961,
+9962,
+9963,
+9964,
+9965,
+9966,
+9967,
+9968,
+9969,
+9970,
+9971,
+9972,
+9973,
+9974,
+9975,
+9976,
+9977,
+9978,
+9979,
+9980,
+9981,
+9982,
+9983,
+9984,
+9985,
+9986,
+9987,
+9988,
+9989,
+9990,
+9991,
+9992,
+9993,
+9994,
+9995,
+9996,
+9997,
+9998,
+9999
+];
+
+var largeDouble = [
+0.1,
+1.1,
+2.1,
+3.1,
+4.1,
+5.1,
+6.1,
+7.1,
+8.1,
+9.1,
+10.1,
+11.1,
+12.1,
+13.1,
+14.1,
+15.1,
+16.1,
+17.1,
+18.1,
+19.1,
+20.1,
+21.1,
+22.1,
+23.1,
+24.1,
+25.1,
+26.1,
+27.1,
+28.1,
+29.1,
+30.1,
+31.1,
+32.1,
+33.1,
+34.1,
+35.1,
+36.1,
+37.1,
+38.1,
+39.1,
+40.1,
+41.1,
+42.1,
+43.1,
+44.1,
+45.1,
+46.1,
+47.1,
+48.1,
+49.1,
+50.1,
+51.1,
+52.1,
+53.1,
+54.1,
+55.1,
+56.1,
+57.1,
+58.1,
+59.1,
+60.1,
+61.1,
+62.1,
+63.1,
+64.1,
+65.1,
+66.1,
+67.1,
+68.1,
+69.1,
+70.1,
+71.1,
+72.1,
+73.1,
+74.1,
+75.1,
+76.1,
+77.1,
+78.1,
+79.1,
+80.1,
+81.1,
+82.1,
+83.1,
+84.1,
+85.1,
+86.1,
+87.1,
+88.1,
+89.1,
+90.1,
+91.1,
+92.1,
+93.1,
+94.1,
+95.1,
+96.1,
+97.1,
+98.1,
+99.1,
+100.1,
+101.1,
+102.1,
+103.1,
+104.1,
+105.1,
+106.1,
+107.1,
+108.1,
+109.1,
+110.1,
+111.1,
+112.1,
+113.1,
+114.1,
+115.1,
+116.1,
+117.1,
+118.1,
+119.1,
+120.1,
+121.1,
+122.1,
+123.1,
+124.1,
+125.1,
+126.1,
+127.1,
+128.1,
+129.1,
+130.1,
+131.1,
+132.1,
+133.1,
+134.1,
+135.1,
+136.1,
+137.1,
+138.1,
+139.1,
+140.1,
+141.1,
+142.1,
+143.1,
+144.1,
+145.1,
+146.1,
+147.1,
+148.1,
+149.1,
+150.1,
+151.1,
+152.1,
+153.1,
+154.1,
+155.1,
+156.1,
+157.1,
+158.1,
+159.1,
+160.1,
+161.1,
+162.1,
+163.1,
+164.1,
+165.1,
+166.1,
+167.1,
+168.1,
+169.1,
+170.1,
+171.1,
+172.1,
+173.1,
+174.1,
+175.1,
+176.1,
+177.1,
+178.1,
+179.1,
+180.1,
+181.1,
+182.1,
+183.1,
+184.1,
+185.1,
+186.1,
+187.1,
+188.1,
+189.1,
+190.1,
+191.1,
+192.1,
+193.1,
+194.1,
+195.1,
+196.1,
+197.1,
+198.1,
+199.1,
+200.1,
+201.1,
+202.1,
+203.1,
+204.1,
+205.1,
+206.1,
+207.1,
+208.1,
+209.1,
+210.1,
+211.1,
+212.1,
+213.1,
+214.1,
+215.1,
+216.1,
+217.1,
+218.1,
+219.1,
+220.1,
+221.1,
+222.1,
+223.1,
+224.1,
+225.1,
+226.1,
+227.1,
+228.1,
+229.1,
+230.1,
+231.1,
+232.1,
+233.1,
+234.1,
+235.1,
+236.1,
+237.1,
+238.1,
+239.1,
+240.1,
+241.1,
+242.1,
+243.1,
+244.1,
+245.1,
+246.1,
+247.1,
+248.1,
+249.1,
+250.1,
+251.1,
+252.1,
+253.1,
+254.1,
+255.1,
+256.1,
+257.1,
+258.1,
+259.1,
+260.1,
+261.1,
+262.1,
+263.1,
+264.1,
+265.1,
+266.1,
+267.1,
+268.1,
+269.1,
+270.1,
+271.1,
+272.1,
+273.1,
+274.1,
+275.1,
+276.1,
+277.1,
+278.1,
+279.1,
+280.1,
+281.1,
+282.1,
+283.1,
+284.1,
+285.1,
+286.1,
+287.1,
+288.1,
+289.1,
+290.1,
+291.1,
+292.1,
+293.1,
+294.1,
+295.1,
+296.1,
+297.1,
+298.1,
+299.1,
+300.1,
+301.1,
+302.1,
+303.1,
+304.1,
+305.1,
+306.1,
+307.1,
+308.1,
+309.1,
+310.1,
+311.1,
+312.1,
+313.1,
+314.1,
+315.1,
+316.1,
+317.1,
+318.1,
+319.1,
+320.1,
+321.1,
+322.1,
+323.1,
+324.1,
+325.1,
+326.1,
+327.1,
+328.1,
+329.1,
+330.1,
+331.1,
+332.1,
+333.1,
+334.1,
+335.1,
+336.1,
+337.1,
+338.1,
+339.1,
+340.1,
+341.1,
+342.1,
+343.1,
+344.1,
+345.1,
+346.1,
+347.1,
+348.1,
+349.1,
+350.1,
+351.1,
+352.1,
+353.1,
+354.1,
+355.1,
+356.1,
+357.1,
+358.1,
+359.1,
+360.1,
+361.1,
+362.1,
+363.1,
+364.1,
+365.1,
+366.1,
+367.1,
+368.1,
+369.1,
+370.1,
+371.1,
+372.1,
+373.1,
+374.1,
+375.1,
+376.1,
+377.1,
+378.1,
+379.1,
+380.1,
+381.1,
+382.1,
+383.1,
+384.1,
+385.1,
+386.1,
+387.1,
+388.1,
+389.1,
+390.1,
+391.1,
+392.1,
+393.1,
+394.1,
+395.1,
+396.1,
+397.1,
+398.1,
+399.1,
+400.1,
+401.1,
+402.1,
+403.1,
+404.1,
+405.1,
+406.1,
+407.1,
+408.1,
+409.1,
+410.1,
+411.1,
+412.1,
+413.1,
+414.1,
+415.1,
+416.1,
+417.1,
+418.1,
+419.1,
+420.1,
+421.1,
+422.1,
+423.1,
+424.1,
+425.1,
+426.1,
+427.1,
+428.1,
+429.1,
+430.1,
+431.1,
+432.1,
+433.1,
+434.1,
+435.1,
+436.1,
+437.1,
+438.1,
+439.1,
+440.1,
+441.1,
+442.1,
+443.1,
+444.1,
+445.1,
+446.1,
+447.1,
+448.1,
+449.1,
+450.1,
+451.1,
+452.1,
+453.1,
+454.1,
+455.1,
+456.1,
+457.1,
+458.1,
+459.1,
+460.1,
+461.1,
+462.1,
+463.1,
+464.1,
+465.1,
+466.1,
+467.1,
+468.1,
+469.1,
+470.1,
+471.1,
+472.1,
+473.1,
+474.1,
+475.1,
+476.1,
+477.1,
+478.1,
+479.1,
+480.1,
+481.1,
+482.1,
+483.1,
+484.1,
+485.1,
+486.1,
+487.1,
+488.1,
+489.1,
+490.1,
+491.1,
+492.1,
+493.1,
+494.1,
+495.1,
+496.1,
+497.1,
+498.1,
+499.1,
+500.1,
+501.1,
+502.1,
+503.1,
+504.1,
+505.1,
+506.1,
+507.1,
+508.1,
+509.1,
+510.1,
+511.1,
+512.1,
+513.1,
+514.1,
+515.1,
+516.1,
+517.1,
+518.1,
+519.1,
+520.1,
+521.1,
+522.1,
+523.1,
+524.1,
+525.1,
+526.1,
+527.1,
+528.1,
+529.1,
+530.1,
+531.1,
+532.1,
+533.1,
+534.1,
+535.1,
+536.1,
+537.1,
+538.1,
+539.1,
+540.1,
+541.1,
+542.1,
+543.1,
+544.1,
+545.1,
+546.1,
+547.1,
+548.1,
+549.1,
+550.1,
+551.1,
+552.1,
+553.1,
+554.1,
+555.1,
+556.1,
+557.1,
+558.1,
+559.1,
+560.1,
+561.1,
+562.1,
+563.1,
+564.1,
+565.1,
+566.1,
+567.1,
+568.1,
+569.1,
+570.1,
+571.1,
+572.1,
+573.1,
+574.1,
+575.1,
+576.1,
+577.1,
+578.1,
+579.1,
+580.1,
+581.1,
+582.1,
+583.1,
+584.1,
+585.1,
+586.1,
+587.1,
+588.1,
+589.1,
+590.1,
+591.1,
+592.1,
+593.1,
+594.1,
+595.1,
+596.1,
+597.1,
+598.1,
+599.1,
+600.1,
+601.1,
+602.1,
+603.1,
+604.1,
+605.1,
+606.1,
+607.1,
+608.1,
+609.1,
+610.1,
+611.1,
+612.1,
+613.1,
+614.1,
+615.1,
+616.1,
+617.1,
+618.1,
+619.1,
+620.1,
+621.1,
+622.1,
+623.1,
+624.1,
+625.1,
+626.1,
+627.1,
+628.1,
+629.1,
+630.1,
+631.1,
+632.1,
+633.1,
+634.1,
+635.1,
+636.1,
+637.1,
+638.1,
+639.1,
+640.1,
+641.1,
+642.1,
+643.1,
+644.1,
+645.1,
+646.1,
+647.1,
+648.1,
+649.1,
+650.1,
+651.1,
+652.1,
+653.1,
+654.1,
+655.1,
+656.1,
+657.1,
+658.1,
+659.1,
+660.1,
+661.1,
+662.1,
+663.1,
+664.1,
+665.1,
+666.1,
+667.1,
+668.1,
+669.1,
+670.1,
+671.1,
+672.1,
+673.1,
+674.1,
+675.1,
+676.1,
+677.1,
+678.1,
+679.1,
+680.1,
+681.1,
+682.1,
+683.1,
+684.1,
+685.1,
+686.1,
+687.1,
+688.1,
+689.1,
+690.1,
+691.1,
+692.1,
+693.1,
+694.1,
+695.1,
+696.1,
+697.1,
+698.1,
+699.1,
+700.1,
+701.1,
+702.1,
+703.1,
+704.1,
+705.1,
+706.1,
+707.1,
+708.1,
+709.1,
+710.1,
+711.1,
+712.1,
+713.1,
+714.1,
+715.1,
+716.1,
+717.1,
+718.1,
+719.1,
+720.1,
+721.1,
+722.1,
+723.1,
+724.1,
+725.1,
+726.1,
+727.1,
+728.1,
+729.1,
+730.1,
+731.1,
+732.1,
+733.1,
+734.1,
+735.1,
+736.1,
+737.1,
+738.1,
+739.1,
+740.1,
+741.1,
+742.1,
+743.1,
+744.1,
+745.1,
+746.1,
+747.1,
+748.1,
+749.1,
+750.1,
+751.1,
+752.1,
+753.1,
+754.1,
+755.1,
+756.1,
+757.1,
+758.1,
+759.1,
+760.1,
+761.1,
+762.1,
+763.1,
+764.1,
+765.1,
+766.1,
+767.1,
+768.1,
+769.1,
+770.1,
+771.1,
+772.1,
+773.1,
+774.1,
+775.1,
+776.1,
+777.1,
+778.1,
+779.1,
+780.1,
+781.1,
+782.1,
+783.1,
+784.1,
+785.1,
+786.1,
+787.1,
+788.1,
+789.1,
+790.1,
+791.1,
+792.1,
+793.1,
+794.1,
+795.1,
+796.1,
+797.1,
+798.1,
+799.1,
+800.1,
+801.1,
+802.1,
+803.1,
+804.1,
+805.1,
+806.1,
+807.1,
+808.1,
+809.1,
+810.1,
+811.1,
+812.1,
+813.1,
+814.1,
+815.1,
+816.1,
+817.1,
+818.1,
+819.1,
+820.1,
+821.1,
+822.1,
+823.1,
+824.1,
+825.1,
+826.1,
+827.1,
+828.1,
+829.1,
+830.1,
+831.1,
+832.1,
+833.1,
+834.1,
+835.1,
+836.1,
+837.1,
+838.1,
+839.1,
+840.1,
+841.1,
+842.1,
+843.1,
+844.1,
+845.1,
+846.1,
+847.1,
+848.1,
+849.1,
+850.1,
+851.1,
+852.1,
+853.1,
+854.1,
+855.1,
+856.1,
+857.1,
+858.1,
+859.1,
+860.1,
+861.1,
+862.1,
+863.1,
+864.1,
+865.1,
+866.1,
+867.1,
+868.1,
+869.1,
+870.1,
+871.1,
+872.1,
+873.1,
+874.1,
+875.1,
+876.1,
+877.1,
+878.1,
+879.1,
+880.1,
+881.1,
+882.1,
+883.1,
+884.1,
+885.1,
+886.1,
+887.1,
+888.1,
+889.1,
+890.1,
+891.1,
+892.1,
+893.1,
+894.1,
+895.1,
+896.1,
+897.1,
+898.1,
+899.1,
+900.1,
+901.1,
+902.1,
+903.1,
+904.1,
+905.1,
+906.1,
+907.1,
+908.1,
+909.1,
+910.1,
+911.1,
+912.1,
+913.1,
+914.1,
+915.1,
+916.1,
+917.1,
+918.1,
+919.1,
+920.1,
+921.1,
+922.1,
+923.1,
+924.1,
+925.1,
+926.1,
+927.1,
+928.1,
+929.1,
+930.1,
+931.1,
+932.1,
+933.1,
+934.1,
+935.1,
+936.1,
+937.1,
+938.1,
+939.1,
+940.1,
+941.1,
+942.1,
+943.1,
+944.1,
+945.1,
+946.1,
+947.1,
+948.1,
+949.1,
+950.1,
+951.1,
+952.1,
+953.1,
+954.1,
+955.1,
+956.1,
+957.1,
+958.1,
+959.1,
+960.1,
+961.1,
+962.1,
+963.1,
+964.1,
+965.1,
+966.1,
+967.1,
+968.1,
+969.1,
+970.1,
+971.1,
+972.1,
+973.1,
+974.1,
+975.1,
+976.1,
+977.1,
+978.1,
+979.1,
+980.1,
+981.1,
+982.1,
+983.1,
+984.1,
+985.1,
+986.1,
+987.1,
+988.1,
+989.1,
+990.1,
+991.1,
+992.1,
+993.1,
+994.1,
+995.1,
+996.1,
+997.1,
+998.1,
+999.1,
+1000.1,
+1001.1,
+1002.1,
+1003.1,
+1004.1,
+1005.1,
+1006.1,
+1007.1,
+1008.1,
+1009.1,
+1010.1,
+1011.1,
+1012.1,
+1013.1,
+1014.1,
+1015.1,
+1016.1,
+1017.1,
+1018.1,
+1019.1,
+1020.1,
+1021.1,
+1022.1,
+1023.1,
+1024.1,
+1025.1,
+1026.1,
+1027.1,
+1028.1,
+1029.1,
+1030.1,
+1031.1,
+1032.1,
+1033.1,
+1034.1,
+1035.1,
+1036.1,
+1037.1,
+1038.1,
+1039.1,
+1040.1,
+1041.1,
+1042.1,
+1043.1,
+1044.1,
+1045.1,
+1046.1,
+1047.1,
+1048.1,
+1049.1,
+1050.1,
+1051.1,
+1052.1,
+1053.1,
+1054.1,
+1055.1,
+1056.1,
+1057.1,
+1058.1,
+1059.1,
+1060.1,
+1061.1,
+1062.1,
+1063.1,
+1064.1,
+1065.1,
+1066.1,
+1067.1,
+1068.1,
+1069.1,
+1070.1,
+1071.1,
+1072.1,
+1073.1,
+1074.1,
+1075.1,
+1076.1,
+1077.1,
+1078.1,
+1079.1,
+1080.1,
+1081.1,
+1082.1,
+1083.1,
+1084.1,
+1085.1,
+1086.1,
+1087.1,
+1088.1,
+1089.1,
+1090.1,
+1091.1,
+1092.1,
+1093.1,
+1094.1,
+1095.1,
+1096.1,
+1097.1,
+1098.1,
+1099.1,
+1100.1,
+1101.1,
+1102.1,
+1103.1,
+1104.1,
+1105.1,
+1106.1,
+1107.1,
+1108.1,
+1109.1,
+1110.1,
+1111.1,
+1112.1,
+1113.1,
+1114.1,
+1115.1,
+1116.1,
+1117.1,
+1118.1,
+1119.1,
+1120.1,
+1121.1,
+1122.1,
+1123.1,
+1124.1,
+1125.1,
+1126.1,
+1127.1,
+1128.1,
+1129.1,
+1130.1,
+1131.1,
+1132.1,
+1133.1,
+1134.1,
+1135.1,
+1136.1,
+1137.1,
+1138.1,
+1139.1,
+1140.1,
+1141.1,
+1142.1,
+1143.1,
+1144.1,
+1145.1,
+1146.1,
+1147.1,
+1148.1,
+1149.1,
+1150.1,
+1151.1,
+1152.1,
+1153.1,
+1154.1,
+1155.1,
+1156.1,
+1157.1,
+1158.1,
+1159.1,
+1160.1,
+1161.1,
+1162.1,
+1163.1,
+1164.1,
+1165.1,
+1166.1,
+1167.1,
+1168.1,
+1169.1,
+1170.1,
+1171.1,
+1172.1,
+1173.1,
+1174.1,
+1175.1,
+1176.1,
+1177.1,
+1178.1,
+1179.1,
+1180.1,
+1181.1,
+1182.1,
+1183.1,
+1184.1,
+1185.1,
+1186.1,
+1187.1,
+1188.1,
+1189.1,
+1190.1,
+1191.1,
+1192.1,
+1193.1,
+1194.1,
+1195.1,
+1196.1,
+1197.1,
+1198.1,
+1199.1,
+1200.1,
+1201.1,
+1202.1,
+1203.1,
+1204.1,
+1205.1,
+1206.1,
+1207.1,
+1208.1,
+1209.1,
+1210.1,
+1211.1,
+1212.1,
+1213.1,
+1214.1,
+1215.1,
+1216.1,
+1217.1,
+1218.1,
+1219.1,
+1220.1,
+1221.1,
+1222.1,
+1223.1,
+1224.1,
+1225.1,
+1226.1,
+1227.1,
+1228.1,
+1229.1,
+1230.1,
+1231.1,
+1232.1,
+1233.1,
+1234.1,
+1235.1,
+1236.1,
+1237.1,
+1238.1,
+1239.1,
+1240.1,
+1241.1,
+1242.1,
+1243.1,
+1244.1,
+1245.1,
+1246.1,
+1247.1,
+1248.1,
+1249.1,
+1250.1,
+1251.1,
+1252.1,
+1253.1,
+1254.1,
+1255.1,
+1256.1,
+1257.1,
+1258.1,
+1259.1,
+1260.1,
+1261.1,
+1262.1,
+1263.1,
+1264.1,
+1265.1,
+1266.1,
+1267.1,
+1268.1,
+1269.1,
+1270.1,
+1271.1,
+1272.1,
+1273.1,
+1274.1,
+1275.1,
+1276.1,
+1277.1,
+1278.1,
+1279.1,
+1280.1,
+1281.1,
+1282.1,
+1283.1,
+1284.1,
+1285.1,
+1286.1,
+1287.1,
+1288.1,
+1289.1,
+1290.1,
+1291.1,
+1292.1,
+1293.1,
+1294.1,
+1295.1,
+1296.1,
+1297.1,
+1298.1,
+1299.1,
+1300.1,
+1301.1,
+1302.1,
+1303.1,
+1304.1,
+1305.1,
+1306.1,
+1307.1,
+1308.1,
+1309.1,
+1310.1,
+1311.1,
+1312.1,
+1313.1,
+1314.1,
+1315.1,
+1316.1,
+1317.1,
+1318.1,
+1319.1,
+1320.1,
+1321.1,
+1322.1,
+1323.1,
+1324.1,
+1325.1,
+1326.1,
+1327.1,
+1328.1,
+1329.1,
+1330.1,
+1331.1,
+1332.1,
+1333.1,
+1334.1,
+1335.1,
+1336.1,
+1337.1,
+1338.1,
+1339.1,
+1340.1,
+1341.1,
+1342.1,
+1343.1,
+1344.1,
+1345.1,
+1346.1,
+1347.1,
+1348.1,
+1349.1,
+1350.1,
+1351.1,
+1352.1,
+1353.1,
+1354.1,
+1355.1,
+1356.1,
+1357.1,
+1358.1,
+1359.1,
+1360.1,
+1361.1,
+1362.1,
+1363.1,
+1364.1,
+1365.1,
+1366.1,
+1367.1,
+1368.1,
+1369.1,
+1370.1,
+1371.1,
+1372.1,
+1373.1,
+1374.1,
+1375.1,
+1376.1,
+1377.1,
+1378.1,
+1379.1,
+1380.1,
+1381.1,
+1382.1,
+1383.1,
+1384.1,
+1385.1,
+1386.1,
+1387.1,
+1388.1,
+1389.1,
+1390.1,
+1391.1,
+1392.1,
+1393.1,
+1394.1,
+1395.1,
+1396.1,
+1397.1,
+1398.1,
+1399.1,
+1400.1,
+1401.1,
+1402.1,
+1403.1,
+1404.1,
+1405.1,
+1406.1,
+1407.1,
+1408.1,
+1409.1,
+1410.1,
+1411.1,
+1412.1,
+1413.1,
+1414.1,
+1415.1,
+1416.1,
+1417.1,
+1418.1,
+1419.1,
+1420.1,
+1421.1,
+1422.1,
+1423.1,
+1424.1,
+1425.1,
+1426.1,
+1427.1,
+1428.1,
+1429.1,
+1430.1,
+1431.1,
+1432.1,
+1433.1,
+1434.1,
+1435.1,
+1436.1,
+1437.1,
+1438.1,
+1439.1,
+1440.1,
+1441.1,
+1442.1,
+1443.1,
+1444.1,
+1445.1,
+1446.1,
+1447.1,
+1448.1,
+1449.1,
+1450.1,
+1451.1,
+1452.1,
+1453.1,
+1454.1,
+1455.1,
+1456.1,
+1457.1,
+1458.1,
+1459.1,
+1460.1,
+1461.1,
+1462.1,
+1463.1,
+1464.1,
+1465.1,
+1466.1,
+1467.1,
+1468.1,
+1469.1,
+1470.1,
+1471.1,
+1472.1,
+1473.1,
+1474.1,
+1475.1,
+1476.1,
+1477.1,
+1478.1,
+1479.1,
+1480.1,
+1481.1,
+1482.1,
+1483.1,
+1484.1,
+1485.1,
+1486.1,
+1487.1,
+1488.1,
+1489.1,
+1490.1,
+1491.1,
+1492.1,
+1493.1,
+1494.1,
+1495.1,
+1496.1,
+1497.1,
+1498.1,
+1499.1,
+1500.1,
+1501.1,
+1502.1,
+1503.1,
+1504.1,
+1505.1,
+1506.1,
+1507.1,
+1508.1,
+1509.1,
+1510.1,
+1511.1,
+1512.1,
+1513.1,
+1514.1,
+1515.1,
+1516.1,
+1517.1,
+1518.1,
+1519.1,
+1520.1,
+1521.1,
+1522.1,
+1523.1,
+1524.1,
+1525.1,
+1526.1,
+1527.1,
+1528.1,
+1529.1,
+1530.1,
+1531.1,
+1532.1,
+1533.1,
+1534.1,
+1535.1,
+1536.1,
+1537.1,
+1538.1,
+1539.1,
+1540.1,
+1541.1,
+1542.1,
+1543.1,
+1544.1,
+1545.1,
+1546.1,
+1547.1,
+1548.1,
+1549.1,
+1550.1,
+1551.1,
+1552.1,
+1553.1,
+1554.1,
+1555.1,
+1556.1,
+1557.1,
+1558.1,
+1559.1,
+1560.1,
+1561.1,
+1562.1,
+1563.1,
+1564.1,
+1565.1,
+1566.1,
+1567.1,
+1568.1,
+1569.1,
+1570.1,
+1571.1,
+1572.1,
+1573.1,
+1574.1,
+1575.1,
+1576.1,
+1577.1,
+1578.1,
+1579.1,
+1580.1,
+1581.1,
+1582.1,
+1583.1,
+1584.1,
+1585.1,
+1586.1,
+1587.1,
+1588.1,
+1589.1,
+1590.1,
+1591.1,
+1592.1,
+1593.1,
+1594.1,
+1595.1,
+1596.1,
+1597.1,
+1598.1,
+1599.1,
+1600.1,
+1601.1,
+1602.1,
+1603.1,
+1604.1,
+1605.1,
+1606.1,
+1607.1,
+1608.1,
+1609.1,
+1610.1,
+1611.1,
+1612.1,
+1613.1,
+1614.1,
+1615.1,
+1616.1,
+1617.1,
+1618.1,
+1619.1,
+1620.1,
+1621.1,
+1622.1,
+1623.1,
+1624.1,
+1625.1,
+1626.1,
+1627.1,
+1628.1,
+1629.1,
+1630.1,
+1631.1,
+1632.1,
+1633.1,
+1634.1,
+1635.1,
+1636.1,
+1637.1,
+1638.1,
+1639.1,
+1640.1,
+1641.1,
+1642.1,
+1643.1,
+1644.1,
+1645.1,
+1646.1,
+1647.1,
+1648.1,
+1649.1,
+1650.1,
+1651.1,
+1652.1,
+1653.1,
+1654.1,
+1655.1,
+1656.1,
+1657.1,
+1658.1,
+1659.1,
+1660.1,
+1661.1,
+1662.1,
+1663.1,
+1664.1,
+1665.1,
+1666.1,
+1667.1,
+1668.1,
+1669.1,
+1670.1,
+1671.1,
+1672.1,
+1673.1,
+1674.1,
+1675.1,
+1676.1,
+1677.1,
+1678.1,
+1679.1,
+1680.1,
+1681.1,
+1682.1,
+1683.1,
+1684.1,
+1685.1,
+1686.1,
+1687.1,
+1688.1,
+1689.1,
+1690.1,
+1691.1,
+1692.1,
+1693.1,
+1694.1,
+1695.1,
+1696.1,
+1697.1,
+1698.1,
+1699.1,
+1700.1,
+1701.1,
+1702.1,
+1703.1,
+1704.1,
+1705.1,
+1706.1,
+1707.1,
+1708.1,
+1709.1,
+1710.1,
+1711.1,
+1712.1,
+1713.1,
+1714.1,
+1715.1,
+1716.1,
+1717.1,
+1718.1,
+1719.1,
+1720.1,
+1721.1,
+1722.1,
+1723.1,
+1724.1,
+1725.1,
+1726.1,
+1727.1,
+1728.1,
+1729.1,
+1730.1,
+1731.1,
+1732.1,
+1733.1,
+1734.1,
+1735.1,
+1736.1,
+1737.1,
+1738.1,
+1739.1,
+1740.1,
+1741.1,
+1742.1,
+1743.1,
+1744.1,
+1745.1,
+1746.1,
+1747.1,
+1748.1,
+1749.1,
+1750.1,
+1751.1,
+1752.1,
+1753.1,
+1754.1,
+1755.1,
+1756.1,
+1757.1,
+1758.1,
+1759.1,
+1760.1,
+1761.1,
+1762.1,
+1763.1,
+1764.1,
+1765.1,
+1766.1,
+1767.1,
+1768.1,
+1769.1,
+1770.1,
+1771.1,
+1772.1,
+1773.1,
+1774.1,
+1775.1,
+1776.1,
+1777.1,
+1778.1,
+1779.1,
+1780.1,
+1781.1,
+1782.1,
+1783.1,
+1784.1,
+1785.1,
+1786.1,
+1787.1,
+1788.1,
+1789.1,
+1790.1,
+1791.1,
+1792.1,
+1793.1,
+1794.1,
+1795.1,
+1796.1,
+1797.1,
+1798.1,
+1799.1,
+1800.1,
+1801.1,
+1802.1,
+1803.1,
+1804.1,
+1805.1,
+1806.1,
+1807.1,
+1808.1,
+1809.1,
+1810.1,
+1811.1,
+1812.1,
+1813.1,
+1814.1,
+1815.1,
+1816.1,
+1817.1,
+1818.1,
+1819.1,
+1820.1,
+1821.1,
+1822.1,
+1823.1,
+1824.1,
+1825.1,
+1826.1,
+1827.1,
+1828.1,
+1829.1,
+1830.1,
+1831.1,
+1832.1,
+1833.1,
+1834.1,
+1835.1,
+1836.1,
+1837.1,
+1838.1,
+1839.1,
+1840.1,
+1841.1,
+1842.1,
+1843.1,
+1844.1,
+1845.1,
+1846.1,
+1847.1,
+1848.1,
+1849.1,
+1850.1,
+1851.1,
+1852.1,
+1853.1,
+1854.1,
+1855.1,
+1856.1,
+1857.1,
+1858.1,
+1859.1,
+1860.1,
+1861.1,
+1862.1,
+1863.1,
+1864.1,
+1865.1,
+1866.1,
+1867.1,
+1868.1,
+1869.1,
+1870.1,
+1871.1,
+1872.1,
+1873.1,
+1874.1,
+1875.1,
+1876.1,
+1877.1,
+1878.1,
+1879.1,
+1880.1,
+1881.1,
+1882.1,
+1883.1,
+1884.1,
+1885.1,
+1886.1,
+1887.1,
+1888.1,
+1889.1,
+1890.1,
+1891.1,
+1892.1,
+1893.1,
+1894.1,
+1895.1,
+1896.1,
+1897.1,
+1898.1,
+1899.1,
+1900.1,
+1901.1,
+1902.1,
+1903.1,
+1904.1,
+1905.1,
+1906.1,
+1907.1,
+1908.1,
+1909.1,
+1910.1,
+1911.1,
+1912.1,
+1913.1,
+1914.1,
+1915.1,
+1916.1,
+1917.1,
+1918.1,
+1919.1,
+1920.1,
+1921.1,
+1922.1,
+1923.1,
+1924.1,
+1925.1,
+1926.1,
+1927.1,
+1928.1,
+1929.1,
+1930.1,
+1931.1,
+1932.1,
+1933.1,
+1934.1,
+1935.1,
+1936.1,
+1937.1,
+1938.1,
+1939.1,
+1940.1,
+1941.1,
+1942.1,
+1943.1,
+1944.1,
+1945.1,
+1946.1,
+1947.1,
+1948.1,
+1949.1,
+1950.1,
+1951.1,
+1952.1,
+1953.1,
+1954.1,
+1955.1,
+1956.1,
+1957.1,
+1958.1,
+1959.1,
+1960.1,
+1961.1,
+1962.1,
+1963.1,
+1964.1,
+1965.1,
+1966.1,
+1967.1,
+1968.1,
+1969.1,
+1970.1,
+1971.1,
+1972.1,
+1973.1,
+1974.1,
+1975.1,
+1976.1,
+1977.1,
+1978.1,
+1979.1,
+1980.1,
+1981.1,
+1982.1,
+1983.1,
+1984.1,
+1985.1,
+1986.1,
+1987.1,
+1988.1,
+1989.1,
+1990.1,
+1991.1,
+1992.1,
+1993.1,
+1994.1,
+1995.1,
+1996.1,
+1997.1,
+1998.1,
+1999.1,
+2000.1,
+2001.1,
+2002.1,
+2003.1,
+2004.1,
+2005.1,
+2006.1,
+2007.1,
+2008.1,
+2009.1,
+2010.1,
+2011.1,
+2012.1,
+2013.1,
+2014.1,
+2015.1,
+2016.1,
+2017.1,
+2018.1,
+2019.1,
+2020.1,
+2021.1,
+2022.1,
+2023.1,
+2024.1,
+2025.1,
+2026.1,
+2027.1,
+2028.1,
+2029.1,
+2030.1,
+2031.1,
+2032.1,
+2033.1,
+2034.1,
+2035.1,
+2036.1,
+2037.1,
+2038.1,
+2039.1,
+2040.1,
+2041.1,
+2042.1,
+2043.1,
+2044.1,
+2045.1,
+2046.1,
+2047.1,
+2048.1,
+2049.1,
+2050.1,
+2051.1,
+2052.1,
+2053.1,
+2054.1,
+2055.1,
+2056.1,
+2057.1,
+2058.1,
+2059.1,
+2060.1,
+2061.1,
+2062.1,
+2063.1,
+2064.1,
+2065.1,
+2066.1,
+2067.1,
+2068.1,
+2069.1,
+2070.1,
+2071.1,
+2072.1,
+2073.1,
+2074.1,
+2075.1,
+2076.1,
+2077.1,
+2078.1,
+2079.1,
+2080.1,
+2081.1,
+2082.1,
+2083.1,
+2084.1,
+2085.1,
+2086.1,
+2087.1,
+2088.1,
+2089.1,
+2090.1,
+2091.1,
+2092.1,
+2093.1,
+2094.1,
+2095.1,
+2096.1,
+2097.1,
+2098.1,
+2099.1,
+2100.1,
+2101.1,
+2102.1,
+2103.1,
+2104.1,
+2105.1,
+2106.1,
+2107.1,
+2108.1,
+2109.1,
+2110.1,
+2111.1,
+2112.1,
+2113.1,
+2114.1,
+2115.1,
+2116.1,
+2117.1,
+2118.1,
+2119.1,
+2120.1,
+2121.1,
+2122.1,
+2123.1,
+2124.1,
+2125.1,
+2126.1,
+2127.1,
+2128.1,
+2129.1,
+2130.1,
+2131.1,
+2132.1,
+2133.1,
+2134.1,
+2135.1,
+2136.1,
+2137.1,
+2138.1,
+2139.1,
+2140.1,
+2141.1,
+2142.1,
+2143.1,
+2144.1,
+2145.1,
+2146.1,
+2147.1,
+2148.1,
+2149.1,
+2150.1,
+2151.1,
+2152.1,
+2153.1,
+2154.1,
+2155.1,
+2156.1,
+2157.1,
+2158.1,
+2159.1,
+2160.1,
+2161.1,
+2162.1,
+2163.1,
+2164.1,
+2165.1,
+2166.1,
+2167.1,
+2168.1,
+2169.1,
+2170.1,
+2171.1,
+2172.1,
+2173.1,
+2174.1,
+2175.1,
+2176.1,
+2177.1,
+2178.1,
+2179.1,
+2180.1,
+2181.1,
+2182.1,
+2183.1,
+2184.1,
+2185.1,
+2186.1,
+2187.1,
+2188.1,
+2189.1,
+2190.1,
+2191.1,
+2192.1,
+2193.1,
+2194.1,
+2195.1,
+2196.1,
+2197.1,
+2198.1,
+2199.1,
+2200.1,
+2201.1,
+2202.1,
+2203.1,
+2204.1,
+2205.1,
+2206.1,
+2207.1,
+2208.1,
+2209.1,
+2210.1,
+2211.1,
+2212.1,
+2213.1,
+2214.1,
+2215.1,
+2216.1,
+2217.1,
+2218.1,
+2219.1,
+2220.1,
+2221.1,
+2222.1,
+2223.1,
+2224.1,
+2225.1,
+2226.1,
+2227.1,
+2228.1,
+2229.1,
+2230.1,
+2231.1,
+2232.1,
+2233.1,
+2234.1,
+2235.1,
+2236.1,
+2237.1,
+2238.1,
+2239.1,
+2240.1,
+2241.1,
+2242.1,
+2243.1,
+2244.1,
+2245.1,
+2246.1,
+2247.1,
+2248.1,
+2249.1,
+2250.1,
+2251.1,
+2252.1,
+2253.1,
+2254.1,
+2255.1,
+2256.1,
+2257.1,
+2258.1,
+2259.1,
+2260.1,
+2261.1,
+2262.1,
+2263.1,
+2264.1,
+2265.1,
+2266.1,
+2267.1,
+2268.1,
+2269.1,
+2270.1,
+2271.1,
+2272.1,
+2273.1,
+2274.1,
+2275.1,
+2276.1,
+2277.1,
+2278.1,
+2279.1,
+2280.1,
+2281.1,
+2282.1,
+2283.1,
+2284.1,
+2285.1,
+2286.1,
+2287.1,
+2288.1,
+2289.1,
+2290.1,
+2291.1,
+2292.1,
+2293.1,
+2294.1,
+2295.1,
+2296.1,
+2297.1,
+2298.1,
+2299.1,
+2300.1,
+2301.1,
+2302.1,
+2303.1,
+2304.1,
+2305.1,
+2306.1,
+2307.1,
+2308.1,
+2309.1,
+2310.1,
+2311.1,
+2312.1,
+2313.1,
+2314.1,
+2315.1,
+2316.1,
+2317.1,
+2318.1,
+2319.1,
+2320.1,
+2321.1,
+2322.1,
+2323.1,
+2324.1,
+2325.1,
+2326.1,
+2327.1,
+2328.1,
+2329.1,
+2330.1,
+2331.1,
+2332.1,
+2333.1,
+2334.1,
+2335.1,
+2336.1,
+2337.1,
+2338.1,
+2339.1,
+2340.1,
+2341.1,
+2342.1,
+2343.1,
+2344.1,
+2345.1,
+2346.1,
+2347.1,
+2348.1,
+2349.1,
+2350.1,
+2351.1,
+2352.1,
+2353.1,
+2354.1,
+2355.1,
+2356.1,
+2357.1,
+2358.1,
+2359.1,
+2360.1,
+2361.1,
+2362.1,
+2363.1,
+2364.1,
+2365.1,
+2366.1,
+2367.1,
+2368.1,
+2369.1,
+2370.1,
+2371.1,
+2372.1,
+2373.1,
+2374.1,
+2375.1,
+2376.1,
+2377.1,
+2378.1,
+2379.1,
+2380.1,
+2381.1,
+2382.1,
+2383.1,
+2384.1,
+2385.1,
+2386.1,
+2387.1,
+2388.1,
+2389.1,
+2390.1,
+2391.1,
+2392.1,
+2393.1,
+2394.1,
+2395.1,
+2396.1,
+2397.1,
+2398.1,
+2399.1,
+2400.1,
+2401.1,
+2402.1,
+2403.1,
+2404.1,
+2405.1,
+2406.1,
+2407.1,
+2408.1,
+2409.1,
+2410.1,
+2411.1,
+2412.1,
+2413.1,
+2414.1,
+2415.1,
+2416.1,
+2417.1,
+2418.1,
+2419.1,
+2420.1,
+2421.1,
+2422.1,
+2423.1,
+2424.1,
+2425.1,
+2426.1,
+2427.1,
+2428.1,
+2429.1,
+2430.1,
+2431.1,
+2432.1,
+2433.1,
+2434.1,
+2435.1,
+2436.1,
+2437.1,
+2438.1,
+2439.1,
+2440.1,
+2441.1,
+2442.1,
+2443.1,
+2444.1,
+2445.1,
+2446.1,
+2447.1,
+2448.1,
+2449.1,
+2450.1,
+2451.1,
+2452.1,
+2453.1,
+2454.1,
+2455.1,
+2456.1,
+2457.1,
+2458.1,
+2459.1,
+2460.1,
+2461.1,
+2462.1,
+2463.1,
+2464.1,
+2465.1,
+2466.1,
+2467.1,
+2468.1,
+2469.1,
+2470.1,
+2471.1,
+2472.1,
+2473.1,
+2474.1,
+2475.1,
+2476.1,
+2477.1,
+2478.1,
+2479.1,
+2480.1,
+2481.1,
+2482.1,
+2483.1,
+2484.1,
+2485.1,
+2486.1,
+2487.1,
+2488.1,
+2489.1,
+2490.1,
+2491.1,
+2492.1,
+2493.1,
+2494.1,
+2495.1,
+2496.1,
+2497.1,
+2498.1,
+2499.1,
+2500.1,
+2501.1,
+2502.1,
+2503.1,
+2504.1,
+2505.1,
+2506.1,
+2507.1,
+2508.1,
+2509.1,
+2510.1,
+2511.1,
+2512.1,
+2513.1,
+2514.1,
+2515.1,
+2516.1,
+2517.1,
+2518.1,
+2519.1,
+2520.1,
+2521.1,
+2522.1,
+2523.1,
+2524.1,
+2525.1,
+2526.1,
+2527.1,
+2528.1,
+2529.1,
+2530.1,
+2531.1,
+2532.1,
+2533.1,
+2534.1,
+2535.1,
+2536.1,
+2537.1,
+2538.1,
+2539.1,
+2540.1,
+2541.1,
+2542.1,
+2543.1,
+2544.1,
+2545.1,
+2546.1,
+2547.1,
+2548.1,
+2549.1,
+2550.1,
+2551.1,
+2552.1,
+2553.1,
+2554.1,
+2555.1,
+2556.1,
+2557.1,
+2558.1,
+2559.1,
+2560.1,
+2561.1,
+2562.1,
+2563.1,
+2564.1,
+2565.1,
+2566.1,
+2567.1,
+2568.1,
+2569.1,
+2570.1,
+2571.1,
+2572.1,
+2573.1,
+2574.1,
+2575.1,
+2576.1,
+2577.1,
+2578.1,
+2579.1,
+2580.1,
+2581.1,
+2582.1,
+2583.1,
+2584.1,
+2585.1,
+2586.1,
+2587.1,
+2588.1,
+2589.1,
+2590.1,
+2591.1,
+2592.1,
+2593.1,
+2594.1,
+2595.1,
+2596.1,
+2597.1,
+2598.1,
+2599.1,
+2600.1,
+2601.1,
+2602.1,
+2603.1,
+2604.1,
+2605.1,
+2606.1,
+2607.1,
+2608.1,
+2609.1,
+2610.1,
+2611.1,
+2612.1,
+2613.1,
+2614.1,
+2615.1,
+2616.1,
+2617.1,
+2618.1,
+2619.1,
+2620.1,
+2621.1,
+2622.1,
+2623.1,
+2624.1,
+2625.1,
+2626.1,
+2627.1,
+2628.1,
+2629.1,
+2630.1,
+2631.1,
+2632.1,
+2633.1,
+2634.1,
+2635.1,
+2636.1,
+2637.1,
+2638.1,
+2639.1,
+2640.1,
+2641.1,
+2642.1,
+2643.1,
+2644.1,
+2645.1,
+2646.1,
+2647.1,
+2648.1,
+2649.1,
+2650.1,
+2651.1,
+2652.1,
+2653.1,
+2654.1,
+2655.1,
+2656.1,
+2657.1,
+2658.1,
+2659.1,
+2660.1,
+2661.1,
+2662.1,
+2663.1,
+2664.1,
+2665.1,
+2666.1,
+2667.1,
+2668.1,
+2669.1,
+2670.1,
+2671.1,
+2672.1,
+2673.1,
+2674.1,
+2675.1,
+2676.1,
+2677.1,
+2678.1,
+2679.1,
+2680.1,
+2681.1,
+2682.1,
+2683.1,
+2684.1,
+2685.1,
+2686.1,
+2687.1,
+2688.1,
+2689.1,
+2690.1,
+2691.1,
+2692.1,
+2693.1,
+2694.1,
+2695.1,
+2696.1,
+2697.1,
+2698.1,
+2699.1,
+2700.1,
+2701.1,
+2702.1,
+2703.1,
+2704.1,
+2705.1,
+2706.1,
+2707.1,
+2708.1,
+2709.1,
+2710.1,
+2711.1,
+2712.1,
+2713.1,
+2714.1,
+2715.1,
+2716.1,
+2717.1,
+2718.1,
+2719.1,
+2720.1,
+2721.1,
+2722.1,
+2723.1,
+2724.1,
+2725.1,
+2726.1,
+2727.1,
+2728.1,
+2729.1,
+2730.1,
+2731.1,
+2732.1,
+2733.1,
+2734.1,
+2735.1,
+2736.1,
+2737.1,
+2738.1,
+2739.1,
+2740.1,
+2741.1,
+2742.1,
+2743.1,
+2744.1,
+2745.1,
+2746.1,
+2747.1,
+2748.1,
+2749.1,
+2750.1,
+2751.1,
+2752.1,
+2753.1,
+2754.1,
+2755.1,
+2756.1,
+2757.1,
+2758.1,
+2759.1,
+2760.1,
+2761.1,
+2762.1,
+2763.1,
+2764.1,
+2765.1,
+2766.1,
+2767.1,
+2768.1,
+2769.1,
+2770.1,
+2771.1,
+2772.1,
+2773.1,
+2774.1,
+2775.1,
+2776.1,
+2777.1,
+2778.1,
+2779.1,
+2780.1,
+2781.1,
+2782.1,
+2783.1,
+2784.1,
+2785.1,
+2786.1,
+2787.1,
+2788.1,
+2789.1,
+2790.1,
+2791.1,
+2792.1,
+2793.1,
+2794.1,
+2795.1,
+2796.1,
+2797.1,
+2798.1,
+2799.1,
+2800.1,
+2801.1,
+2802.1,
+2803.1,
+2804.1,
+2805.1,
+2806.1,
+2807.1,
+2808.1,
+2809.1,
+2810.1,
+2811.1,
+2812.1,
+2813.1,
+2814.1,
+2815.1,
+2816.1,
+2817.1,
+2818.1,
+2819.1,
+2820.1,
+2821.1,
+2822.1,
+2823.1,
+2824.1,
+2825.1,
+2826.1,
+2827.1,
+2828.1,
+2829.1,
+2830.1,
+2831.1,
+2832.1,
+2833.1,
+2834.1,
+2835.1,
+2836.1,
+2837.1,
+2838.1,
+2839.1,
+2840.1,
+2841.1,
+2842.1,
+2843.1,
+2844.1,
+2845.1,
+2846.1,
+2847.1,
+2848.1,
+2849.1,
+2850.1,
+2851.1,
+2852.1,
+2853.1,
+2854.1,
+2855.1,
+2856.1,
+2857.1,
+2858.1,
+2859.1,
+2860.1,
+2861.1,
+2862.1,
+2863.1,
+2864.1,
+2865.1,
+2866.1,
+2867.1,
+2868.1,
+2869.1,
+2870.1,
+2871.1,
+2872.1,
+2873.1,
+2874.1,
+2875.1,
+2876.1,
+2877.1,
+2878.1,
+2879.1,
+2880.1,
+2881.1,
+2882.1,
+2883.1,
+2884.1,
+2885.1,
+2886.1,
+2887.1,
+2888.1,
+2889.1,
+2890.1,
+2891.1,
+2892.1,
+2893.1,
+2894.1,
+2895.1,
+2896.1,
+2897.1,
+2898.1,
+2899.1,
+2900.1,
+2901.1,
+2902.1,
+2903.1,
+2904.1,
+2905.1,
+2906.1,
+2907.1,
+2908.1,
+2909.1,
+2910.1,
+2911.1,
+2912.1,
+2913.1,
+2914.1,
+2915.1,
+2916.1,
+2917.1,
+2918.1,
+2919.1,
+2920.1,
+2921.1,
+2922.1,
+2923.1,
+2924.1,
+2925.1,
+2926.1,
+2927.1,
+2928.1,
+2929.1,
+2930.1,
+2931.1,
+2932.1,
+2933.1,
+2934.1,
+2935.1,
+2936.1,
+2937.1,
+2938.1,
+2939.1,
+2940.1,
+2941.1,
+2942.1,
+2943.1,
+2944.1,
+2945.1,
+2946.1,
+2947.1,
+2948.1,
+2949.1,
+2950.1,
+2951.1,
+2952.1,
+2953.1,
+2954.1,
+2955.1,
+2956.1,
+2957.1,
+2958.1,
+2959.1,
+2960.1,
+2961.1,
+2962.1,
+2963.1,
+2964.1,
+2965.1,
+2966.1,
+2967.1,
+2968.1,
+2969.1,
+2970.1,
+2971.1,
+2972.1,
+2973.1,
+2974.1,
+2975.1,
+2976.1,
+2977.1,
+2978.1,
+2979.1,
+2980.1,
+2981.1,
+2982.1,
+2983.1,
+2984.1,
+2985.1,
+2986.1,
+2987.1,
+2988.1,
+2989.1,
+2990.1,
+2991.1,
+2992.1,
+2993.1,
+2994.1,
+2995.1,
+2996.1,
+2997.1,
+2998.1,
+2999.1,
+3000.1,
+3001.1,
+3002.1,
+3003.1,
+3004.1,
+3005.1,
+3006.1,
+3007.1,
+3008.1,
+3009.1,
+3010.1,
+3011.1,
+3012.1,
+3013.1,
+3014.1,
+3015.1,
+3016.1,
+3017.1,
+3018.1,
+3019.1,
+3020.1,
+3021.1,
+3022.1,
+3023.1,
+3024.1,
+3025.1,
+3026.1,
+3027.1,
+3028.1,
+3029.1,
+3030.1,
+3031.1,
+3032.1,
+3033.1,
+3034.1,
+3035.1,
+3036.1,
+3037.1,
+3038.1,
+3039.1,
+3040.1,
+3041.1,
+3042.1,
+3043.1,
+3044.1,
+3045.1,
+3046.1,
+3047.1,
+3048.1,
+3049.1,
+3050.1,
+3051.1,
+3052.1,
+3053.1,
+3054.1,
+3055.1,
+3056.1,
+3057.1,
+3058.1,
+3059.1,
+3060.1,
+3061.1,
+3062.1,
+3063.1,
+3064.1,
+3065.1,
+3066.1,
+3067.1,
+3068.1,
+3069.1,
+3070.1,
+3071.1,
+3072.1,
+3073.1,
+3074.1,
+3075.1,
+3076.1,
+3077.1,
+3078.1,
+3079.1,
+3080.1,
+3081.1,
+3082.1,
+3083.1,
+3084.1,
+3085.1,
+3086.1,
+3087.1,
+3088.1,
+3089.1,
+3090.1,
+3091.1,
+3092.1,
+3093.1,
+3094.1,
+3095.1,
+3096.1,
+3097.1,
+3098.1,
+3099.1,
+3100.1,
+3101.1,
+3102.1,
+3103.1,
+3104.1,
+3105.1,
+3106.1,
+3107.1,
+3108.1,
+3109.1,
+3110.1,
+3111.1,
+3112.1,
+3113.1,
+3114.1,
+3115.1,
+3116.1,
+3117.1,
+3118.1,
+3119.1,
+3120.1,
+3121.1,
+3122.1,
+3123.1,
+3124.1,
+3125.1,
+3126.1,
+3127.1,
+3128.1,
+3129.1,
+3130.1,
+3131.1,
+3132.1,
+3133.1,
+3134.1,
+3135.1,
+3136.1,
+3137.1,
+3138.1,
+3139.1,
+3140.1,
+3141.1,
+3142.1,
+3143.1,
+3144.1,
+3145.1,
+3146.1,
+3147.1,
+3148.1,
+3149.1,
+3150.1,
+3151.1,
+3152.1,
+3153.1,
+3154.1,
+3155.1,
+3156.1,
+3157.1,
+3158.1,
+3159.1,
+3160.1,
+3161.1,
+3162.1,
+3163.1,
+3164.1,
+3165.1,
+3166.1,
+3167.1,
+3168.1,
+3169.1,
+3170.1,
+3171.1,
+3172.1,
+3173.1,
+3174.1,
+3175.1,
+3176.1,
+3177.1,
+3178.1,
+3179.1,
+3180.1,
+3181.1,
+3182.1,
+3183.1,
+3184.1,
+3185.1,
+3186.1,
+3187.1,
+3188.1,
+3189.1,
+3190.1,
+3191.1,
+3192.1,
+3193.1,
+3194.1,
+3195.1,
+3196.1,
+3197.1,
+3198.1,
+3199.1,
+3200.1,
+3201.1,
+3202.1,
+3203.1,
+3204.1,
+3205.1,
+3206.1,
+3207.1,
+3208.1,
+3209.1,
+3210.1,
+3211.1,
+3212.1,
+3213.1,
+3214.1,
+3215.1,
+3216.1,
+3217.1,
+3218.1,
+3219.1,
+3220.1,
+3221.1,
+3222.1,
+3223.1,
+3224.1,
+3225.1,
+3226.1,
+3227.1,
+3228.1,
+3229.1,
+3230.1,
+3231.1,
+3232.1,
+3233.1,
+3234.1,
+3235.1,
+3236.1,
+3237.1,
+3238.1,
+3239.1,
+3240.1,
+3241.1,
+3242.1,
+3243.1,
+3244.1,
+3245.1,
+3246.1,
+3247.1,
+3248.1,
+3249.1,
+3250.1,
+3251.1,
+3252.1,
+3253.1,
+3254.1,
+3255.1,
+3256.1,
+3257.1,
+3258.1,
+3259.1,
+3260.1,
+3261.1,
+3262.1,
+3263.1,
+3264.1,
+3265.1,
+3266.1,
+3267.1,
+3268.1,
+3269.1,
+3270.1,
+3271.1,
+3272.1,
+3273.1,
+3274.1,
+3275.1,
+3276.1,
+3277.1,
+3278.1,
+3279.1,
+3280.1,
+3281.1,
+3282.1,
+3283.1,
+3284.1,
+3285.1,
+3286.1,
+3287.1,
+3288.1,
+3289.1,
+3290.1,
+3291.1,
+3292.1,
+3293.1,
+3294.1,
+3295.1,
+3296.1,
+3297.1,
+3298.1,
+3299.1,
+3300.1,
+3301.1,
+3302.1,
+3303.1,
+3304.1,
+3305.1,
+3306.1,
+3307.1,
+3308.1,
+3309.1,
+3310.1,
+3311.1,
+3312.1,
+3313.1,
+3314.1,
+3315.1,
+3316.1,
+3317.1,
+3318.1,
+3319.1,
+3320.1,
+3321.1,
+3322.1,
+3323.1,
+3324.1,
+3325.1,
+3326.1,
+3327.1,
+3328.1,
+3329.1,
+3330.1,
+3331.1,
+3332.1,
+3333.1,
+3334.1,
+3335.1,
+3336.1,
+3337.1,
+3338.1,
+3339.1,
+3340.1,
+3341.1,
+3342.1,
+3343.1,
+3344.1,
+3345.1,
+3346.1,
+3347.1,
+3348.1,
+3349.1,
+3350.1,
+3351.1,
+3352.1,
+3353.1,
+3354.1,
+3355.1,
+3356.1,
+3357.1,
+3358.1,
+3359.1,
+3360.1,
+3361.1,
+3362.1,
+3363.1,
+3364.1,
+3365.1,
+3366.1,
+3367.1,
+3368.1,
+3369.1,
+3370.1,
+3371.1,
+3372.1,
+3373.1,
+3374.1,
+3375.1,
+3376.1,
+3377.1,
+3378.1,
+3379.1,
+3380.1,
+3381.1,
+3382.1,
+3383.1,
+3384.1,
+3385.1,
+3386.1,
+3387.1,
+3388.1,
+3389.1,
+3390.1,
+3391.1,
+3392.1,
+3393.1,
+3394.1,
+3395.1,
+3396.1,
+3397.1,
+3398.1,
+3399.1,
+3400.1,
+3401.1,
+3402.1,
+3403.1,
+3404.1,
+3405.1,
+3406.1,
+3407.1,
+3408.1,
+3409.1,
+3410.1,
+3411.1,
+3412.1,
+3413.1,
+3414.1,
+3415.1,
+3416.1,
+3417.1,
+3418.1,
+3419.1,
+3420.1,
+3421.1,
+3422.1,
+3423.1,
+3424.1,
+3425.1,
+3426.1,
+3427.1,
+3428.1,
+3429.1,
+3430.1,
+3431.1,
+3432.1,
+3433.1,
+3434.1,
+3435.1,
+3436.1,
+3437.1,
+3438.1,
+3439.1,
+3440.1,
+3441.1,
+3442.1,
+3443.1,
+3444.1,
+3445.1,
+3446.1,
+3447.1,
+3448.1,
+3449.1,
+3450.1,
+3451.1,
+3452.1,
+3453.1,
+3454.1,
+3455.1,
+3456.1,
+3457.1,
+3458.1,
+3459.1,
+3460.1,
+3461.1,
+3462.1,
+3463.1,
+3464.1,
+3465.1,
+3466.1,
+3467.1,
+3468.1,
+3469.1,
+3470.1,
+3471.1,
+3472.1,
+3473.1,
+3474.1,
+3475.1,
+3476.1,
+3477.1,
+3478.1,
+3479.1,
+3480.1,
+3481.1,
+3482.1,
+3483.1,
+3484.1,
+3485.1,
+3486.1,
+3487.1,
+3488.1,
+3489.1,
+3490.1,
+3491.1,
+3492.1,
+3493.1,
+3494.1,
+3495.1,
+3496.1,
+3497.1,
+3498.1,
+3499.1,
+3500.1,
+3501.1,
+3502.1,
+3503.1,
+3504.1,
+3505.1,
+3506.1,
+3507.1,
+3508.1,
+3509.1,
+3510.1,
+3511.1,
+3512.1,
+3513.1,
+3514.1,
+3515.1,
+3516.1,
+3517.1,
+3518.1,
+3519.1,
+3520.1,
+3521.1,
+3522.1,
+3523.1,
+3524.1,
+3525.1,
+3526.1,
+3527.1,
+3528.1,
+3529.1,
+3530.1,
+3531.1,
+3532.1,
+3533.1,
+3534.1,
+3535.1,
+3536.1,
+3537.1,
+3538.1,
+3539.1,
+3540.1,
+3541.1,
+3542.1,
+3543.1,
+3544.1,
+3545.1,
+3546.1,
+3547.1,
+3548.1,
+3549.1,
+3550.1,
+3551.1,
+3552.1,
+3553.1,
+3554.1,
+3555.1,
+3556.1,
+3557.1,
+3558.1,
+3559.1,
+3560.1,
+3561.1,
+3562.1,
+3563.1,
+3564.1,
+3565.1,
+3566.1,
+3567.1,
+3568.1,
+3569.1,
+3570.1,
+3571.1,
+3572.1,
+3573.1,
+3574.1,
+3575.1,
+3576.1,
+3577.1,
+3578.1,
+3579.1,
+3580.1,
+3581.1,
+3582.1,
+3583.1,
+3584.1,
+3585.1,
+3586.1,
+3587.1,
+3588.1,
+3589.1,
+3590.1,
+3591.1,
+3592.1,
+3593.1,
+3594.1,
+3595.1,
+3596.1,
+3597.1,
+3598.1,
+3599.1,
+3600.1,
+3601.1,
+3602.1,
+3603.1,
+3604.1,
+3605.1,
+3606.1,
+3607.1,
+3608.1,
+3609.1,
+3610.1,
+3611.1,
+3612.1,
+3613.1,
+3614.1,
+3615.1,
+3616.1,
+3617.1,
+3618.1,
+3619.1,
+3620.1,
+3621.1,
+3622.1,
+3623.1,
+3624.1,
+3625.1,
+3626.1,
+3627.1,
+3628.1,
+3629.1,
+3630.1,
+3631.1,
+3632.1,
+3633.1,
+3634.1,
+3635.1,
+3636.1,
+3637.1,
+3638.1,
+3639.1,
+3640.1,
+3641.1,
+3642.1,
+3643.1,
+3644.1,
+3645.1,
+3646.1,
+3647.1,
+3648.1,
+3649.1,
+3650.1,
+3651.1,
+3652.1,
+3653.1,
+3654.1,
+3655.1,
+3656.1,
+3657.1,
+3658.1,
+3659.1,
+3660.1,
+3661.1,
+3662.1,
+3663.1,
+3664.1,
+3665.1,
+3666.1,
+3667.1,
+3668.1,
+3669.1,
+3670.1,
+3671.1,
+3672.1,
+3673.1,
+3674.1,
+3675.1,
+3676.1,
+3677.1,
+3678.1,
+3679.1,
+3680.1,
+3681.1,
+3682.1,
+3683.1,
+3684.1,
+3685.1,
+3686.1,
+3687.1,
+3688.1,
+3689.1,
+3690.1,
+3691.1,
+3692.1,
+3693.1,
+3694.1,
+3695.1,
+3696.1,
+3697.1,
+3698.1,
+3699.1,
+3700.1,
+3701.1,
+3702.1,
+3703.1,
+3704.1,
+3705.1,
+3706.1,
+3707.1,
+3708.1,
+3709.1,
+3710.1,
+3711.1,
+3712.1,
+3713.1,
+3714.1,
+3715.1,
+3716.1,
+3717.1,
+3718.1,
+3719.1,
+3720.1,
+3721.1,
+3722.1,
+3723.1,
+3724.1,
+3725.1,
+3726.1,
+3727.1,
+3728.1,
+3729.1,
+3730.1,
+3731.1,
+3732.1,
+3733.1,
+3734.1,
+3735.1,
+3736.1,
+3737.1,
+3738.1,
+3739.1,
+3740.1,
+3741.1,
+3742.1,
+3743.1,
+3744.1,
+3745.1,
+3746.1,
+3747.1,
+3748.1,
+3749.1,
+3750.1,
+3751.1,
+3752.1,
+3753.1,
+3754.1,
+3755.1,
+3756.1,
+3757.1,
+3758.1,
+3759.1,
+3760.1,
+3761.1,
+3762.1,
+3763.1,
+3764.1,
+3765.1,
+3766.1,
+3767.1,
+3768.1,
+3769.1,
+3770.1,
+3771.1,
+3772.1,
+3773.1,
+3774.1,
+3775.1,
+3776.1,
+3777.1,
+3778.1,
+3779.1,
+3780.1,
+3781.1,
+3782.1,
+3783.1,
+3784.1,
+3785.1,
+3786.1,
+3787.1,
+3788.1,
+3789.1,
+3790.1,
+3791.1,
+3792.1,
+3793.1,
+3794.1,
+3795.1,
+3796.1,
+3797.1,
+3798.1,
+3799.1,
+3800.1,
+3801.1,
+3802.1,
+3803.1,
+3804.1,
+3805.1,
+3806.1,
+3807.1,
+3808.1,
+3809.1,
+3810.1,
+3811.1,
+3812.1,
+3813.1,
+3814.1,
+3815.1,
+3816.1,
+3817.1,
+3818.1,
+3819.1,
+3820.1,
+3821.1,
+3822.1,
+3823.1,
+3824.1,
+3825.1,
+3826.1,
+3827.1,
+3828.1,
+3829.1,
+3830.1,
+3831.1,
+3832.1,
+3833.1,
+3834.1,
+3835.1,
+3836.1,
+3837.1,
+3838.1,
+3839.1,
+3840.1,
+3841.1,
+3842.1,
+3843.1,
+3844.1,
+3845.1,
+3846.1,
+3847.1,
+3848.1,
+3849.1,
+3850.1,
+3851.1,
+3852.1,
+3853.1,
+3854.1,
+3855.1,
+3856.1,
+3857.1,
+3858.1,
+3859.1,
+3860.1,
+3861.1,
+3862.1,
+3863.1,
+3864.1,
+3865.1,
+3866.1,
+3867.1,
+3868.1,
+3869.1,
+3870.1,
+3871.1,
+3872.1,
+3873.1,
+3874.1,
+3875.1,
+3876.1,
+3877.1,
+3878.1,
+3879.1,
+3880.1,
+3881.1,
+3882.1,
+3883.1,
+3884.1,
+3885.1,
+3886.1,
+3887.1,
+3888.1,
+3889.1,
+3890.1,
+3891.1,
+3892.1,
+3893.1,
+3894.1,
+3895.1,
+3896.1,
+3897.1,
+3898.1,
+3899.1,
+3900.1,
+3901.1,
+3902.1,
+3903.1,
+3904.1,
+3905.1,
+3906.1,
+3907.1,
+3908.1,
+3909.1,
+3910.1,
+3911.1,
+3912.1,
+3913.1,
+3914.1,
+3915.1,
+3916.1,
+3917.1,
+3918.1,
+3919.1,
+3920.1,
+3921.1,
+3922.1,
+3923.1,
+3924.1,
+3925.1,
+3926.1,
+3927.1,
+3928.1,
+3929.1,
+3930.1,
+3931.1,
+3932.1,
+3933.1,
+3934.1,
+3935.1,
+3936.1,
+3937.1,
+3938.1,
+3939.1,
+3940.1,
+3941.1,
+3942.1,
+3943.1,
+3944.1,
+3945.1,
+3946.1,
+3947.1,
+3948.1,
+3949.1,
+3950.1,
+3951.1,
+3952.1,
+3953.1,
+3954.1,
+3955.1,
+3956.1,
+3957.1,
+3958.1,
+3959.1,
+3960.1,
+3961.1,
+3962.1,
+3963.1,
+3964.1,
+3965.1,
+3966.1,
+3967.1,
+3968.1,
+3969.1,
+3970.1,
+3971.1,
+3972.1,
+3973.1,
+3974.1,
+3975.1,
+3976.1,
+3977.1,
+3978.1,
+3979.1,
+3980.1,
+3981.1,
+3982.1,
+3983.1,
+3984.1,
+3985.1,
+3986.1,
+3987.1,
+3988.1,
+3989.1,
+3990.1,
+3991.1,
+3992.1,
+3993.1,
+3994.1,
+3995.1,
+3996.1,
+3997.1,
+3998.1,
+3999.1,
+4000.1,
+4001.1,
+4002.1,
+4003.1,
+4004.1,
+4005.1,
+4006.1,
+4007.1,
+4008.1,
+4009.1,
+4010.1,
+4011.1,
+4012.1,
+4013.1,
+4014.1,
+4015.1,
+4016.1,
+4017.1,
+4018.1,
+4019.1,
+4020.1,
+4021.1,
+4022.1,
+4023.1,
+4024.1,
+4025.1,
+4026.1,
+4027.1,
+4028.1,
+4029.1,
+4030.1,
+4031.1,
+4032.1,
+4033.1,
+4034.1,
+4035.1,
+4036.1,
+4037.1,
+4038.1,
+4039.1,
+4040.1,
+4041.1,
+4042.1,
+4043.1,
+4044.1,
+4045.1,
+4046.1,
+4047.1,
+4048.1,
+4049.1,
+4050.1,
+4051.1,
+4052.1,
+4053.1,
+4054.1,
+4055.1,
+4056.1,
+4057.1,
+4058.1,
+4059.1,
+4060.1,
+4061.1,
+4062.1,
+4063.1,
+4064.1,
+4065.1,
+4066.1,
+4067.1,
+4068.1,
+4069.1,
+4070.1,
+4071.1,
+4072.1,
+4073.1,
+4074.1,
+4075.1,
+4076.1,
+4077.1,
+4078.1,
+4079.1,
+4080.1,
+4081.1,
+4082.1,
+4083.1,
+4084.1,
+4085.1,
+4086.1,
+4087.1,
+4088.1,
+4089.1,
+4090.1,
+4091.1,
+4092.1,
+4093.1,
+4094.1,
+4095.1,
+4096.1,
+4097.1,
+4098.1,
+4099.1,
+4100.1,
+4101.1,
+4102.1,
+4103.1,
+4104.1,
+4105.1,
+4106.1,
+4107.1,
+4108.1,
+4109.1,
+4110.1,
+4111.1,
+4112.1,
+4113.1,
+4114.1,
+4115.1,
+4116.1,
+4117.1,
+4118.1,
+4119.1,
+4120.1,
+4121.1,
+4122.1,
+4123.1,
+4124.1,
+4125.1,
+4126.1,
+4127.1,
+4128.1,
+4129.1,
+4130.1,
+4131.1,
+4132.1,
+4133.1,
+4134.1,
+4135.1,
+4136.1,
+4137.1,
+4138.1,
+4139.1,
+4140.1,
+4141.1,
+4142.1,
+4143.1,
+4144.1,
+4145.1,
+4146.1,
+4147.1,
+4148.1,
+4149.1,
+4150.1,
+4151.1,
+4152.1,
+4153.1,
+4154.1,
+4155.1,
+4156.1,
+4157.1,
+4158.1,
+4159.1,
+4160.1,
+4161.1,
+4162.1,
+4163.1,
+4164.1,
+4165.1,
+4166.1,
+4167.1,
+4168.1,
+4169.1,
+4170.1,
+4171.1,
+4172.1,
+4173.1,
+4174.1,
+4175.1,
+4176.1,
+4177.1,
+4178.1,
+4179.1,
+4180.1,
+4181.1,
+4182.1,
+4183.1,
+4184.1,
+4185.1,
+4186.1,
+4187.1,
+4188.1,
+4189.1,
+4190.1,
+4191.1,
+4192.1,
+4193.1,
+4194.1,
+4195.1,
+4196.1,
+4197.1,
+4198.1,
+4199.1,
+4200.1,
+4201.1,
+4202.1,
+4203.1,
+4204.1,
+4205.1,
+4206.1,
+4207.1,
+4208.1,
+4209.1,
+4210.1,
+4211.1,
+4212.1,
+4213.1,
+4214.1,
+4215.1,
+4216.1,
+4217.1,
+4218.1,
+4219.1,
+4220.1,
+4221.1,
+4222.1,
+4223.1,
+4224.1,
+4225.1,
+4226.1,
+4227.1,
+4228.1,
+4229.1,
+4230.1,
+4231.1,
+4232.1,
+4233.1,
+4234.1,
+4235.1,
+4236.1,
+4237.1,
+4238.1,
+4239.1,
+4240.1,
+4241.1,
+4242.1,
+4243.1,
+4244.1,
+4245.1,
+4246.1,
+4247.1,
+4248.1,
+4249.1,
+4250.1,
+4251.1,
+4252.1,
+4253.1,
+4254.1,
+4255.1,
+4256.1,
+4257.1,
+4258.1,
+4259.1,
+4260.1,
+4261.1,
+4262.1,
+4263.1,
+4264.1,
+4265.1,
+4266.1,
+4267.1,
+4268.1,
+4269.1,
+4270.1,
+4271.1,
+4272.1,
+4273.1,
+4274.1,
+4275.1,
+4276.1,
+4277.1,
+4278.1,
+4279.1,
+4280.1,
+4281.1,
+4282.1,
+4283.1,
+4284.1,
+4285.1,
+4286.1,
+4287.1,
+4288.1,
+4289.1,
+4290.1,
+4291.1,
+4292.1,
+4293.1,
+4294.1,
+4295.1,
+4296.1,
+4297.1,
+4298.1,
+4299.1,
+4300.1,
+4301.1,
+4302.1,
+4303.1,
+4304.1,
+4305.1,
+4306.1,
+4307.1,
+4308.1,
+4309.1,
+4310.1,
+4311.1,
+4312.1,
+4313.1,
+4314.1,
+4315.1,
+4316.1,
+4317.1,
+4318.1,
+4319.1,
+4320.1,
+4321.1,
+4322.1,
+4323.1,
+4324.1,
+4325.1,
+4326.1,
+4327.1,
+4328.1,
+4329.1,
+4330.1,
+4331.1,
+4332.1,
+4333.1,
+4334.1,
+4335.1,
+4336.1,
+4337.1,
+4338.1,
+4339.1,
+4340.1,
+4341.1,
+4342.1,
+4343.1,
+4344.1,
+4345.1,
+4346.1,
+4347.1,
+4348.1,
+4349.1,
+4350.1,
+4351.1,
+4352.1,
+4353.1,
+4354.1,
+4355.1,
+4356.1,
+4357.1,
+4358.1,
+4359.1,
+4360.1,
+4361.1,
+4362.1,
+4363.1,
+4364.1,
+4365.1,
+4366.1,
+4367.1,
+4368.1,
+4369.1,
+4370.1,
+4371.1,
+4372.1,
+4373.1,
+4374.1,
+4375.1,
+4376.1,
+4377.1,
+4378.1,
+4379.1,
+4380.1,
+4381.1,
+4382.1,
+4383.1,
+4384.1,
+4385.1,
+4386.1,
+4387.1,
+4388.1,
+4389.1,
+4390.1,
+4391.1,
+4392.1,
+4393.1,
+4394.1,
+4395.1,
+4396.1,
+4397.1,
+4398.1,
+4399.1,
+4400.1,
+4401.1,
+4402.1,
+4403.1,
+4404.1,
+4405.1,
+4406.1,
+4407.1,
+4408.1,
+4409.1,
+4410.1,
+4411.1,
+4412.1,
+4413.1,
+4414.1,
+4415.1,
+4416.1,
+4417.1,
+4418.1,
+4419.1,
+4420.1,
+4421.1,
+4422.1,
+4423.1,
+4424.1,
+4425.1,
+4426.1,
+4427.1,
+4428.1,
+4429.1,
+4430.1,
+4431.1,
+4432.1,
+4433.1,
+4434.1,
+4435.1,
+4436.1,
+4437.1,
+4438.1,
+4439.1,
+4440.1,
+4441.1,
+4442.1,
+4443.1,
+4444.1,
+4445.1,
+4446.1,
+4447.1,
+4448.1,
+4449.1,
+4450.1,
+4451.1,
+4452.1,
+4453.1,
+4454.1,
+4455.1,
+4456.1,
+4457.1,
+4458.1,
+4459.1,
+4460.1,
+4461.1,
+4462.1,
+4463.1,
+4464.1,
+4465.1,
+4466.1,
+4467.1,
+4468.1,
+4469.1,
+4470.1,
+4471.1,
+4472.1,
+4473.1,
+4474.1,
+4475.1,
+4476.1,
+4477.1,
+4478.1,
+4479.1,
+4480.1,
+4481.1,
+4482.1,
+4483.1,
+4484.1,
+4485.1,
+4486.1,
+4487.1,
+4488.1,
+4489.1,
+4490.1,
+4491.1,
+4492.1,
+4493.1,
+4494.1,
+4495.1,
+4496.1,
+4497.1,
+4498.1,
+4499.1,
+4500.1,
+4501.1,
+4502.1,
+4503.1,
+4504.1,
+4505.1,
+4506.1,
+4507.1,
+4508.1,
+4509.1,
+4510.1,
+4511.1,
+4512.1,
+4513.1,
+4514.1,
+4515.1,
+4516.1,
+4517.1,
+4518.1,
+4519.1,
+4520.1,
+4521.1,
+4522.1,
+4523.1,
+4524.1,
+4525.1,
+4526.1,
+4527.1,
+4528.1,
+4529.1,
+4530.1,
+4531.1,
+4532.1,
+4533.1,
+4534.1,
+4535.1,
+4536.1,
+4537.1,
+4538.1,
+4539.1,
+4540.1,
+4541.1,
+4542.1,
+4543.1,
+4544.1,
+4545.1,
+4546.1,
+4547.1,
+4548.1,
+4549.1,
+4550.1,
+4551.1,
+4552.1,
+4553.1,
+4554.1,
+4555.1,
+4556.1,
+4557.1,
+4558.1,
+4559.1,
+4560.1,
+4561.1,
+4562.1,
+4563.1,
+4564.1,
+4565.1,
+4566.1,
+4567.1,
+4568.1,
+4569.1,
+4570.1,
+4571.1,
+4572.1,
+4573.1,
+4574.1,
+4575.1,
+4576.1,
+4577.1,
+4578.1,
+4579.1,
+4580.1,
+4581.1,
+4582.1,
+4583.1,
+4584.1,
+4585.1,
+4586.1,
+4587.1,
+4588.1,
+4589.1,
+4590.1,
+4591.1,
+4592.1,
+4593.1,
+4594.1,
+4595.1,
+4596.1,
+4597.1,
+4598.1,
+4599.1,
+4600.1,
+4601.1,
+4602.1,
+4603.1,
+4604.1,
+4605.1,
+4606.1,
+4607.1,
+4608.1,
+4609.1,
+4610.1,
+4611.1,
+4612.1,
+4613.1,
+4614.1,
+4615.1,
+4616.1,
+4617.1,
+4618.1,
+4619.1,
+4620.1,
+4621.1,
+4622.1,
+4623.1,
+4624.1,
+4625.1,
+4626.1,
+4627.1,
+4628.1,
+4629.1,
+4630.1,
+4631.1,
+4632.1,
+4633.1,
+4634.1,
+4635.1,
+4636.1,
+4637.1,
+4638.1,
+4639.1,
+4640.1,
+4641.1,
+4642.1,
+4643.1,
+4644.1,
+4645.1,
+4646.1,
+4647.1,
+4648.1,
+4649.1,
+4650.1,
+4651.1,
+4652.1,
+4653.1,
+4654.1,
+4655.1,
+4656.1,
+4657.1,
+4658.1,
+4659.1,
+4660.1,
+4661.1,
+4662.1,
+4663.1,
+4664.1,
+4665.1,
+4666.1,
+4667.1,
+4668.1,
+4669.1,
+4670.1,
+4671.1,
+4672.1,
+4673.1,
+4674.1,
+4675.1,
+4676.1,
+4677.1,
+4678.1,
+4679.1,
+4680.1,
+4681.1,
+4682.1,
+4683.1,
+4684.1,
+4685.1,
+4686.1,
+4687.1,
+4688.1,
+4689.1,
+4690.1,
+4691.1,
+4692.1,
+4693.1,
+4694.1,
+4695.1,
+4696.1,
+4697.1,
+4698.1,
+4699.1,
+4700.1,
+4701.1,
+4702.1,
+4703.1,
+4704.1,
+4705.1,
+4706.1,
+4707.1,
+4708.1,
+4709.1,
+4710.1,
+4711.1,
+4712.1,
+4713.1,
+4714.1,
+4715.1,
+4716.1,
+4717.1,
+4718.1,
+4719.1,
+4720.1,
+4721.1,
+4722.1,
+4723.1,
+4724.1,
+4725.1,
+4726.1,
+4727.1,
+4728.1,
+4729.1,
+4730.1,
+4731.1,
+4732.1,
+4733.1,
+4734.1,
+4735.1,
+4736.1,
+4737.1,
+4738.1,
+4739.1,
+4740.1,
+4741.1,
+4742.1,
+4743.1,
+4744.1,
+4745.1,
+4746.1,
+4747.1,
+4748.1,
+4749.1,
+4750.1,
+4751.1,
+4752.1,
+4753.1,
+4754.1,
+4755.1,
+4756.1,
+4757.1,
+4758.1,
+4759.1,
+4760.1,
+4761.1,
+4762.1,
+4763.1,
+4764.1,
+4765.1,
+4766.1,
+4767.1,
+4768.1,
+4769.1,
+4770.1,
+4771.1,
+4772.1,
+4773.1,
+4774.1,
+4775.1,
+4776.1,
+4777.1,
+4778.1,
+4779.1,
+4780.1,
+4781.1,
+4782.1,
+4783.1,
+4784.1,
+4785.1,
+4786.1,
+4787.1,
+4788.1,
+4789.1,
+4790.1,
+4791.1,
+4792.1,
+4793.1,
+4794.1,
+4795.1,
+4796.1,
+4797.1,
+4798.1,
+4799.1,
+4800.1,
+4801.1,
+4802.1,
+4803.1,
+4804.1,
+4805.1,
+4806.1,
+4807.1,
+4808.1,
+4809.1,
+4810.1,
+4811.1,
+4812.1,
+4813.1,
+4814.1,
+4815.1,
+4816.1,
+4817.1,
+4818.1,
+4819.1,
+4820.1,
+4821.1,
+4822.1,
+4823.1,
+4824.1,
+4825.1,
+4826.1,
+4827.1,
+4828.1,
+4829.1,
+4830.1,
+4831.1,
+4832.1,
+4833.1,
+4834.1,
+4835.1,
+4836.1,
+4837.1,
+4838.1,
+4839.1,
+4840.1,
+4841.1,
+4842.1,
+4843.1,
+4844.1,
+4845.1,
+4846.1,
+4847.1,
+4848.1,
+4849.1,
+4850.1,
+4851.1,
+4852.1,
+4853.1,
+4854.1,
+4855.1,
+4856.1,
+4857.1,
+4858.1,
+4859.1,
+4860.1,
+4861.1,
+4862.1,
+4863.1,
+4864.1,
+4865.1,
+4866.1,
+4867.1,
+4868.1,
+4869.1,
+4870.1,
+4871.1,
+4872.1,
+4873.1,
+4874.1,
+4875.1,
+4876.1,
+4877.1,
+4878.1,
+4879.1,
+4880.1,
+4881.1,
+4882.1,
+4883.1,
+4884.1,
+4885.1,
+4886.1,
+4887.1,
+4888.1,
+4889.1,
+4890.1,
+4891.1,
+4892.1,
+4893.1,
+4894.1,
+4895.1,
+4896.1,
+4897.1,
+4898.1,
+4899.1,
+4900.1,
+4901.1,
+4902.1,
+4903.1,
+4904.1,
+4905.1,
+4906.1,
+4907.1,
+4908.1,
+4909.1,
+4910.1,
+4911.1,
+4912.1,
+4913.1,
+4914.1,
+4915.1,
+4916.1,
+4917.1,
+4918.1,
+4919.1,
+4920.1,
+4921.1,
+4922.1,
+4923.1,
+4924.1,
+4925.1,
+4926.1,
+4927.1,
+4928.1,
+4929.1,
+4930.1,
+4931.1,
+4932.1,
+4933.1,
+4934.1,
+4935.1,
+4936.1,
+4937.1,
+4938.1,
+4939.1,
+4940.1,
+4941.1,
+4942.1,
+4943.1,
+4944.1,
+4945.1,
+4946.1,
+4947.1,
+4948.1,
+4949.1,
+4950.1,
+4951.1,
+4952.1,
+4953.1,
+4954.1,
+4955.1,
+4956.1,
+4957.1,
+4958.1,
+4959.1,
+4960.1,
+4961.1,
+4962.1,
+4963.1,
+4964.1,
+4965.1,
+4966.1,
+4967.1,
+4968.1,
+4969.1,
+4970.1,
+4971.1,
+4972.1,
+4973.1,
+4974.1,
+4975.1,
+4976.1,
+4977.1,
+4978.1,
+4979.1,
+4980.1,
+4981.1,
+4982.1,
+4983.1,
+4984.1,
+4985.1,
+4986.1,
+4987.1,
+4988.1,
+4989.1,
+4990.1,
+4991.1,
+4992.1,
+4993.1,
+4994.1,
+4995.1,
+4996.1,
+4997.1,
+4998.1,
+4999.1,
+5000.1,
+5001.1,
+5002.1,
+5003.1,
+5004.1,
+5005.1,
+5006.1,
+5007.1,
+5008.1,
+5009.1,
+5010.1,
+5011.1,
+5012.1,
+5013.1,
+5014.1,
+5015.1,
+5016.1,
+5017.1,
+5018.1,
+5019.1,
+5020.1,
+5021.1,
+5022.1,
+5023.1,
+5024.1,
+5025.1,
+5026.1,
+5027.1,
+5028.1,
+5029.1,
+5030.1,
+5031.1,
+5032.1,
+5033.1,
+5034.1,
+5035.1,
+5036.1,
+5037.1,
+5038.1,
+5039.1,
+5040.1,
+5041.1,
+5042.1,
+5043.1,
+5044.1,
+5045.1,
+5046.1,
+5047.1,
+5048.1,
+5049.1,
+5050.1,
+5051.1,
+5052.1,
+5053.1,
+5054.1,
+5055.1,
+5056.1,
+5057.1,
+5058.1,
+5059.1,
+5060.1,
+5061.1,
+5062.1,
+5063.1,
+5064.1,
+5065.1,
+5066.1,
+5067.1,
+5068.1,
+5069.1,
+5070.1,
+5071.1,
+5072.1,
+5073.1,
+5074.1,
+5075.1,
+5076.1,
+5077.1,
+5078.1,
+5079.1,
+5080.1,
+5081.1,
+5082.1,
+5083.1,
+5084.1,
+5085.1,
+5086.1,
+5087.1,
+5088.1,
+5089.1,
+5090.1,
+5091.1,
+5092.1,
+5093.1,
+5094.1,
+5095.1,
+5096.1,
+5097.1,
+5098.1,
+5099.1,
+5100.1,
+5101.1,
+5102.1,
+5103.1,
+5104.1,
+5105.1,
+5106.1,
+5107.1,
+5108.1,
+5109.1,
+5110.1,
+5111.1,
+5112.1,
+5113.1,
+5114.1,
+5115.1,
+5116.1,
+5117.1,
+5118.1,
+5119.1,
+5120.1,
+5121.1,
+5122.1,
+5123.1,
+5124.1,
+5125.1,
+5126.1,
+5127.1,
+5128.1,
+5129.1,
+5130.1,
+5131.1,
+5132.1,
+5133.1,
+5134.1,
+5135.1,
+5136.1,
+5137.1,
+5138.1,
+5139.1,
+5140.1,
+5141.1,
+5142.1,
+5143.1,
+5144.1,
+5145.1,
+5146.1,
+5147.1,
+5148.1,
+5149.1,
+5150.1,
+5151.1,
+5152.1,
+5153.1,
+5154.1,
+5155.1,
+5156.1,
+5157.1,
+5158.1,
+5159.1,
+5160.1,
+5161.1,
+5162.1,
+5163.1,
+5164.1,
+5165.1,
+5166.1,
+5167.1,
+5168.1,
+5169.1,
+5170.1,
+5171.1,
+5172.1,
+5173.1,
+5174.1,
+5175.1,
+5176.1,
+5177.1,
+5178.1,
+5179.1,
+5180.1,
+5181.1,
+5182.1,
+5183.1,
+5184.1,
+5185.1,
+5186.1,
+5187.1,
+5188.1,
+5189.1,
+5190.1,
+5191.1,
+5192.1,
+5193.1,
+5194.1,
+5195.1,
+5196.1,
+5197.1,
+5198.1,
+5199.1,
+5200.1,
+5201.1,
+5202.1,
+5203.1,
+5204.1,
+5205.1,
+5206.1,
+5207.1,
+5208.1,
+5209.1,
+5210.1,
+5211.1,
+5212.1,
+5213.1,
+5214.1,
+5215.1,
+5216.1,
+5217.1,
+5218.1,
+5219.1,
+5220.1,
+5221.1,
+5222.1,
+5223.1,
+5224.1,
+5225.1,
+5226.1,
+5227.1,
+5228.1,
+5229.1,
+5230.1,
+5231.1,
+5232.1,
+5233.1,
+5234.1,
+5235.1,
+5236.1,
+5237.1,
+5238.1,
+5239.1,
+5240.1,
+5241.1,
+5242.1,
+5243.1,
+5244.1,
+5245.1,
+5246.1,
+5247.1,
+5248.1,
+5249.1,
+5250.1,
+5251.1,
+5252.1,
+5253.1,
+5254.1,
+5255.1,
+5256.1,
+5257.1,
+5258.1,
+5259.1,
+5260.1,
+5261.1,
+5262.1,
+5263.1,
+5264.1,
+5265.1,
+5266.1,
+5267.1,
+5268.1,
+5269.1,
+5270.1,
+5271.1,
+5272.1,
+5273.1,
+5274.1,
+5275.1,
+5276.1,
+5277.1,
+5278.1,
+5279.1,
+5280.1,
+5281.1,
+5282.1,
+5283.1,
+5284.1,
+5285.1,
+5286.1,
+5287.1,
+5288.1,
+5289.1,
+5290.1,
+5291.1,
+5292.1,
+5293.1,
+5294.1,
+5295.1,
+5296.1,
+5297.1,
+5298.1,
+5299.1,
+5300.1,
+5301.1,
+5302.1,
+5303.1,
+5304.1,
+5305.1,
+5306.1,
+5307.1,
+5308.1,
+5309.1,
+5310.1,
+5311.1,
+5312.1,
+5313.1,
+5314.1,
+5315.1,
+5316.1,
+5317.1,
+5318.1,
+5319.1,
+5320.1,
+5321.1,
+5322.1,
+5323.1,
+5324.1,
+5325.1,
+5326.1,
+5327.1,
+5328.1,
+5329.1,
+5330.1,
+5331.1,
+5332.1,
+5333.1,
+5334.1,
+5335.1,
+5336.1,
+5337.1,
+5338.1,
+5339.1,
+5340.1,
+5341.1,
+5342.1,
+5343.1,
+5344.1,
+5345.1,
+5346.1,
+5347.1,
+5348.1,
+5349.1,
+5350.1,
+5351.1,
+5352.1,
+5353.1,
+5354.1,
+5355.1,
+5356.1,
+5357.1,
+5358.1,
+5359.1,
+5360.1,
+5361.1,
+5362.1,
+5363.1,
+5364.1,
+5365.1,
+5366.1,
+5367.1,
+5368.1,
+5369.1,
+5370.1,
+5371.1,
+5372.1,
+5373.1,
+5374.1,
+5375.1,
+5376.1,
+5377.1,
+5378.1,
+5379.1,
+5380.1,
+5381.1,
+5382.1,
+5383.1,
+5384.1,
+5385.1,
+5386.1,
+5387.1,
+5388.1,
+5389.1,
+5390.1,
+5391.1,
+5392.1,
+5393.1,
+5394.1,
+5395.1,
+5396.1,
+5397.1,
+5398.1,
+5399.1,
+5400.1,
+5401.1,
+5402.1,
+5403.1,
+5404.1,
+5405.1,
+5406.1,
+5407.1,
+5408.1,
+5409.1,
+5410.1,
+5411.1,
+5412.1,
+5413.1,
+5414.1,
+5415.1,
+5416.1,
+5417.1,
+5418.1,
+5419.1,
+5420.1,
+5421.1,
+5422.1,
+5423.1,
+5424.1,
+5425.1,
+5426.1,
+5427.1,
+5428.1,
+5429.1,
+5430.1,
+5431.1,
+5432.1,
+5433.1,
+5434.1,
+5435.1,
+5436.1,
+5437.1,
+5438.1,
+5439.1,
+5440.1,
+5441.1,
+5442.1,
+5443.1,
+5444.1,
+5445.1,
+5446.1,
+5447.1,
+5448.1,
+5449.1,
+5450.1,
+5451.1,
+5452.1,
+5453.1,
+5454.1,
+5455.1,
+5456.1,
+5457.1,
+5458.1,
+5459.1,
+5460.1,
+5461.1,
+5462.1,
+5463.1,
+5464.1,
+5465.1,
+5466.1,
+5467.1,
+5468.1,
+5469.1,
+5470.1,
+5471.1,
+5472.1,
+5473.1,
+5474.1,
+5475.1,
+5476.1,
+5477.1,
+5478.1,
+5479.1,
+5480.1,
+5481.1,
+5482.1,
+5483.1,
+5484.1,
+5485.1,
+5486.1,
+5487.1,
+5488.1,
+5489.1,
+5490.1,
+5491.1,
+5492.1,
+5493.1,
+5494.1,
+5495.1,
+5496.1,
+5497.1,
+5498.1,
+5499.1,
+5500.1,
+5501.1,
+5502.1,
+5503.1,
+5504.1,
+5505.1,
+5506.1,
+5507.1,
+5508.1,
+5509.1,
+5510.1,
+5511.1,
+5512.1,
+5513.1,
+5514.1,
+5515.1,
+5516.1,
+5517.1,
+5518.1,
+5519.1,
+5520.1,
+5521.1,
+5522.1,
+5523.1,
+5524.1,
+5525.1,
+5526.1,
+5527.1,
+5528.1,
+5529.1,
+5530.1,
+5531.1,
+5532.1,
+5533.1,
+5534.1,
+5535.1,
+5536.1,
+5537.1,
+5538.1,
+5539.1,
+5540.1,
+5541.1,
+5542.1,
+5543.1,
+5544.1,
+5545.1,
+5546.1,
+5547.1,
+5548.1,
+5549.1,
+5550.1,
+5551.1,
+5552.1,
+5553.1,
+5554.1,
+5555.1,
+5556.1,
+5557.1,
+5558.1,
+5559.1,
+5560.1,
+5561.1,
+5562.1,
+5563.1,
+5564.1,
+5565.1,
+5566.1,
+5567.1,
+5568.1,
+5569.1,
+5570.1,
+5571.1,
+5572.1,
+5573.1,
+5574.1,
+5575.1,
+5576.1,
+5577.1,
+5578.1,
+5579.1,
+5580.1,
+5581.1,
+5582.1,
+5583.1,
+5584.1,
+5585.1,
+5586.1,
+5587.1,
+5588.1,
+5589.1,
+5590.1,
+5591.1,
+5592.1,
+5593.1,
+5594.1,
+5595.1,
+5596.1,
+5597.1,
+5598.1,
+5599.1,
+5600.1,
+5601.1,
+5602.1,
+5603.1,
+5604.1,
+5605.1,
+5606.1,
+5607.1,
+5608.1,
+5609.1,
+5610.1,
+5611.1,
+5612.1,
+5613.1,
+5614.1,
+5615.1,
+5616.1,
+5617.1,
+5618.1,
+5619.1,
+5620.1,
+5621.1,
+5622.1,
+5623.1,
+5624.1,
+5625.1,
+5626.1,
+5627.1,
+5628.1,
+5629.1,
+5630.1,
+5631.1,
+5632.1,
+5633.1,
+5634.1,
+5635.1,
+5636.1,
+5637.1,
+5638.1,
+5639.1,
+5640.1,
+5641.1,
+5642.1,
+5643.1,
+5644.1,
+5645.1,
+5646.1,
+5647.1,
+5648.1,
+5649.1,
+5650.1,
+5651.1,
+5652.1,
+5653.1,
+5654.1,
+5655.1,
+5656.1,
+5657.1,
+5658.1,
+5659.1,
+5660.1,
+5661.1,
+5662.1,
+5663.1,
+5664.1,
+5665.1,
+5666.1,
+5667.1,
+5668.1,
+5669.1,
+5670.1,
+5671.1,
+5672.1,
+5673.1,
+5674.1,
+5675.1,
+5676.1,
+5677.1,
+5678.1,
+5679.1,
+5680.1,
+5681.1,
+5682.1,
+5683.1,
+5684.1,
+5685.1,
+5686.1,
+5687.1,
+5688.1,
+5689.1,
+5690.1,
+5691.1,
+5692.1,
+5693.1,
+5694.1,
+5695.1,
+5696.1,
+5697.1,
+5698.1,
+5699.1,
+5700.1,
+5701.1,
+5702.1,
+5703.1,
+5704.1,
+5705.1,
+5706.1,
+5707.1,
+5708.1,
+5709.1,
+5710.1,
+5711.1,
+5712.1,
+5713.1,
+5714.1,
+5715.1,
+5716.1,
+5717.1,
+5718.1,
+5719.1,
+5720.1,
+5721.1,
+5722.1,
+5723.1,
+5724.1,
+5725.1,
+5726.1,
+5727.1,
+5728.1,
+5729.1,
+5730.1,
+5731.1,
+5732.1,
+5733.1,
+5734.1,
+5735.1,
+5736.1,
+5737.1,
+5738.1,
+5739.1,
+5740.1,
+5741.1,
+5742.1,
+5743.1,
+5744.1,
+5745.1,
+5746.1,
+5747.1,
+5748.1,
+5749.1,
+5750.1,
+5751.1,
+5752.1,
+5753.1,
+5754.1,
+5755.1,
+5756.1,
+5757.1,
+5758.1,
+5759.1,
+5760.1,
+5761.1,
+5762.1,
+5763.1,
+5764.1,
+5765.1,
+5766.1,
+5767.1,
+5768.1,
+5769.1,
+5770.1,
+5771.1,
+5772.1,
+5773.1,
+5774.1,
+5775.1,
+5776.1,
+5777.1,
+5778.1,
+5779.1,
+5780.1,
+5781.1,
+5782.1,
+5783.1,
+5784.1,
+5785.1,
+5786.1,
+5787.1,
+5788.1,
+5789.1,
+5790.1,
+5791.1,
+5792.1,
+5793.1,
+5794.1,
+5795.1,
+5796.1,
+5797.1,
+5798.1,
+5799.1,
+5800.1,
+5801.1,
+5802.1,
+5803.1,
+5804.1,
+5805.1,
+5806.1,
+5807.1,
+5808.1,
+5809.1,
+5810.1,
+5811.1,
+5812.1,
+5813.1,
+5814.1,
+5815.1,
+5816.1,
+5817.1,
+5818.1,
+5819.1,
+5820.1,
+5821.1,
+5822.1,
+5823.1,
+5824.1,
+5825.1,
+5826.1,
+5827.1,
+5828.1,
+5829.1,
+5830.1,
+5831.1,
+5832.1,
+5833.1,
+5834.1,
+5835.1,
+5836.1,
+5837.1,
+5838.1,
+5839.1,
+5840.1,
+5841.1,
+5842.1,
+5843.1,
+5844.1,
+5845.1,
+5846.1,
+5847.1,
+5848.1,
+5849.1,
+5850.1,
+5851.1,
+5852.1,
+5853.1,
+5854.1,
+5855.1,
+5856.1,
+5857.1,
+5858.1,
+5859.1,
+5860.1,
+5861.1,
+5862.1,
+5863.1,
+5864.1,
+5865.1,
+5866.1,
+5867.1,
+5868.1,
+5869.1,
+5870.1,
+5871.1,
+5872.1,
+5873.1,
+5874.1,
+5875.1,
+5876.1,
+5877.1,
+5878.1,
+5879.1,
+5880.1,
+5881.1,
+5882.1,
+5883.1,
+5884.1,
+5885.1,
+5886.1,
+5887.1,
+5888.1,
+5889.1,
+5890.1,
+5891.1,
+5892.1,
+5893.1,
+5894.1,
+5895.1,
+5896.1,
+5897.1,
+5898.1,
+5899.1,
+5900.1,
+5901.1,
+5902.1,
+5903.1,
+5904.1,
+5905.1,
+5906.1,
+5907.1,
+5908.1,
+5909.1,
+5910.1,
+5911.1,
+5912.1,
+5913.1,
+5914.1,
+5915.1,
+5916.1,
+5917.1,
+5918.1,
+5919.1,
+5920.1,
+5921.1,
+5922.1,
+5923.1,
+5924.1,
+5925.1,
+5926.1,
+5927.1,
+5928.1,
+5929.1,
+5930.1,
+5931.1,
+5932.1,
+5933.1,
+5934.1,
+5935.1,
+5936.1,
+5937.1,
+5938.1,
+5939.1,
+5940.1,
+5941.1,
+5942.1,
+5943.1,
+5944.1,
+5945.1,
+5946.1,
+5947.1,
+5948.1,
+5949.1,
+5950.1,
+5951.1,
+5952.1,
+5953.1,
+5954.1,
+5955.1,
+5956.1,
+5957.1,
+5958.1,
+5959.1,
+5960.1,
+5961.1,
+5962.1,
+5963.1,
+5964.1,
+5965.1,
+5966.1,
+5967.1,
+5968.1,
+5969.1,
+5970.1,
+5971.1,
+5972.1,
+5973.1,
+5974.1,
+5975.1,
+5976.1,
+5977.1,
+5978.1,
+5979.1,
+5980.1,
+5981.1,
+5982.1,
+5983.1,
+5984.1,
+5985.1,
+5986.1,
+5987.1,
+5988.1,
+5989.1,
+5990.1,
+5991.1,
+5992.1,
+5993.1,
+5994.1,
+5995.1,
+5996.1,
+5997.1,
+5998.1,
+5999.1,
+6000.1,
+6001.1,
+6002.1,
+6003.1,
+6004.1,
+6005.1,
+6006.1,
+6007.1,
+6008.1,
+6009.1,
+6010.1,
+6011.1,
+6012.1,
+6013.1,
+6014.1,
+6015.1,
+6016.1,
+6017.1,
+6018.1,
+6019.1,
+6020.1,
+6021.1,
+6022.1,
+6023.1,
+6024.1,
+6025.1,
+6026.1,
+6027.1,
+6028.1,
+6029.1,
+6030.1,
+6031.1,
+6032.1,
+6033.1,
+6034.1,
+6035.1,
+6036.1,
+6037.1,
+6038.1,
+6039.1,
+6040.1,
+6041.1,
+6042.1,
+6043.1,
+6044.1,
+6045.1,
+6046.1,
+6047.1,
+6048.1,
+6049.1,
+6050.1,
+6051.1,
+6052.1,
+6053.1,
+6054.1,
+6055.1,
+6056.1,
+6057.1,
+6058.1,
+6059.1,
+6060.1,
+6061.1,
+6062.1,
+6063.1,
+6064.1,
+6065.1,
+6066.1,
+6067.1,
+6068.1,
+6069.1,
+6070.1,
+6071.1,
+6072.1,
+6073.1,
+6074.1,
+6075.1,
+6076.1,
+6077.1,
+6078.1,
+6079.1,
+6080.1,
+6081.1,
+6082.1,
+6083.1,
+6084.1,
+6085.1,
+6086.1,
+6087.1,
+6088.1,
+6089.1,
+6090.1,
+6091.1,
+6092.1,
+6093.1,
+6094.1,
+6095.1,
+6096.1,
+6097.1,
+6098.1,
+6099.1,
+6100.1,
+6101.1,
+6102.1,
+6103.1,
+6104.1,
+6105.1,
+6106.1,
+6107.1,
+6108.1,
+6109.1,
+6110.1,
+6111.1,
+6112.1,
+6113.1,
+6114.1,
+6115.1,
+6116.1,
+6117.1,
+6118.1,
+6119.1,
+6120.1,
+6121.1,
+6122.1,
+6123.1,
+6124.1,
+6125.1,
+6126.1,
+6127.1,
+6128.1,
+6129.1,
+6130.1,
+6131.1,
+6132.1,
+6133.1,
+6134.1,
+6135.1,
+6136.1,
+6137.1,
+6138.1,
+6139.1,
+6140.1,
+6141.1,
+6142.1,
+6143.1,
+6144.1,
+6145.1,
+6146.1,
+6147.1,
+6148.1,
+6149.1,
+6150.1,
+6151.1,
+6152.1,
+6153.1,
+6154.1,
+6155.1,
+6156.1,
+6157.1,
+6158.1,
+6159.1,
+6160.1,
+6161.1,
+6162.1,
+6163.1,
+6164.1,
+6165.1,
+6166.1,
+6167.1,
+6168.1,
+6169.1,
+6170.1,
+6171.1,
+6172.1,
+6173.1,
+6174.1,
+6175.1,
+6176.1,
+6177.1,
+6178.1,
+6179.1,
+6180.1,
+6181.1,
+6182.1,
+6183.1,
+6184.1,
+6185.1,
+6186.1,
+6187.1,
+6188.1,
+6189.1,
+6190.1,
+6191.1,
+6192.1,
+6193.1,
+6194.1,
+6195.1,
+6196.1,
+6197.1,
+6198.1,
+6199.1,
+6200.1,
+6201.1,
+6202.1,
+6203.1,
+6204.1,
+6205.1,
+6206.1,
+6207.1,
+6208.1,
+6209.1,
+6210.1,
+6211.1,
+6212.1,
+6213.1,
+6214.1,
+6215.1,
+6216.1,
+6217.1,
+6218.1,
+6219.1,
+6220.1,
+6221.1,
+6222.1,
+6223.1,
+6224.1,
+6225.1,
+6226.1,
+6227.1,
+6228.1,
+6229.1,
+6230.1,
+6231.1,
+6232.1,
+6233.1,
+6234.1,
+6235.1,
+6236.1,
+6237.1,
+6238.1,
+6239.1,
+6240.1,
+6241.1,
+6242.1,
+6243.1,
+6244.1,
+6245.1,
+6246.1,
+6247.1,
+6248.1,
+6249.1,
+6250.1,
+6251.1,
+6252.1,
+6253.1,
+6254.1,
+6255.1,
+6256.1,
+6257.1,
+6258.1,
+6259.1,
+6260.1,
+6261.1,
+6262.1,
+6263.1,
+6264.1,
+6265.1,
+6266.1,
+6267.1,
+6268.1,
+6269.1,
+6270.1,
+6271.1,
+6272.1,
+6273.1,
+6274.1,
+6275.1,
+6276.1,
+6277.1,
+6278.1,
+6279.1,
+6280.1,
+6281.1,
+6282.1,
+6283.1,
+6284.1,
+6285.1,
+6286.1,
+6287.1,
+6288.1,
+6289.1,
+6290.1,
+6291.1,
+6292.1,
+6293.1,
+6294.1,
+6295.1,
+6296.1,
+6297.1,
+6298.1,
+6299.1,
+6300.1,
+6301.1,
+6302.1,
+6303.1,
+6304.1,
+6305.1,
+6306.1,
+6307.1,
+6308.1,
+6309.1,
+6310.1,
+6311.1,
+6312.1,
+6313.1,
+6314.1,
+6315.1,
+6316.1,
+6317.1,
+6318.1,
+6319.1,
+6320.1,
+6321.1,
+6322.1,
+6323.1,
+6324.1,
+6325.1,
+6326.1,
+6327.1,
+6328.1,
+6329.1,
+6330.1,
+6331.1,
+6332.1,
+6333.1,
+6334.1,
+6335.1,
+6336.1,
+6337.1,
+6338.1,
+6339.1,
+6340.1,
+6341.1,
+6342.1,
+6343.1,
+6344.1,
+6345.1,
+6346.1,
+6347.1,
+6348.1,
+6349.1,
+6350.1,
+6351.1,
+6352.1,
+6353.1,
+6354.1,
+6355.1,
+6356.1,
+6357.1,
+6358.1,
+6359.1,
+6360.1,
+6361.1,
+6362.1,
+6363.1,
+6364.1,
+6365.1,
+6366.1,
+6367.1,
+6368.1,
+6369.1,
+6370.1,
+6371.1,
+6372.1,
+6373.1,
+6374.1,
+6375.1,
+6376.1,
+6377.1,
+6378.1,
+6379.1,
+6380.1,
+6381.1,
+6382.1,
+6383.1,
+6384.1,
+6385.1,
+6386.1,
+6387.1,
+6388.1,
+6389.1,
+6390.1,
+6391.1,
+6392.1,
+6393.1,
+6394.1,
+6395.1,
+6396.1,
+6397.1,
+6398.1,
+6399.1,
+6400.1,
+6401.1,
+6402.1,
+6403.1,
+6404.1,
+6405.1,
+6406.1,
+6407.1,
+6408.1,
+6409.1,
+6410.1,
+6411.1,
+6412.1,
+6413.1,
+6414.1,
+6415.1,
+6416.1,
+6417.1,
+6418.1,
+6419.1,
+6420.1,
+6421.1,
+6422.1,
+6423.1,
+6424.1,
+6425.1,
+6426.1,
+6427.1,
+6428.1,
+6429.1,
+6430.1,
+6431.1,
+6432.1,
+6433.1,
+6434.1,
+6435.1,
+6436.1,
+6437.1,
+6438.1,
+6439.1,
+6440.1,
+6441.1,
+6442.1,
+6443.1,
+6444.1,
+6445.1,
+6446.1,
+6447.1,
+6448.1,
+6449.1,
+6450.1,
+6451.1,
+6452.1,
+6453.1,
+6454.1,
+6455.1,
+6456.1,
+6457.1,
+6458.1,
+6459.1,
+6460.1,
+6461.1,
+6462.1,
+6463.1,
+6464.1,
+6465.1,
+6466.1,
+6467.1,
+6468.1,
+6469.1,
+6470.1,
+6471.1,
+6472.1,
+6473.1,
+6474.1,
+6475.1,
+6476.1,
+6477.1,
+6478.1,
+6479.1,
+6480.1,
+6481.1,
+6482.1,
+6483.1,
+6484.1,
+6485.1,
+6486.1,
+6487.1,
+6488.1,
+6489.1,
+6490.1,
+6491.1,
+6492.1,
+6493.1,
+6494.1,
+6495.1,
+6496.1,
+6497.1,
+6498.1,
+6499.1,
+6500.1,
+6501.1,
+6502.1,
+6503.1,
+6504.1,
+6505.1,
+6506.1,
+6507.1,
+6508.1,
+6509.1,
+6510.1,
+6511.1,
+6512.1,
+6513.1,
+6514.1,
+6515.1,
+6516.1,
+6517.1,
+6518.1,
+6519.1,
+6520.1,
+6521.1,
+6522.1,
+6523.1,
+6524.1,
+6525.1,
+6526.1,
+6527.1,
+6528.1,
+6529.1,
+6530.1,
+6531.1,
+6532.1,
+6533.1,
+6534.1,
+6535.1,
+6536.1,
+6537.1,
+6538.1,
+6539.1,
+6540.1,
+6541.1,
+6542.1,
+6543.1,
+6544.1,
+6545.1,
+6546.1,
+6547.1,
+6548.1,
+6549.1,
+6550.1,
+6551.1,
+6552.1,
+6553.1,
+6554.1,
+6555.1,
+6556.1,
+6557.1,
+6558.1,
+6559.1,
+6560.1,
+6561.1,
+6562.1,
+6563.1,
+6564.1,
+6565.1,
+6566.1,
+6567.1,
+6568.1,
+6569.1,
+6570.1,
+6571.1,
+6572.1,
+6573.1,
+6574.1,
+6575.1,
+6576.1,
+6577.1,
+6578.1,
+6579.1,
+6580.1,
+6581.1,
+6582.1,
+6583.1,
+6584.1,
+6585.1,
+6586.1,
+6587.1,
+6588.1,
+6589.1,
+6590.1,
+6591.1,
+6592.1,
+6593.1,
+6594.1,
+6595.1,
+6596.1,
+6597.1,
+6598.1,
+6599.1,
+6600.1,
+6601.1,
+6602.1,
+6603.1,
+6604.1,
+6605.1,
+6606.1,
+6607.1,
+6608.1,
+6609.1,
+6610.1,
+6611.1,
+6612.1,
+6613.1,
+6614.1,
+6615.1,
+6616.1,
+6617.1,
+6618.1,
+6619.1,
+6620.1,
+6621.1,
+6622.1,
+6623.1,
+6624.1,
+6625.1,
+6626.1,
+6627.1,
+6628.1,
+6629.1,
+6630.1,
+6631.1,
+6632.1,
+6633.1,
+6634.1,
+6635.1,
+6636.1,
+6637.1,
+6638.1,
+6639.1,
+6640.1,
+6641.1,
+6642.1,
+6643.1,
+6644.1,
+6645.1,
+6646.1,
+6647.1,
+6648.1,
+6649.1,
+6650.1,
+6651.1,
+6652.1,
+6653.1,
+6654.1,
+6655.1,
+6656.1,
+6657.1,
+6658.1,
+6659.1,
+6660.1,
+6661.1,
+6662.1,
+6663.1,
+6664.1,
+6665.1,
+6666.1,
+6667.1,
+6668.1,
+6669.1,
+6670.1,
+6671.1,
+6672.1,
+6673.1,
+6674.1,
+6675.1,
+6676.1,
+6677.1,
+6678.1,
+6679.1,
+6680.1,
+6681.1,
+6682.1,
+6683.1,
+6684.1,
+6685.1,
+6686.1,
+6687.1,
+6688.1,
+6689.1,
+6690.1,
+6691.1,
+6692.1,
+6693.1,
+6694.1,
+6695.1,
+6696.1,
+6697.1,
+6698.1,
+6699.1,
+6700.1,
+6701.1,
+6702.1,
+6703.1,
+6704.1,
+6705.1,
+6706.1,
+6707.1,
+6708.1,
+6709.1,
+6710.1,
+6711.1,
+6712.1,
+6713.1,
+6714.1,
+6715.1,
+6716.1,
+6717.1,
+6718.1,
+6719.1,
+6720.1,
+6721.1,
+6722.1,
+6723.1,
+6724.1,
+6725.1,
+6726.1,
+6727.1,
+6728.1,
+6729.1,
+6730.1,
+6731.1,
+6732.1,
+6733.1,
+6734.1,
+6735.1,
+6736.1,
+6737.1,
+6738.1,
+6739.1,
+6740.1,
+6741.1,
+6742.1,
+6743.1,
+6744.1,
+6745.1,
+6746.1,
+6747.1,
+6748.1,
+6749.1,
+6750.1,
+6751.1,
+6752.1,
+6753.1,
+6754.1,
+6755.1,
+6756.1,
+6757.1,
+6758.1,
+6759.1,
+6760.1,
+6761.1,
+6762.1,
+6763.1,
+6764.1,
+6765.1,
+6766.1,
+6767.1,
+6768.1,
+6769.1,
+6770.1,
+6771.1,
+6772.1,
+6773.1,
+6774.1,
+6775.1,
+6776.1,
+6777.1,
+6778.1,
+6779.1,
+6780.1,
+6781.1,
+6782.1,
+6783.1,
+6784.1,
+6785.1,
+6786.1,
+6787.1,
+6788.1,
+6789.1,
+6790.1,
+6791.1,
+6792.1,
+6793.1,
+6794.1,
+6795.1,
+6796.1,
+6797.1,
+6798.1,
+6799.1,
+6800.1,
+6801.1,
+6802.1,
+6803.1,
+6804.1,
+6805.1,
+6806.1,
+6807.1,
+6808.1,
+6809.1,
+6810.1,
+6811.1,
+6812.1,
+6813.1,
+6814.1,
+6815.1,
+6816.1,
+6817.1,
+6818.1,
+6819.1,
+6820.1,
+6821.1,
+6822.1,
+6823.1,
+6824.1,
+6825.1,
+6826.1,
+6827.1,
+6828.1,
+6829.1,
+6830.1,
+6831.1,
+6832.1,
+6833.1,
+6834.1,
+6835.1,
+6836.1,
+6837.1,
+6838.1,
+6839.1,
+6840.1,
+6841.1,
+6842.1,
+6843.1,
+6844.1,
+6845.1,
+6846.1,
+6847.1,
+6848.1,
+6849.1,
+6850.1,
+6851.1,
+6852.1,
+6853.1,
+6854.1,
+6855.1,
+6856.1,
+6857.1,
+6858.1,
+6859.1,
+6860.1,
+6861.1,
+6862.1,
+6863.1,
+6864.1,
+6865.1,
+6866.1,
+6867.1,
+6868.1,
+6869.1,
+6870.1,
+6871.1,
+6872.1,
+6873.1,
+6874.1,
+6875.1,
+6876.1,
+6877.1,
+6878.1,
+6879.1,
+6880.1,
+6881.1,
+6882.1,
+6883.1,
+6884.1,
+6885.1,
+6886.1,
+6887.1,
+6888.1,
+6889.1,
+6890.1,
+6891.1,
+6892.1,
+6893.1,
+6894.1,
+6895.1,
+6896.1,
+6897.1,
+6898.1,
+6899.1,
+6900.1,
+6901.1,
+6902.1,
+6903.1,
+6904.1,
+6905.1,
+6906.1,
+6907.1,
+6908.1,
+6909.1,
+6910.1,
+6911.1,
+6912.1,
+6913.1,
+6914.1,
+6915.1,
+6916.1,
+6917.1,
+6918.1,
+6919.1,
+6920.1,
+6921.1,
+6922.1,
+6923.1,
+6924.1,
+6925.1,
+6926.1,
+6927.1,
+6928.1,
+6929.1,
+6930.1,
+6931.1,
+6932.1,
+6933.1,
+6934.1,
+6935.1,
+6936.1,
+6937.1,
+6938.1,
+6939.1,
+6940.1,
+6941.1,
+6942.1,
+6943.1,
+6944.1,
+6945.1,
+6946.1,
+6947.1,
+6948.1,
+6949.1,
+6950.1,
+6951.1,
+6952.1,
+6953.1,
+6954.1,
+6955.1,
+6956.1,
+6957.1,
+6958.1,
+6959.1,
+6960.1,
+6961.1,
+6962.1,
+6963.1,
+6964.1,
+6965.1,
+6966.1,
+6967.1,
+6968.1,
+6969.1,
+6970.1,
+6971.1,
+6972.1,
+6973.1,
+6974.1,
+6975.1,
+6976.1,
+6977.1,
+6978.1,
+6979.1,
+6980.1,
+6981.1,
+6982.1,
+6983.1,
+6984.1,
+6985.1,
+6986.1,
+6987.1,
+6988.1,
+6989.1,
+6990.1,
+6991.1,
+6992.1,
+6993.1,
+6994.1,
+6995.1,
+6996.1,
+6997.1,
+6998.1,
+6999.1,
+7000.1,
+7001.1,
+7002.1,
+7003.1,
+7004.1,
+7005.1,
+7006.1,
+7007.1,
+7008.1,
+7009.1,
+7010.1,
+7011.1,
+7012.1,
+7013.1,
+7014.1,
+7015.1,
+7016.1,
+7017.1,
+7018.1,
+7019.1,
+7020.1,
+7021.1,
+7022.1,
+7023.1,
+7024.1,
+7025.1,
+7026.1,
+7027.1,
+7028.1,
+7029.1,
+7030.1,
+7031.1,
+7032.1,
+7033.1,
+7034.1,
+7035.1,
+7036.1,
+7037.1,
+7038.1,
+7039.1,
+7040.1,
+7041.1,
+7042.1,
+7043.1,
+7044.1,
+7045.1,
+7046.1,
+7047.1,
+7048.1,
+7049.1,
+7050.1,
+7051.1,
+7052.1,
+7053.1,
+7054.1,
+7055.1,
+7056.1,
+7057.1,
+7058.1,
+7059.1,
+7060.1,
+7061.1,
+7062.1,
+7063.1,
+7064.1,
+7065.1,
+7066.1,
+7067.1,
+7068.1,
+7069.1,
+7070.1,
+7071.1,
+7072.1,
+7073.1,
+7074.1,
+7075.1,
+7076.1,
+7077.1,
+7078.1,
+7079.1,
+7080.1,
+7081.1,
+7082.1,
+7083.1,
+7084.1,
+7085.1,
+7086.1,
+7087.1,
+7088.1,
+7089.1,
+7090.1,
+7091.1,
+7092.1,
+7093.1,
+7094.1,
+7095.1,
+7096.1,
+7097.1,
+7098.1,
+7099.1,
+7100.1,
+7101.1,
+7102.1,
+7103.1,
+7104.1,
+7105.1,
+7106.1,
+7107.1,
+7108.1,
+7109.1,
+7110.1,
+7111.1,
+7112.1,
+7113.1,
+7114.1,
+7115.1,
+7116.1,
+7117.1,
+7118.1,
+7119.1,
+7120.1,
+7121.1,
+7122.1,
+7123.1,
+7124.1,
+7125.1,
+7126.1,
+7127.1,
+7128.1,
+7129.1,
+7130.1,
+7131.1,
+7132.1,
+7133.1,
+7134.1,
+7135.1,
+7136.1,
+7137.1,
+7138.1,
+7139.1,
+7140.1,
+7141.1,
+7142.1,
+7143.1,
+7144.1,
+7145.1,
+7146.1,
+7147.1,
+7148.1,
+7149.1,
+7150.1,
+7151.1,
+7152.1,
+7153.1,
+7154.1,
+7155.1,
+7156.1,
+7157.1,
+7158.1,
+7159.1,
+7160.1,
+7161.1,
+7162.1,
+7163.1,
+7164.1,
+7165.1,
+7166.1,
+7167.1,
+7168.1,
+7169.1,
+7170.1,
+7171.1,
+7172.1,
+7173.1,
+7174.1,
+7175.1,
+7176.1,
+7177.1,
+7178.1,
+7179.1,
+7180.1,
+7181.1,
+7182.1,
+7183.1,
+7184.1,
+7185.1,
+7186.1,
+7187.1,
+7188.1,
+7189.1,
+7190.1,
+7191.1,
+7192.1,
+7193.1,
+7194.1,
+7195.1,
+7196.1,
+7197.1,
+7198.1,
+7199.1,
+7200.1,
+7201.1,
+7202.1,
+7203.1,
+7204.1,
+7205.1,
+7206.1,
+7207.1,
+7208.1,
+7209.1,
+7210.1,
+7211.1,
+7212.1,
+7213.1,
+7214.1,
+7215.1,
+7216.1,
+7217.1,
+7218.1,
+7219.1,
+7220.1,
+7221.1,
+7222.1,
+7223.1,
+7224.1,
+7225.1,
+7226.1,
+7227.1,
+7228.1,
+7229.1,
+7230.1,
+7231.1,
+7232.1,
+7233.1,
+7234.1,
+7235.1,
+7236.1,
+7237.1,
+7238.1,
+7239.1,
+7240.1,
+7241.1,
+7242.1,
+7243.1,
+7244.1,
+7245.1,
+7246.1,
+7247.1,
+7248.1,
+7249.1,
+7250.1,
+7251.1,
+7252.1,
+7253.1,
+7254.1,
+7255.1,
+7256.1,
+7257.1,
+7258.1,
+7259.1,
+7260.1,
+7261.1,
+7262.1,
+7263.1,
+7264.1,
+7265.1,
+7266.1,
+7267.1,
+7268.1,
+7269.1,
+7270.1,
+7271.1,
+7272.1,
+7273.1,
+7274.1,
+7275.1,
+7276.1,
+7277.1,
+7278.1,
+7279.1,
+7280.1,
+7281.1,
+7282.1,
+7283.1,
+7284.1,
+7285.1,
+7286.1,
+7287.1,
+7288.1,
+7289.1,
+7290.1,
+7291.1,
+7292.1,
+7293.1,
+7294.1,
+7295.1,
+7296.1,
+7297.1,
+7298.1,
+7299.1,
+7300.1,
+7301.1,
+7302.1,
+7303.1,
+7304.1,
+7305.1,
+7306.1,
+7307.1,
+7308.1,
+7309.1,
+7310.1,
+7311.1,
+7312.1,
+7313.1,
+7314.1,
+7315.1,
+7316.1,
+7317.1,
+7318.1,
+7319.1,
+7320.1,
+7321.1,
+7322.1,
+7323.1,
+7324.1,
+7325.1,
+7326.1,
+7327.1,
+7328.1,
+7329.1,
+7330.1,
+7331.1,
+7332.1,
+7333.1,
+7334.1,
+7335.1,
+7336.1,
+7337.1,
+7338.1,
+7339.1,
+7340.1,
+7341.1,
+7342.1,
+7343.1,
+7344.1,
+7345.1,
+7346.1,
+7347.1,
+7348.1,
+7349.1,
+7350.1,
+7351.1,
+7352.1,
+7353.1,
+7354.1,
+7355.1,
+7356.1,
+7357.1,
+7358.1,
+7359.1,
+7360.1,
+7361.1,
+7362.1,
+7363.1,
+7364.1,
+7365.1,
+7366.1,
+7367.1,
+7368.1,
+7369.1,
+7370.1,
+7371.1,
+7372.1,
+7373.1,
+7374.1,
+7375.1,
+7376.1,
+7377.1,
+7378.1,
+7379.1,
+7380.1,
+7381.1,
+7382.1,
+7383.1,
+7384.1,
+7385.1,
+7386.1,
+7387.1,
+7388.1,
+7389.1,
+7390.1,
+7391.1,
+7392.1,
+7393.1,
+7394.1,
+7395.1,
+7396.1,
+7397.1,
+7398.1,
+7399.1,
+7400.1,
+7401.1,
+7402.1,
+7403.1,
+7404.1,
+7405.1,
+7406.1,
+7407.1,
+7408.1,
+7409.1,
+7410.1,
+7411.1,
+7412.1,
+7413.1,
+7414.1,
+7415.1,
+7416.1,
+7417.1,
+7418.1,
+7419.1,
+7420.1,
+7421.1,
+7422.1,
+7423.1,
+7424.1,
+7425.1,
+7426.1,
+7427.1,
+7428.1,
+7429.1,
+7430.1,
+7431.1,
+7432.1,
+7433.1,
+7434.1,
+7435.1,
+7436.1,
+7437.1,
+7438.1,
+7439.1,
+7440.1,
+7441.1,
+7442.1,
+7443.1,
+7444.1,
+7445.1,
+7446.1,
+7447.1,
+7448.1,
+7449.1,
+7450.1,
+7451.1,
+7452.1,
+7453.1,
+7454.1,
+7455.1,
+7456.1,
+7457.1,
+7458.1,
+7459.1,
+7460.1,
+7461.1,
+7462.1,
+7463.1,
+7464.1,
+7465.1,
+7466.1,
+7467.1,
+7468.1,
+7469.1,
+7470.1,
+7471.1,
+7472.1,
+7473.1,
+7474.1,
+7475.1,
+7476.1,
+7477.1,
+7478.1,
+7479.1,
+7480.1,
+7481.1,
+7482.1,
+7483.1,
+7484.1,
+7485.1,
+7486.1,
+7487.1,
+7488.1,
+7489.1,
+7490.1,
+7491.1,
+7492.1,
+7493.1,
+7494.1,
+7495.1,
+7496.1,
+7497.1,
+7498.1,
+7499.1,
+7500.1,
+7501.1,
+7502.1,
+7503.1,
+7504.1,
+7505.1,
+7506.1,
+7507.1,
+7508.1,
+7509.1,
+7510.1,
+7511.1,
+7512.1,
+7513.1,
+7514.1,
+7515.1,
+7516.1,
+7517.1,
+7518.1,
+7519.1,
+7520.1,
+7521.1,
+7522.1,
+7523.1,
+7524.1,
+7525.1,
+7526.1,
+7527.1,
+7528.1,
+7529.1,
+7530.1,
+7531.1,
+7532.1,
+7533.1,
+7534.1,
+7535.1,
+7536.1,
+7537.1,
+7538.1,
+7539.1,
+7540.1,
+7541.1,
+7542.1,
+7543.1,
+7544.1,
+7545.1,
+7546.1,
+7547.1,
+7548.1,
+7549.1,
+7550.1,
+7551.1,
+7552.1,
+7553.1,
+7554.1,
+7555.1,
+7556.1,
+7557.1,
+7558.1,
+7559.1,
+7560.1,
+7561.1,
+7562.1,
+7563.1,
+7564.1,
+7565.1,
+7566.1,
+7567.1,
+7568.1,
+7569.1,
+7570.1,
+7571.1,
+7572.1,
+7573.1,
+7574.1,
+7575.1,
+7576.1,
+7577.1,
+7578.1,
+7579.1,
+7580.1,
+7581.1,
+7582.1,
+7583.1,
+7584.1,
+7585.1,
+7586.1,
+7587.1,
+7588.1,
+7589.1,
+7590.1,
+7591.1,
+7592.1,
+7593.1,
+7594.1,
+7595.1,
+7596.1,
+7597.1,
+7598.1,
+7599.1,
+7600.1,
+7601.1,
+7602.1,
+7603.1,
+7604.1,
+7605.1,
+7606.1,
+7607.1,
+7608.1,
+7609.1,
+7610.1,
+7611.1,
+7612.1,
+7613.1,
+7614.1,
+7615.1,
+7616.1,
+7617.1,
+7618.1,
+7619.1,
+7620.1,
+7621.1,
+7622.1,
+7623.1,
+7624.1,
+7625.1,
+7626.1,
+7627.1,
+7628.1,
+7629.1,
+7630.1,
+7631.1,
+7632.1,
+7633.1,
+7634.1,
+7635.1,
+7636.1,
+7637.1,
+7638.1,
+7639.1,
+7640.1,
+7641.1,
+7642.1,
+7643.1,
+7644.1,
+7645.1,
+7646.1,
+7647.1,
+7648.1,
+7649.1,
+7650.1,
+7651.1,
+7652.1,
+7653.1,
+7654.1,
+7655.1,
+7656.1,
+7657.1,
+7658.1,
+7659.1,
+7660.1,
+7661.1,
+7662.1,
+7663.1,
+7664.1,
+7665.1,
+7666.1,
+7667.1,
+7668.1,
+7669.1,
+7670.1,
+7671.1,
+7672.1,
+7673.1,
+7674.1,
+7675.1,
+7676.1,
+7677.1,
+7678.1,
+7679.1,
+7680.1,
+7681.1,
+7682.1,
+7683.1,
+7684.1,
+7685.1,
+7686.1,
+7687.1,
+7688.1,
+7689.1,
+7690.1,
+7691.1,
+7692.1,
+7693.1,
+7694.1,
+7695.1,
+7696.1,
+7697.1,
+7698.1,
+7699.1,
+7700.1,
+7701.1,
+7702.1,
+7703.1,
+7704.1,
+7705.1,
+7706.1,
+7707.1,
+7708.1,
+7709.1,
+7710.1,
+7711.1,
+7712.1,
+7713.1,
+7714.1,
+7715.1,
+7716.1,
+7717.1,
+7718.1,
+7719.1,
+7720.1,
+7721.1,
+7722.1,
+7723.1,
+7724.1,
+7725.1,
+7726.1,
+7727.1,
+7728.1,
+7729.1,
+7730.1,
+7731.1,
+7732.1,
+7733.1,
+7734.1,
+7735.1,
+7736.1,
+7737.1,
+7738.1,
+7739.1,
+7740.1,
+7741.1,
+7742.1,
+7743.1,
+7744.1,
+7745.1,
+7746.1,
+7747.1,
+7748.1,
+7749.1,
+7750.1,
+7751.1,
+7752.1,
+7753.1,
+7754.1,
+7755.1,
+7756.1,
+7757.1,
+7758.1,
+7759.1,
+7760.1,
+7761.1,
+7762.1,
+7763.1,
+7764.1,
+7765.1,
+7766.1,
+7767.1,
+7768.1,
+7769.1,
+7770.1,
+7771.1,
+7772.1,
+7773.1,
+7774.1,
+7775.1,
+7776.1,
+7777.1,
+7778.1,
+7779.1,
+7780.1,
+7781.1,
+7782.1,
+7783.1,
+7784.1,
+7785.1,
+7786.1,
+7787.1,
+7788.1,
+7789.1,
+7790.1,
+7791.1,
+7792.1,
+7793.1,
+7794.1,
+7795.1,
+7796.1,
+7797.1,
+7798.1,
+7799.1,
+7800.1,
+7801.1,
+7802.1,
+7803.1,
+7804.1,
+7805.1,
+7806.1,
+7807.1,
+7808.1,
+7809.1,
+7810.1,
+7811.1,
+7812.1,
+7813.1,
+7814.1,
+7815.1,
+7816.1,
+7817.1,
+7818.1,
+7819.1,
+7820.1,
+7821.1,
+7822.1,
+7823.1,
+7824.1,
+7825.1,
+7826.1,
+7827.1,
+7828.1,
+7829.1,
+7830.1,
+7831.1,
+7832.1,
+7833.1,
+7834.1,
+7835.1,
+7836.1,
+7837.1,
+7838.1,
+7839.1,
+7840.1,
+7841.1,
+7842.1,
+7843.1,
+7844.1,
+7845.1,
+7846.1,
+7847.1,
+7848.1,
+7849.1,
+7850.1,
+7851.1,
+7852.1,
+7853.1,
+7854.1,
+7855.1,
+7856.1,
+7857.1,
+7858.1,
+7859.1,
+7860.1,
+7861.1,
+7862.1,
+7863.1,
+7864.1,
+7865.1,
+7866.1,
+7867.1,
+7868.1,
+7869.1,
+7870.1,
+7871.1,
+7872.1,
+7873.1,
+7874.1,
+7875.1,
+7876.1,
+7877.1,
+7878.1,
+7879.1,
+7880.1,
+7881.1,
+7882.1,
+7883.1,
+7884.1,
+7885.1,
+7886.1,
+7887.1,
+7888.1,
+7889.1,
+7890.1,
+7891.1,
+7892.1,
+7893.1,
+7894.1,
+7895.1,
+7896.1,
+7897.1,
+7898.1,
+7899.1,
+7900.1,
+7901.1,
+7902.1,
+7903.1,
+7904.1,
+7905.1,
+7906.1,
+7907.1,
+7908.1,
+7909.1,
+7910.1,
+7911.1,
+7912.1,
+7913.1,
+7914.1,
+7915.1,
+7916.1,
+7917.1,
+7918.1,
+7919.1,
+7920.1,
+7921.1,
+7922.1,
+7923.1,
+7924.1,
+7925.1,
+7926.1,
+7927.1,
+7928.1,
+7929.1,
+7930.1,
+7931.1,
+7932.1,
+7933.1,
+7934.1,
+7935.1,
+7936.1,
+7937.1,
+7938.1,
+7939.1,
+7940.1,
+7941.1,
+7942.1,
+7943.1,
+7944.1,
+7945.1,
+7946.1,
+7947.1,
+7948.1,
+7949.1,
+7950.1,
+7951.1,
+7952.1,
+7953.1,
+7954.1,
+7955.1,
+7956.1,
+7957.1,
+7958.1,
+7959.1,
+7960.1,
+7961.1,
+7962.1,
+7963.1,
+7964.1,
+7965.1,
+7966.1,
+7967.1,
+7968.1,
+7969.1,
+7970.1,
+7971.1,
+7972.1,
+7973.1,
+7974.1,
+7975.1,
+7976.1,
+7977.1,
+7978.1,
+7979.1,
+7980.1,
+7981.1,
+7982.1,
+7983.1,
+7984.1,
+7985.1,
+7986.1,
+7987.1,
+7988.1,
+7989.1,
+7990.1,
+7991.1,
+7992.1,
+7993.1,
+7994.1,
+7995.1,
+7996.1,
+7997.1,
+7998.1,
+7999.1,
+8000.1,
+8001.1,
+8002.1,
+8003.1,
+8004.1,
+8005.1,
+8006.1,
+8007.1,
+8008.1,
+8009.1,
+8010.1,
+8011.1,
+8012.1,
+8013.1,
+8014.1,
+8015.1,
+8016.1,
+8017.1,
+8018.1,
+8019.1,
+8020.1,
+8021.1,
+8022.1,
+8023.1,
+8024.1,
+8025.1,
+8026.1,
+8027.1,
+8028.1,
+8029.1,
+8030.1,
+8031.1,
+8032.1,
+8033.1,
+8034.1,
+8035.1,
+8036.1,
+8037.1,
+8038.1,
+8039.1,
+8040.1,
+8041.1,
+8042.1,
+8043.1,
+8044.1,
+8045.1,
+8046.1,
+8047.1,
+8048.1,
+8049.1,
+8050.1,
+8051.1,
+8052.1,
+8053.1,
+8054.1,
+8055.1,
+8056.1,
+8057.1,
+8058.1,
+8059.1,
+8060.1,
+8061.1,
+8062.1,
+8063.1,
+8064.1,
+8065.1,
+8066.1,
+8067.1,
+8068.1,
+8069.1,
+8070.1,
+8071.1,
+8072.1,
+8073.1,
+8074.1,
+8075.1,
+8076.1,
+8077.1,
+8078.1,
+8079.1,
+8080.1,
+8081.1,
+8082.1,
+8083.1,
+8084.1,
+8085.1,
+8086.1,
+8087.1,
+8088.1,
+8089.1,
+8090.1,
+8091.1,
+8092.1,
+8093.1,
+8094.1,
+8095.1,
+8096.1,
+8097.1,
+8098.1,
+8099.1,
+8100.1,
+8101.1,
+8102.1,
+8103.1,
+8104.1,
+8105.1,
+8106.1,
+8107.1,
+8108.1,
+8109.1,
+8110.1,
+8111.1,
+8112.1,
+8113.1,
+8114.1,
+8115.1,
+8116.1,
+8117.1,
+8118.1,
+8119.1,
+8120.1,
+8121.1,
+8122.1,
+8123.1,
+8124.1,
+8125.1,
+8126.1,
+8127.1,
+8128.1,
+8129.1,
+8130.1,
+8131.1,
+8132.1,
+8133.1,
+8134.1,
+8135.1,
+8136.1,
+8137.1,
+8138.1,
+8139.1,
+8140.1,
+8141.1,
+8142.1,
+8143.1,
+8144.1,
+8145.1,
+8146.1,
+8147.1,
+8148.1,
+8149.1,
+8150.1,
+8151.1,
+8152.1,
+8153.1,
+8154.1,
+8155.1,
+8156.1,
+8157.1,
+8158.1,
+8159.1,
+8160.1,
+8161.1,
+8162.1,
+8163.1,
+8164.1,
+8165.1,
+8166.1,
+8167.1,
+8168.1,
+8169.1,
+8170.1,
+8171.1,
+8172.1,
+8173.1,
+8174.1,
+8175.1,
+8176.1,
+8177.1,
+8178.1,
+8179.1,
+8180.1,
+8181.1,
+8182.1,
+8183.1,
+8184.1,
+8185.1,
+8186.1,
+8187.1,
+8188.1,
+8189.1,
+8190.1,
+8191.1,
+8192.1,
+8193.1,
+8194.1,
+8195.1,
+8196.1,
+8197.1,
+8198.1,
+8199.1,
+8200.1,
+8201.1,
+8202.1,
+8203.1,
+8204.1,
+8205.1,
+8206.1,
+8207.1,
+8208.1,
+8209.1,
+8210.1,
+8211.1,
+8212.1,
+8213.1,
+8214.1,
+8215.1,
+8216.1,
+8217.1,
+8218.1,
+8219.1,
+8220.1,
+8221.1,
+8222.1,
+8223.1,
+8224.1,
+8225.1,
+8226.1,
+8227.1,
+8228.1,
+8229.1,
+8230.1,
+8231.1,
+8232.1,
+8233.1,
+8234.1,
+8235.1,
+8236.1,
+8237.1,
+8238.1,
+8239.1,
+8240.1,
+8241.1,
+8242.1,
+8243.1,
+8244.1,
+8245.1,
+8246.1,
+8247.1,
+8248.1,
+8249.1,
+8250.1,
+8251.1,
+8252.1,
+8253.1,
+8254.1,
+8255.1,
+8256.1,
+8257.1,
+8258.1,
+8259.1,
+8260.1,
+8261.1,
+8262.1,
+8263.1,
+8264.1,
+8265.1,
+8266.1,
+8267.1,
+8268.1,
+8269.1,
+8270.1,
+8271.1,
+8272.1,
+8273.1,
+8274.1,
+8275.1,
+8276.1,
+8277.1,
+8278.1,
+8279.1,
+8280.1,
+8281.1,
+8282.1,
+8283.1,
+8284.1,
+8285.1,
+8286.1,
+8287.1,
+8288.1,
+8289.1,
+8290.1,
+8291.1,
+8292.1,
+8293.1,
+8294.1,
+8295.1,
+8296.1,
+8297.1,
+8298.1,
+8299.1,
+8300.1,
+8301.1,
+8302.1,
+8303.1,
+8304.1,
+8305.1,
+8306.1,
+8307.1,
+8308.1,
+8309.1,
+8310.1,
+8311.1,
+8312.1,
+8313.1,
+8314.1,
+8315.1,
+8316.1,
+8317.1,
+8318.1,
+8319.1,
+8320.1,
+8321.1,
+8322.1,
+8323.1,
+8324.1,
+8325.1,
+8326.1,
+8327.1,
+8328.1,
+8329.1,
+8330.1,
+8331.1,
+8332.1,
+8333.1,
+8334.1,
+8335.1,
+8336.1,
+8337.1,
+8338.1,
+8339.1,
+8340.1,
+8341.1,
+8342.1,
+8343.1,
+8344.1,
+8345.1,
+8346.1,
+8347.1,
+8348.1,
+8349.1,
+8350.1,
+8351.1,
+8352.1,
+8353.1,
+8354.1,
+8355.1,
+8356.1,
+8357.1,
+8358.1,
+8359.1,
+8360.1,
+8361.1,
+8362.1,
+8363.1,
+8364.1,
+8365.1,
+8366.1,
+8367.1,
+8368.1,
+8369.1,
+8370.1,
+8371.1,
+8372.1,
+8373.1,
+8374.1,
+8375.1,
+8376.1,
+8377.1,
+8378.1,
+8379.1,
+8380.1,
+8381.1,
+8382.1,
+8383.1,
+8384.1,
+8385.1,
+8386.1,
+8387.1,
+8388.1,
+8389.1,
+8390.1,
+8391.1,
+8392.1,
+8393.1,
+8394.1,
+8395.1,
+8396.1,
+8397.1,
+8398.1,
+8399.1,
+8400.1,
+8401.1,
+8402.1,
+8403.1,
+8404.1,
+8405.1,
+8406.1,
+8407.1,
+8408.1,
+8409.1,
+8410.1,
+8411.1,
+8412.1,
+8413.1,
+8414.1,
+8415.1,
+8416.1,
+8417.1,
+8418.1,
+8419.1,
+8420.1,
+8421.1,
+8422.1,
+8423.1,
+8424.1,
+8425.1,
+8426.1,
+8427.1,
+8428.1,
+8429.1,
+8430.1,
+8431.1,
+8432.1,
+8433.1,
+8434.1,
+8435.1,
+8436.1,
+8437.1,
+8438.1,
+8439.1,
+8440.1,
+8441.1,
+8442.1,
+8443.1,
+8444.1,
+8445.1,
+8446.1,
+8447.1,
+8448.1,
+8449.1,
+8450.1,
+8451.1,
+8452.1,
+8453.1,
+8454.1,
+8455.1,
+8456.1,
+8457.1,
+8458.1,
+8459.1,
+8460.1,
+8461.1,
+8462.1,
+8463.1,
+8464.1,
+8465.1,
+8466.1,
+8467.1,
+8468.1,
+8469.1,
+8470.1,
+8471.1,
+8472.1,
+8473.1,
+8474.1,
+8475.1,
+8476.1,
+8477.1,
+8478.1,
+8479.1,
+8480.1,
+8481.1,
+8482.1,
+8483.1,
+8484.1,
+8485.1,
+8486.1,
+8487.1,
+8488.1,
+8489.1,
+8490.1,
+8491.1,
+8492.1,
+8493.1,
+8494.1,
+8495.1,
+8496.1,
+8497.1,
+8498.1,
+8499.1,
+8500.1,
+8501.1,
+8502.1,
+8503.1,
+8504.1,
+8505.1,
+8506.1,
+8507.1,
+8508.1,
+8509.1,
+8510.1,
+8511.1,
+8512.1,
+8513.1,
+8514.1,
+8515.1,
+8516.1,
+8517.1,
+8518.1,
+8519.1,
+8520.1,
+8521.1,
+8522.1,
+8523.1,
+8524.1,
+8525.1,
+8526.1,
+8527.1,
+8528.1,
+8529.1,
+8530.1,
+8531.1,
+8532.1,
+8533.1,
+8534.1,
+8535.1,
+8536.1,
+8537.1,
+8538.1,
+8539.1,
+8540.1,
+8541.1,
+8542.1,
+8543.1,
+8544.1,
+8545.1,
+8546.1,
+8547.1,
+8548.1,
+8549.1,
+8550.1,
+8551.1,
+8552.1,
+8553.1,
+8554.1,
+8555.1,
+8556.1,
+8557.1,
+8558.1,
+8559.1,
+8560.1,
+8561.1,
+8562.1,
+8563.1,
+8564.1,
+8565.1,
+8566.1,
+8567.1,
+8568.1,
+8569.1,
+8570.1,
+8571.1,
+8572.1,
+8573.1,
+8574.1,
+8575.1,
+8576.1,
+8577.1,
+8578.1,
+8579.1,
+8580.1,
+8581.1,
+8582.1,
+8583.1,
+8584.1,
+8585.1,
+8586.1,
+8587.1,
+8588.1,
+8589.1,
+8590.1,
+8591.1,
+8592.1,
+8593.1,
+8594.1,
+8595.1,
+8596.1,
+8597.1,
+8598.1,
+8599.1,
+8600.1,
+8601.1,
+8602.1,
+8603.1,
+8604.1,
+8605.1,
+8606.1,
+8607.1,
+8608.1,
+8609.1,
+8610.1,
+8611.1,
+8612.1,
+8613.1,
+8614.1,
+8615.1,
+8616.1,
+8617.1,
+8618.1,
+8619.1,
+8620.1,
+8621.1,
+8622.1,
+8623.1,
+8624.1,
+8625.1,
+8626.1,
+8627.1,
+8628.1,
+8629.1,
+8630.1,
+8631.1,
+8632.1,
+8633.1,
+8634.1,
+8635.1,
+8636.1,
+8637.1,
+8638.1,
+8639.1,
+8640.1,
+8641.1,
+8642.1,
+8643.1,
+8644.1,
+8645.1,
+8646.1,
+8647.1,
+8648.1,
+8649.1,
+8650.1,
+8651.1,
+8652.1,
+8653.1,
+8654.1,
+8655.1,
+8656.1,
+8657.1,
+8658.1,
+8659.1,
+8660.1,
+8661.1,
+8662.1,
+8663.1,
+8664.1,
+8665.1,
+8666.1,
+8667.1,
+8668.1,
+8669.1,
+8670.1,
+8671.1,
+8672.1,
+8673.1,
+8674.1,
+8675.1,
+8676.1,
+8677.1,
+8678.1,
+8679.1,
+8680.1,
+8681.1,
+8682.1,
+8683.1,
+8684.1,
+8685.1,
+8686.1,
+8687.1,
+8688.1,
+8689.1,
+8690.1,
+8691.1,
+8692.1,
+8693.1,
+8694.1,
+8695.1,
+8696.1,
+8697.1,
+8698.1,
+8699.1,
+8700.1,
+8701.1,
+8702.1,
+8703.1,
+8704.1,
+8705.1,
+8706.1,
+8707.1,
+8708.1,
+8709.1,
+8710.1,
+8711.1,
+8712.1,
+8713.1,
+8714.1,
+8715.1,
+8716.1,
+8717.1,
+8718.1,
+8719.1,
+8720.1,
+8721.1,
+8722.1,
+8723.1,
+8724.1,
+8725.1,
+8726.1,
+8727.1,
+8728.1,
+8729.1,
+8730.1,
+8731.1,
+8732.1,
+8733.1,
+8734.1,
+8735.1,
+8736.1,
+8737.1,
+8738.1,
+8739.1,
+8740.1,
+8741.1,
+8742.1,
+8743.1,
+8744.1,
+8745.1,
+8746.1,
+8747.1,
+8748.1,
+8749.1,
+8750.1,
+8751.1,
+8752.1,
+8753.1,
+8754.1,
+8755.1,
+8756.1,
+8757.1,
+8758.1,
+8759.1,
+8760.1,
+8761.1,
+8762.1,
+8763.1,
+8764.1,
+8765.1,
+8766.1,
+8767.1,
+8768.1,
+8769.1,
+8770.1,
+8771.1,
+8772.1,
+8773.1,
+8774.1,
+8775.1,
+8776.1,
+8777.1,
+8778.1,
+8779.1,
+8780.1,
+8781.1,
+8782.1,
+8783.1,
+8784.1,
+8785.1,
+8786.1,
+8787.1,
+8788.1,
+8789.1,
+8790.1,
+8791.1,
+8792.1,
+8793.1,
+8794.1,
+8795.1,
+8796.1,
+8797.1,
+8798.1,
+8799.1,
+8800.1,
+8801.1,
+8802.1,
+8803.1,
+8804.1,
+8805.1,
+8806.1,
+8807.1,
+8808.1,
+8809.1,
+8810.1,
+8811.1,
+8812.1,
+8813.1,
+8814.1,
+8815.1,
+8816.1,
+8817.1,
+8818.1,
+8819.1,
+8820.1,
+8821.1,
+8822.1,
+8823.1,
+8824.1,
+8825.1,
+8826.1,
+8827.1,
+8828.1,
+8829.1,
+8830.1,
+8831.1,
+8832.1,
+8833.1,
+8834.1,
+8835.1,
+8836.1,
+8837.1,
+8838.1,
+8839.1,
+8840.1,
+8841.1,
+8842.1,
+8843.1,
+8844.1,
+8845.1,
+8846.1,
+8847.1,
+8848.1,
+8849.1,
+8850.1,
+8851.1,
+8852.1,
+8853.1,
+8854.1,
+8855.1,
+8856.1,
+8857.1,
+8858.1,
+8859.1,
+8860.1,
+8861.1,
+8862.1,
+8863.1,
+8864.1,
+8865.1,
+8866.1,
+8867.1,
+8868.1,
+8869.1,
+8870.1,
+8871.1,
+8872.1,
+8873.1,
+8874.1,
+8875.1,
+8876.1,
+8877.1,
+8878.1,
+8879.1,
+8880.1,
+8881.1,
+8882.1,
+8883.1,
+8884.1,
+8885.1,
+8886.1,
+8887.1,
+8888.1,
+8889.1,
+8890.1,
+8891.1,
+8892.1,
+8893.1,
+8894.1,
+8895.1,
+8896.1,
+8897.1,
+8898.1,
+8899.1,
+8900.1,
+8901.1,
+8902.1,
+8903.1,
+8904.1,
+8905.1,
+8906.1,
+8907.1,
+8908.1,
+8909.1,
+8910.1,
+8911.1,
+8912.1,
+8913.1,
+8914.1,
+8915.1,
+8916.1,
+8917.1,
+8918.1,
+8919.1,
+8920.1,
+8921.1,
+8922.1,
+8923.1,
+8924.1,
+8925.1,
+8926.1,
+8927.1,
+8928.1,
+8929.1,
+8930.1,
+8931.1,
+8932.1,
+8933.1,
+8934.1,
+8935.1,
+8936.1,
+8937.1,
+8938.1,
+8939.1,
+8940.1,
+8941.1,
+8942.1,
+8943.1,
+8944.1,
+8945.1,
+8946.1,
+8947.1,
+8948.1,
+8949.1,
+8950.1,
+8951.1,
+8952.1,
+8953.1,
+8954.1,
+8955.1,
+8956.1,
+8957.1,
+8958.1,
+8959.1,
+8960.1,
+8961.1,
+8962.1,
+8963.1,
+8964.1,
+8965.1,
+8966.1,
+8967.1,
+8968.1,
+8969.1,
+8970.1,
+8971.1,
+8972.1,
+8973.1,
+8974.1,
+8975.1,
+8976.1,
+8977.1,
+8978.1,
+8979.1,
+8980.1,
+8981.1,
+8982.1,
+8983.1,
+8984.1,
+8985.1,
+8986.1,
+8987.1,
+8988.1,
+8989.1,
+8990.1,
+8991.1,
+8992.1,
+8993.1,
+8994.1,
+8995.1,
+8996.1,
+8997.1,
+8998.1,
+8999.1,
+9000.1,
+9001.1,
+9002.1,
+9003.1,
+9004.1,
+9005.1,
+9006.1,
+9007.1,
+9008.1,
+9009.1,
+9010.1,
+9011.1,
+9012.1,
+9013.1,
+9014.1,
+9015.1,
+9016.1,
+9017.1,
+9018.1,
+9019.1,
+9020.1,
+9021.1,
+9022.1,
+9023.1,
+9024.1,
+9025.1,
+9026.1,
+9027.1,
+9028.1,
+9029.1,
+9030.1,
+9031.1,
+9032.1,
+9033.1,
+9034.1,
+9035.1,
+9036.1,
+9037.1,
+9038.1,
+9039.1,
+9040.1,
+9041.1,
+9042.1,
+9043.1,
+9044.1,
+9045.1,
+9046.1,
+9047.1,
+9048.1,
+9049.1,
+9050.1,
+9051.1,
+9052.1,
+9053.1,
+9054.1,
+9055.1,
+9056.1,
+9057.1,
+9058.1,
+9059.1,
+9060.1,
+9061.1,
+9062.1,
+9063.1,
+9064.1,
+9065.1,
+9066.1,
+9067.1,
+9068.1,
+9069.1,
+9070.1,
+9071.1,
+9072.1,
+9073.1,
+9074.1,
+9075.1,
+9076.1,
+9077.1,
+9078.1,
+9079.1,
+9080.1,
+9081.1,
+9082.1,
+9083.1,
+9084.1,
+9085.1,
+9086.1,
+9087.1,
+9088.1,
+9089.1,
+9090.1,
+9091.1,
+9092.1,
+9093.1,
+9094.1,
+9095.1,
+9096.1,
+9097.1,
+9098.1,
+9099.1,
+9100.1,
+9101.1,
+9102.1,
+9103.1,
+9104.1,
+9105.1,
+9106.1,
+9107.1,
+9108.1,
+9109.1,
+9110.1,
+9111.1,
+9112.1,
+9113.1,
+9114.1,
+9115.1,
+9116.1,
+9117.1,
+9118.1,
+9119.1,
+9120.1,
+9121.1,
+9122.1,
+9123.1,
+9124.1,
+9125.1,
+9126.1,
+9127.1,
+9128.1,
+9129.1,
+9130.1,
+9131.1,
+9132.1,
+9133.1,
+9134.1,
+9135.1,
+9136.1,
+9137.1,
+9138.1,
+9139.1,
+9140.1,
+9141.1,
+9142.1,
+9143.1,
+9144.1,
+9145.1,
+9146.1,
+9147.1,
+9148.1,
+9149.1,
+9150.1,
+9151.1,
+9152.1,
+9153.1,
+9154.1,
+9155.1,
+9156.1,
+9157.1,
+9158.1,
+9159.1,
+9160.1,
+9161.1,
+9162.1,
+9163.1,
+9164.1,
+9165.1,
+9166.1,
+9167.1,
+9168.1,
+9169.1,
+9170.1,
+9171.1,
+9172.1,
+9173.1,
+9174.1,
+9175.1,
+9176.1,
+9177.1,
+9178.1,
+9179.1,
+9180.1,
+9181.1,
+9182.1,
+9183.1,
+9184.1,
+9185.1,
+9186.1,
+9187.1,
+9188.1,
+9189.1,
+9190.1,
+9191.1,
+9192.1,
+9193.1,
+9194.1,
+9195.1,
+9196.1,
+9197.1,
+9198.1,
+9199.1,
+9200.1,
+9201.1,
+9202.1,
+9203.1,
+9204.1,
+9205.1,
+9206.1,
+9207.1,
+9208.1,
+9209.1,
+9210.1,
+9211.1,
+9212.1,
+9213.1,
+9214.1,
+9215.1,
+9216.1,
+9217.1,
+9218.1,
+9219.1,
+9220.1,
+9221.1,
+9222.1,
+9223.1,
+9224.1,
+9225.1,
+9226.1,
+9227.1,
+9228.1,
+9229.1,
+9230.1,
+9231.1,
+9232.1,
+9233.1,
+9234.1,
+9235.1,
+9236.1,
+9237.1,
+9238.1,
+9239.1,
+9240.1,
+9241.1,
+9242.1,
+9243.1,
+9244.1,
+9245.1,
+9246.1,
+9247.1,
+9248.1,
+9249.1,
+9250.1,
+9251.1,
+9252.1,
+9253.1,
+9254.1,
+9255.1,
+9256.1,
+9257.1,
+9258.1,
+9259.1,
+9260.1,
+9261.1,
+9262.1,
+9263.1,
+9264.1,
+9265.1,
+9266.1,
+9267.1,
+9268.1,
+9269.1,
+9270.1,
+9271.1,
+9272.1,
+9273.1,
+9274.1,
+9275.1,
+9276.1,
+9277.1,
+9278.1,
+9279.1,
+9280.1,
+9281.1,
+9282.1,
+9283.1,
+9284.1,
+9285.1,
+9286.1,
+9287.1,
+9288.1,
+9289.1,
+9290.1,
+9291.1,
+9292.1,
+9293.1,
+9294.1,
+9295.1,
+9296.1,
+9297.1,
+9298.1,
+9299.1,
+9300.1,
+9301.1,
+9302.1,
+9303.1,
+9304.1,
+9305.1,
+9306.1,
+9307.1,
+9308.1,
+9309.1,
+9310.1,
+9311.1,
+9312.1,
+9313.1,
+9314.1,
+9315.1,
+9316.1,
+9317.1,
+9318.1,
+9319.1,
+9320.1,
+9321.1,
+9322.1,
+9323.1,
+9324.1,
+9325.1,
+9326.1,
+9327.1,
+9328.1,
+9329.1,
+9330.1,
+9331.1,
+9332.1,
+9333.1,
+9334.1,
+9335.1,
+9336.1,
+9337.1,
+9338.1,
+9339.1,
+9340.1,
+9341.1,
+9342.1,
+9343.1,
+9344.1,
+9345.1,
+9346.1,
+9347.1,
+9348.1,
+9349.1,
+9350.1,
+9351.1,
+9352.1,
+9353.1,
+9354.1,
+9355.1,
+9356.1,
+9357.1,
+9358.1,
+9359.1,
+9360.1,
+9361.1,
+9362.1,
+9363.1,
+9364.1,
+9365.1,
+9366.1,
+9367.1,
+9368.1,
+9369.1,
+9370.1,
+9371.1,
+9372.1,
+9373.1,
+9374.1,
+9375.1,
+9376.1,
+9377.1,
+9378.1,
+9379.1,
+9380.1,
+9381.1,
+9382.1,
+9383.1,
+9384.1,
+9385.1,
+9386.1,
+9387.1,
+9388.1,
+9389.1,
+9390.1,
+9391.1,
+9392.1,
+9393.1,
+9394.1,
+9395.1,
+9396.1,
+9397.1,
+9398.1,
+9399.1,
+9400.1,
+9401.1,
+9402.1,
+9403.1,
+9404.1,
+9405.1,
+9406.1,
+9407.1,
+9408.1,
+9409.1,
+9410.1,
+9411.1,
+9412.1,
+9413.1,
+9414.1,
+9415.1,
+9416.1,
+9417.1,
+9418.1,
+9419.1,
+9420.1,
+9421.1,
+9422.1,
+9423.1,
+9424.1,
+9425.1,
+9426.1,
+9427.1,
+9428.1,
+9429.1,
+9430.1,
+9431.1,
+9432.1,
+9433.1,
+9434.1,
+9435.1,
+9436.1,
+9437.1,
+9438.1,
+9439.1,
+9440.1,
+9441.1,
+9442.1,
+9443.1,
+9444.1,
+9445.1,
+9446.1,
+9447.1,
+9448.1,
+9449.1,
+9450.1,
+9451.1,
+9452.1,
+9453.1,
+9454.1,
+9455.1,
+9456.1,
+9457.1,
+9458.1,
+9459.1,
+9460.1,
+9461.1,
+9462.1,
+9463.1,
+9464.1,
+9465.1,
+9466.1,
+9467.1,
+9468.1,
+9469.1,
+9470.1,
+9471.1,
+9472.1,
+9473.1,
+9474.1,
+9475.1,
+9476.1,
+9477.1,
+9478.1,
+9479.1,
+9480.1,
+9481.1,
+9482.1,
+9483.1,
+9484.1,
+9485.1,
+9486.1,
+9487.1,
+9488.1,
+9489.1,
+9490.1,
+9491.1,
+9492.1,
+9493.1,
+9494.1,
+9495.1,
+9496.1,
+9497.1,
+9498.1,
+9499.1,
+9500.1,
+9501.1,
+9502.1,
+9503.1,
+9504.1,
+9505.1,
+9506.1,
+9507.1,
+9508.1,
+9509.1,
+9510.1,
+9511.1,
+9512.1,
+9513.1,
+9514.1,
+9515.1,
+9516.1,
+9517.1,
+9518.1,
+9519.1,
+9520.1,
+9521.1,
+9522.1,
+9523.1,
+9524.1,
+9525.1,
+9526.1,
+9527.1,
+9528.1,
+9529.1,
+9530.1,
+9531.1,
+9532.1,
+9533.1,
+9534.1,
+9535.1,
+9536.1,
+9537.1,
+9538.1,
+9539.1,
+9540.1,
+9541.1,
+9542.1,
+9543.1,
+9544.1,
+9545.1,
+9546.1,
+9547.1,
+9548.1,
+9549.1,
+9550.1,
+9551.1,
+9552.1,
+9553.1,
+9554.1,
+9555.1,
+9556.1,
+9557.1,
+9558.1,
+9559.1,
+9560.1,
+9561.1,
+9562.1,
+9563.1,
+9564.1,
+9565.1,
+9566.1,
+9567.1,
+9568.1,
+9569.1,
+9570.1,
+9571.1,
+9572.1,
+9573.1,
+9574.1,
+9575.1,
+9576.1,
+9577.1,
+9578.1,
+9579.1,
+9580.1,
+9581.1,
+9582.1,
+9583.1,
+9584.1,
+9585.1,
+9586.1,
+9587.1,
+9588.1,
+9589.1,
+9590.1,
+9591.1,
+9592.1,
+9593.1,
+9594.1,
+9595.1,
+9596.1,
+9597.1,
+9598.1,
+9599.1,
+9600.1,
+9601.1,
+9602.1,
+9603.1,
+9604.1,
+9605.1,
+9606.1,
+9607.1,
+9608.1,
+9609.1,
+9610.1,
+9611.1,
+9612.1,
+9613.1,
+9614.1,
+9615.1,
+9616.1,
+9617.1,
+9618.1,
+9619.1,
+9620.1,
+9621.1,
+9622.1,
+9623.1,
+9624.1,
+9625.1,
+9626.1,
+9627.1,
+9628.1,
+9629.1,
+9630.1,
+9631.1,
+9632.1,
+9633.1,
+9634.1,
+9635.1,
+9636.1,
+9637.1,
+9638.1,
+9639.1,
+9640.1,
+9641.1,
+9642.1,
+9643.1,
+9644.1,
+9645.1,
+9646.1,
+9647.1,
+9648.1,
+9649.1,
+9650.1,
+9651.1,
+9652.1,
+9653.1,
+9654.1,
+9655.1,
+9656.1,
+9657.1,
+9658.1,
+9659.1,
+9660.1,
+9661.1,
+9662.1,
+9663.1,
+9664.1,
+9665.1,
+9666.1,
+9667.1,
+9668.1,
+9669.1,
+9670.1,
+9671.1,
+9672.1,
+9673.1,
+9674.1,
+9675.1,
+9676.1,
+9677.1,
+9678.1,
+9679.1,
+9680.1,
+9681.1,
+9682.1,
+9683.1,
+9684.1,
+9685.1,
+9686.1,
+9687.1,
+9688.1,
+9689.1,
+9690.1,
+9691.1,
+9692.1,
+9693.1,
+9694.1,
+9695.1,
+9696.1,
+9697.1,
+9698.1,
+9699.1,
+9700.1,
+9701.1,
+9702.1,
+9703.1,
+9704.1,
+9705.1,
+9706.1,
+9707.1,
+9708.1,
+9709.1,
+9710.1,
+9711.1,
+9712.1,
+9713.1,
+9714.1,
+9715.1,
+9716.1,
+9717.1,
+9718.1,
+9719.1,
+9720.1,
+9721.1,
+9722.1,
+9723.1,
+9724.1,
+9725.1,
+9726.1,
+9727.1,
+9728.1,
+9729.1,
+9730.1,
+9731.1,
+9732.1,
+9733.1,
+9734.1,
+9735.1,
+9736.1,
+9737.1,
+9738.1,
+9739.1,
+9740.1,
+9741.1,
+9742.1,
+9743.1,
+9744.1,
+9745.1,
+9746.1,
+9747.1,
+9748.1,
+9749.1,
+9750.1,
+9751.1,
+9752.1,
+9753.1,
+9754.1,
+9755.1,
+9756.1,
+9757.1,
+9758.1,
+9759.1,
+9760.1,
+9761.1,
+9762.1,
+9763.1,
+9764.1,
+9765.1,
+9766.1,
+9767.1,
+9768.1,
+9769.1,
+9770.1,
+9771.1,
+9772.1,
+9773.1,
+9774.1,
+9775.1,
+9776.1,
+9777.1,
+9778.1,
+9779.1,
+9780.1,
+9781.1,
+9782.1,
+9783.1,
+9784.1,
+9785.1,
+9786.1,
+9787.1,
+9788.1,
+9789.1,
+9790.1,
+9791.1,
+9792.1,
+9793.1,
+9794.1,
+9795.1,
+9796.1,
+9797.1,
+9798.1,
+9799.1,
+9800.1,
+9801.1,
+9802.1,
+9803.1,
+9804.1,
+9805.1,
+9806.1,
+9807.1,
+9808.1,
+9809.1,
+9810.1,
+9811.1,
+9812.1,
+9813.1,
+9814.1,
+9815.1,
+9816.1,
+9817.1,
+9818.1,
+9819.1,
+9820.1,
+9821.1,
+9822.1,
+9823.1,
+9824.1,
+9825.1,
+9826.1,
+9827.1,
+9828.1,
+9829.1,
+9830.1,
+9831.1,
+9832.1,
+9833.1,
+9834.1,
+9835.1,
+9836.1,
+9837.1,
+9838.1,
+9839.1,
+9840.1,
+9841.1,
+9842.1,
+9843.1,
+9844.1,
+9845.1,
+9846.1,
+9847.1,
+9848.1,
+9849.1,
+9850.1,
+9851.1,
+9852.1,
+9853.1,
+9854.1,
+9855.1,
+9856.1,
+9857.1,
+9858.1,
+9859.1,
+9860.1,
+9861.1,
+9862.1,
+9863.1,
+9864.1,
+9865.1,
+9866.1,
+9867.1,
+9868.1,
+9869.1,
+9870.1,
+9871.1,
+9872.1,
+9873.1,
+9874.1,
+9875.1,
+9876.1,
+9877.1,
+9878.1,
+9879.1,
+9880.1,
+9881.1,
+9882.1,
+9883.1,
+9884.1,
+9885.1,
+9886.1,
+9887.1,
+9888.1,
+9889.1,
+9890.1,
+9891.1,
+9892.1,
+9893.1,
+9894.1,
+9895.1,
+9896.1,
+9897.1,
+9898.1,
+9899.1,
+9900.1,
+9901.1,
+9902.1,
+9903.1,
+9904.1,
+9905.1,
+9906.1,
+9907.1,
+9908.1,
+9909.1,
+9910.1,
+9911.1,
+9912.1,
+9913.1,
+9914.1,
+9915.1,
+9916.1,
+9917.1,
+9918.1,
+9919.1,
+9920.1,
+9921.1,
+9922.1,
+9923.1,
+9924.1,
+9925.1,
+9926.1,
+9927.1,
+9928.1,
+9929.1,
+9930.1,
+9931.1,
+9932.1,
+9933.1,
+9934.1,
+9935.1,
+9936.1,
+9937.1,
+9938.1,
+9939.1,
+9940.1,
+9941.1,
+9942.1,
+9943.1,
+9944.1,
+9945.1,
+9946.1,
+9947.1,
+9948.1,
+9949.1,
+9950.1,
+9951.1,
+9952.1,
+9953.1,
+9954.1,
+9955.1,
+9956.1,
+9957.1,
+9958.1,
+9959.1,
+9960.1,
+9961.1,
+9962.1,
+9963.1,
+9964.1,
+9965.1,
+9966.1,
+9967.1,
+9968.1,
+9969.1,
+9970.1,
+9971.1,
+9972.1,
+9973.1,
+9974.1,
+9975.1,
+9976.1,
+9977.1,
+9978.1,
+9979.1,
+9980.1,
+9981.1,
+9982.1,
+9983.1,
+9984.1,
+9985.1,
+9986.1,
+9987.1,
+9988.1,
+9989.1,
+9990.1,
+9991.1,
+9992.1,
+9993.1,
+9994.1,
+9995.1,
+9996.1,
+9997.1,
+9998.1,
+9999.1
+];
+
+var largeObject = [
+true,
+1,
+1.234,
+null,
+undefined,
+,
+"string0",
+"string1",
+"string2",
+"string3",
+"string4",
+"string5",
+"string6",
+"string7",
+"string8",
+"string9",
+"string10",
+"string11",
+"string12",
+"string13",
+"string14",
+"string15",
+"string16",
+"string17",
+"string18",
+"string19",
+"string20",
+"string21",
+"string22",
+"string23",
+"string24",
+"string25",
+"string26",
+"string27",
+"string28",
+"string29",
+"string30",
+"string31",
+"string32",
+"string33",
+"string34",
+"string35",
+"string36",
+"string37",
+"string38",
+"string39",
+"string40",
+"string41",
+"string42",
+"string43",
+"string44",
+"string45",
+"string46",
+"string47",
+"string48",
+"string49",
+"string50",
+"string51",
+"string52",
+"string53",
+"string54",
+"string55",
+"string56",
+"string57",
+"string58",
+"string59",
+"string60",
+"string61",
+"string62",
+"string63",
+"string64",
+"string65",
+"string66",
+"string67",
+"string68",
+"string69",
+"string70",
+"string71",
+"string72",
+"string73",
+"string74",
+"string75",
+"string76",
+"string77",
+"string78",
+"string79",
+"string80",
+"string81",
+"string82",
+"string83",
+"string84",
+"string85",
+"string86",
+"string87",
+"string88",
+"string89",
+"string90",
+"string91",
+"string92",
+"string93",
+"string94",
+"string95",
+"string96",
+"string97",
+"string98",
+"string99",
+"string100",
+"string101",
+"string102",
+"string103",
+"string104",
+"string105",
+"string106",
+"string107",
+"string108",
+"string109",
+"string110",
+"string111",
+"string112",
+"string113",
+"string114",
+"string115",
+"string116",
+"string117",
+"string118",
+"string119",
+"string120",
+"string121",
+"string122",
+"string123",
+"string124",
+"string125",
+"string126",
+"string127",
+"string128",
+"string129",
+"string130",
+"string131",
+"string132",
+"string133",
+"string134",
+"string135",
+"string136",
+"string137",
+"string138",
+"string139",
+"string140",
+"string141",
+"string142",
+"string143",
+"string144",
+"string145",
+"string146",
+"string147",
+"string148",
+"string149",
+"string150",
+"string151",
+"string152",
+"string153",
+"string154",
+"string155",
+"string156",
+"string157",
+"string158",
+"string159",
+"string160",
+"string161",
+"string162",
+"string163",
+"string164",
+"string165",
+"string166",
+"string167",
+"string168",
+"string169",
+"string170",
+"string171",
+"string172",
+"string173",
+"string174",
+"string175",
+"string176",
+"string177",
+"string178",
+"string179",
+"string180",
+"string181",
+"string182",
+"string183",
+"string184",
+"string185",
+"string186",
+"string187",
+"string188",
+"string189",
+"string190",
+"string191",
+"string192",
+"string193",
+"string194",
+"string195",
+"string196",
+"string197",
+"string198",
+"string199",
+"string200",
+"string201",
+"string202",
+"string203",
+"string204",
+"string205",
+"string206",
+"string207",
+"string208",
+"string209",
+"string210",
+"string211",
+"string212",
+"string213",
+"string214",
+"string215",
+"string216",
+"string217",
+"string218",
+"string219",
+"string220",
+"string221",
+"string222",
+"string223",
+"string224",
+"string225",
+"string226",
+"string227",
+"string228",
+"string229",
+"string230",
+"string231",
+"string232",
+"string233",
+"string234",
+"string235",
+"string236",
+"string237",
+"string238",
+"string239",
+"string240",
+"string241",
+"string242",
+"string243",
+"string244",
+"string245",
+"string246",
+"string247",
+"string248",
+"string249",
+"string250",
+"string251",
+"string252",
+"string253",
+"string254",
+"string255",
+"string256",
+"string257",
+"string258",
+"string259",
+"string260",
+"string261",
+"string262",
+"string263",
+"string264",
+"string265",
+"string266",
+"string267",
+"string268",
+"string269",
+"string270",
+"string271",
+"string272",
+"string273",
+"string274",
+"string275",
+"string276",
+"string277",
+"string278",
+"string279",
+"string280",
+"string281",
+"string282",
+"string283",
+"string284",
+"string285",
+"string286",
+"string287",
+"string288",
+"string289",
+"string290",
+"string291",
+"string292",
+"string293",
+"string294",
+"string295",
+"string296",
+"string297",
+"string298",
+"string299",
+"string300",
+"string301",
+"string302",
+"string303",
+"string304",
+"string305",
+"string306",
+"string307",
+"string308",
+"string309",
+"string310",
+"string311",
+"string312",
+"string313",
+"string314",
+"string315",
+"string316",
+"string317",
+"string318",
+"string319",
+"string320",
+"string321",
+"string322",
+"string323",
+"string324",
+"string325",
+"string326",
+"string327",
+"string328",
+"string329",
+"string330",
+"string331",
+"string332",
+"string333",
+"string334",
+"string335",
+"string336",
+"string337",
+"string338",
+"string339",
+"string340",
+"string341",
+"string342",
+"string343",
+"string344",
+"string345",
+"string346",
+"string347",
+"string348",
+"string349",
+"string350",
+"string351",
+"string352",
+"string353",
+"string354",
+"string355",
+"string356",
+"string357",
+"string358",
+"string359",
+"string360",
+"string361",
+"string362",
+"string363",
+"string364",
+"string365",
+"string366",
+"string367",
+"string368",
+"string369",
+"string370",
+"string371",
+"string372",
+"string373",
+"string374",
+"string375",
+"string376",
+"string377",
+"string378",
+"string379",
+"string380",
+"string381",
+"string382",
+"string383",
+"string384",
+"string385",
+"string386",
+"string387",
+"string388",
+"string389",
+"string390",
+"string391",
+"string392",
+"string393",
+"string394",
+"string395",
+"string396",
+"string397",
+"string398",
+"string399",
+"string400",
+"string401",
+"string402",
+"string403",
+"string404",
+"string405",
+"string406",
+"string407",
+"string408",
+"string409",
+"string410",
+"string411",
+"string412",
+"string413",
+"string414",
+"string415",
+"string416",
+"string417",
+"string418",
+"string419",
+"string420",
+"string421",
+"string422",
+"string423",
+"string424",
+"string425",
+"string426",
+"string427",
+"string428",
+"string429",
+"string430",
+"string431",
+"string432",
+"string433",
+"string434",
+"string435",
+"string436",
+"string437",
+"string438",
+"string439",
+"string440",
+"string441",
+"string442",
+"string443",
+"string444",
+"string445",
+"string446",
+"string447",
+"string448",
+"string449",
+"string450",
+"string451",
+"string452",
+"string453",
+"string454",
+"string455",
+"string456",
+"string457",
+"string458",
+"string459",
+"string460",
+"string461",
+"string462",
+"string463",
+"string464",
+"string465",
+"string466",
+"string467",
+"string468",
+"string469",
+"string470",
+"string471",
+"string472",
+"string473",
+"string474",
+"string475",
+"string476",
+"string477",
+"string478",
+"string479",
+"string480",
+"string481",
+"string482",
+"string483",
+"string484",
+"string485",
+"string486",
+"string487",
+"string488",
+"string489",
+"string490",
+"string491",
+"string492",
+"string493",
+"string494",
+"string495",
+"string496",
+"string497",
+"string498",
+"string499",
+"string500",
+"string501",
+"string502",
+"string503",
+"string504",
+"string505",
+"string506",
+"string507",
+"string508",
+"string509",
+"string510",
+"string511",
+"string512",
+"string513",
+"string514",
+"string515",
+"string516",
+"string517",
+"string518",
+"string519",
+"string520",
+"string521",
+"string522",
+"string523",
+"string524",
+"string525",
+"string526",
+"string527",
+"string528",
+"string529",
+"string530",
+"string531",
+"string532",
+"string533",
+"string534",
+"string535",
+"string536",
+"string537",
+"string538",
+"string539",
+"string540",
+"string541",
+"string542",
+"string543",
+"string544",
+"string545",
+"string546",
+"string547",
+"string548",
+"string549",
+"string550",
+"string551",
+"string552",
+"string553",
+"string554",
+"string555",
+"string556",
+"string557",
+"string558",
+"string559",
+"string560",
+"string561",
+"string562",
+"string563",
+"string564",
+"string565",
+"string566",
+"string567",
+"string568",
+"string569",
+"string570",
+"string571",
+"string572",
+"string573",
+"string574",
+"string575",
+"string576",
+"string577",
+"string578",
+"string579",
+"string580",
+"string581",
+"string582",
+"string583",
+"string584",
+"string585",
+"string586",
+"string587",
+"string588",
+"string589",
+"string590",
+"string591",
+"string592",
+"string593",
+"string594",
+"string595",
+"string596",
+"string597",
+"string598",
+"string599",
+"string600",
+"string601",
+"string602",
+"string603",
+"string604",
+"string605",
+"string606",
+"string607",
+"string608",
+"string609",
+"string610",
+"string611",
+"string612",
+"string613",
+"string614",
+"string615",
+"string616",
+"string617",
+"string618",
+"string619",
+"string620",
+"string621",
+"string622",
+"string623",
+"string624",
+"string625",
+"string626",
+"string627",
+"string628",
+"string629",
+"string630",
+"string631",
+"string632",
+"string633",
+"string634",
+"string635",
+"string636",
+"string637",
+"string638",
+"string639",
+"string640",
+"string641",
+"string642",
+"string643",
+"string644",
+"string645",
+"string646",
+"string647",
+"string648",
+"string649",
+"string650",
+"string651",
+"string652",
+"string653",
+"string654",
+"string655",
+"string656",
+"string657",
+"string658",
+"string659",
+"string660",
+"string661",
+"string662",
+"string663",
+"string664",
+"string665",
+"string666",
+"string667",
+"string668",
+"string669",
+"string670",
+"string671",
+"string672",
+"string673",
+"string674",
+"string675",
+"string676",
+"string677",
+"string678",
+"string679",
+"string680",
+"string681",
+"string682",
+"string683",
+"string684",
+"string685",
+"string686",
+"string687",
+"string688",
+"string689",
+"string690",
+"string691",
+"string692",
+"string693",
+"string694",
+"string695",
+"string696",
+"string697",
+"string698",
+"string699",
+"string700",
+"string701",
+"string702",
+"string703",
+"string704",
+"string705",
+"string706",
+"string707",
+"string708",
+"string709",
+"string710",
+"string711",
+"string712",
+"string713",
+"string714",
+"string715",
+"string716",
+"string717",
+"string718",
+"string719",
+"string720",
+"string721",
+"string722",
+"string723",
+"string724",
+"string725",
+"string726",
+"string727",
+"string728",
+"string729",
+"string730",
+"string731",
+"string732",
+"string733",
+"string734",
+"string735",
+"string736",
+"string737",
+"string738",
+"string739",
+"string740",
+"string741",
+"string742",
+"string743",
+"string744",
+"string745",
+"string746",
+"string747",
+"string748",
+"string749",
+"string750",
+"string751",
+"string752",
+"string753",
+"string754",
+"string755",
+"string756",
+"string757",
+"string758",
+"string759",
+"string760",
+"string761",
+"string762",
+"string763",
+"string764",
+"string765",
+"string766",
+"string767",
+"string768",
+"string769",
+"string770",
+"string771",
+"string772",
+"string773",
+"string774",
+"string775",
+"string776",
+"string777",
+"string778",
+"string779",
+"string780",
+"string781",
+"string782",
+"string783",
+"string784",
+"string785",
+"string786",
+"string787",
+"string788",
+"string789",
+"string790",
+"string791",
+"string792",
+"string793",
+"string794",
+"string795",
+"string796",
+"string797",
+"string798",
+"string799",
+"string800",
+"string801",
+"string802",
+"string803",
+"string804",
+"string805",
+"string806",
+"string807",
+"string808",
+"string809",
+"string810",
+"string811",
+"string812",
+"string813",
+"string814",
+"string815",
+"string816",
+"string817",
+"string818",
+"string819",
+"string820",
+"string821",
+"string822",
+"string823",
+"string824",
+"string825",
+"string826",
+"string827",
+"string828",
+"string829",
+"string830",
+"string831",
+"string832",
+"string833",
+"string834",
+"string835",
+"string836",
+"string837",
+"string838",
+"string839",
+"string840",
+"string841",
+"string842",
+"string843",
+"string844",
+"string845",
+"string846",
+"string847",
+"string848",
+"string849",
+"string850",
+"string851",
+"string852",
+"string853",
+"string854",
+"string855",
+"string856",
+"string857",
+"string858",
+"string859",
+"string860",
+"string861",
+"string862",
+"string863",
+"string864",
+"string865",
+"string866",
+"string867",
+"string868",
+"string869",
+"string870",
+"string871",
+"string872",
+"string873",
+"string874",
+"string875",
+"string876",
+"string877",
+"string878",
+"string879",
+"string880",
+"string881",
+"string882",
+"string883",
+"string884",
+"string885",
+"string886",
+"string887",
+"string888",
+"string889",
+"string890",
+"string891",
+"string892",
+"string893",
+"string894",
+"string895",
+"string896",
+"string897",
+"string898",
+"string899",
+"string900",
+"string901",
+"string902",
+"string903",
+"string904",
+"string905",
+"string906",
+"string907",
+"string908",
+"string909",
+"string910",
+"string911",
+"string912",
+"string913",
+"string914",
+"string915",
+"string916",
+"string917",
+"string918",
+"string919",
+"string920",
+"string921",
+"string922",
+"string923",
+"string924",
+"string925",
+"string926",
+"string927",
+"string928",
+"string929",
+"string930",
+"string931",
+"string932",
+"string933",
+"string934",
+"string935",
+"string936",
+"string937",
+"string938",
+"string939",
+"string940",
+"string941",
+"string942",
+"string943",
+"string944",
+"string945",
+"string946",
+"string947",
+"string948",
+"string949",
+"string950",
+"string951",
+"string952",
+"string953",
+"string954",
+"string955",
+"string956",
+"string957",
+"string958",
+"string959",
+"string960",
+"string961",
+"string962",
+"string963",
+"string964",
+"string965",
+"string966",
+"string967",
+"string968",
+"string969",
+"string970",
+"string971",
+"string972",
+"string973",
+"string974",
+"string975",
+"string976",
+"string977",
+"string978",
+"string979",
+"string980",
+"string981",
+"string982",
+"string983",
+"string984",
+"string985",
+"string986",
+"string987",
+"string988",
+"string989",
+"string990",
+"string991",
+"string992",
+"string993",
+"string994",
+"string995",
+"string996",
+"string997",
+"string998",
+"string999",
+"string1000",
+"string1001",
+"string1002",
+"string1003",
+"string1004",
+"string1005",
+"string1006",
+"string1007",
+"string1008",
+"string1009",
+"string1010",
+"string1011",
+"string1012",
+"string1013",
+"string1014",
+"string1015",
+"string1016",
+"string1017",
+"string1018",
+"string1019",
+"string1020",
+"string1021",
+"string1022",
+"string1023",
+"string1024",
+"string1025",
+"string1026",
+"string1027",
+"string1028",
+"string1029",
+"string1030",
+"string1031",
+"string1032",
+"string1033",
+"string1034",
+"string1035",
+"string1036",
+"string1037",
+"string1038",
+"string1039",
+"string1040",
+"string1041",
+"string1042",
+"string1043",
+"string1044",
+"string1045",
+"string1046",
+"string1047",
+"string1048",
+"string1049",
+"string1050",
+"string1051",
+"string1052",
+"string1053",
+"string1054",
+"string1055",
+"string1056",
+"string1057",
+"string1058",
+"string1059",
+"string1060",
+"string1061",
+"string1062",
+"string1063",
+"string1064",
+"string1065",
+"string1066",
+"string1067",
+"string1068",
+"string1069",
+"string1070",
+"string1071",
+"string1072",
+"string1073",
+"string1074",
+"string1075",
+"string1076",
+"string1077",
+"string1078",
+"string1079",
+"string1080",
+"string1081",
+"string1082",
+"string1083",
+"string1084",
+"string1085",
+"string1086",
+"string1087",
+"string1088",
+"string1089",
+"string1090",
+"string1091",
+"string1092",
+"string1093",
+"string1094",
+"string1095",
+"string1096",
+"string1097",
+"string1098",
+"string1099",
+"string1100",
+"string1101",
+"string1102",
+"string1103",
+"string1104",
+"string1105",
+"string1106",
+"string1107",
+"string1108",
+"string1109",
+"string1110",
+"string1111",
+"string1112",
+"string1113",
+"string1114",
+"string1115",
+"string1116",
+"string1117",
+"string1118",
+"string1119",
+"string1120",
+"string1121",
+"string1122",
+"string1123",
+"string1124",
+"string1125",
+"string1126",
+"string1127",
+"string1128",
+"string1129",
+"string1130",
+"string1131",
+"string1132",
+"string1133",
+"string1134",
+"string1135",
+"string1136",
+"string1137",
+"string1138",
+"string1139",
+"string1140",
+"string1141",
+"string1142",
+"string1143",
+"string1144",
+"string1145",
+"string1146",
+"string1147",
+"string1148",
+"string1149",
+"string1150",
+"string1151",
+"string1152",
+"string1153",
+"string1154",
+"string1155",
+"string1156",
+"string1157",
+"string1158",
+"string1159",
+"string1160",
+"string1161",
+"string1162",
+"string1163",
+"string1164",
+"string1165",
+"string1166",
+"string1167",
+"string1168",
+"string1169",
+"string1170",
+"string1171",
+"string1172",
+"string1173",
+"string1174",
+"string1175",
+"string1176",
+"string1177",
+"string1178",
+"string1179",
+"string1180",
+"string1181",
+"string1182",
+"string1183",
+"string1184",
+"string1185",
+"string1186",
+"string1187",
+"string1188",
+"string1189",
+"string1190",
+"string1191",
+"string1192",
+"string1193",
+"string1194",
+"string1195",
+"string1196",
+"string1197",
+"string1198",
+"string1199",
+"string1200",
+"string1201",
+"string1202",
+"string1203",
+"string1204",
+"string1205",
+"string1206",
+"string1207",
+"string1208",
+"string1209",
+"string1210",
+"string1211",
+"string1212",
+"string1213",
+"string1214",
+"string1215",
+"string1216",
+"string1217",
+"string1218",
+"string1219",
+"string1220",
+"string1221",
+"string1222",
+"string1223",
+"string1224",
+"string1225",
+"string1226",
+"string1227",
+"string1228",
+"string1229",
+"string1230",
+"string1231",
+"string1232",
+"string1233",
+"string1234",
+"string1235",
+"string1236",
+"string1237",
+"string1238",
+"string1239",
+"string1240",
+"string1241",
+"string1242",
+"string1243",
+"string1244",
+"string1245",
+"string1246",
+"string1247",
+"string1248",
+"string1249",
+"string1250",
+"string1251",
+"string1252",
+"string1253",
+"string1254",
+"string1255",
+"string1256",
+"string1257",
+"string1258",
+"string1259",
+"string1260",
+"string1261",
+"string1262",
+"string1263",
+"string1264",
+"string1265",
+"string1266",
+"string1267",
+"string1268",
+"string1269",
+"string1270",
+"string1271",
+"string1272",
+"string1273",
+"string1274",
+"string1275",
+"string1276",
+"string1277",
+"string1278",
+"string1279",
+"string1280",
+"string1281",
+"string1282",
+"string1283",
+"string1284",
+"string1285",
+"string1286",
+"string1287",
+"string1288",
+"string1289",
+"string1290",
+"string1291",
+"string1292",
+"string1293",
+"string1294",
+"string1295",
+"string1296",
+"string1297",
+"string1298",
+"string1299",
+"string1300",
+"string1301",
+"string1302",
+"string1303",
+"string1304",
+"string1305",
+"string1306",
+"string1307",
+"string1308",
+"string1309",
+"string1310",
+"string1311",
+"string1312",
+"string1313",
+"string1314",
+"string1315",
+"string1316",
+"string1317",
+"string1318",
+"string1319",
+"string1320",
+"string1321",
+"string1322",
+"string1323",
+"string1324",
+"string1325",
+"string1326",
+"string1327",
+"string1328",
+"string1329",
+"string1330",
+"string1331",
+"string1332",
+"string1333",
+"string1334",
+"string1335",
+"string1336",
+"string1337",
+"string1338",
+"string1339",
+"string1340",
+"string1341",
+"string1342",
+"string1343",
+"string1344",
+"string1345",
+"string1346",
+"string1347",
+"string1348",
+"string1349",
+"string1350",
+"string1351",
+"string1352",
+"string1353",
+"string1354",
+"string1355",
+"string1356",
+"string1357",
+"string1358",
+"string1359",
+"string1360",
+"string1361",
+"string1362",
+"string1363",
+"string1364",
+"string1365",
+"string1366",
+"string1367",
+"string1368",
+"string1369",
+"string1370",
+"string1371",
+"string1372",
+"string1373",
+"string1374",
+"string1375",
+"string1376",
+"string1377",
+"string1378",
+"string1379",
+"string1380",
+"string1381",
+"string1382",
+"string1383",
+"string1384",
+"string1385",
+"string1386",
+"string1387",
+"string1388",
+"string1389",
+"string1390",
+"string1391",
+"string1392",
+"string1393",
+"string1394",
+"string1395",
+"string1396",
+"string1397",
+"string1398",
+"string1399",
+"string1400",
+"string1401",
+"string1402",
+"string1403",
+"string1404",
+"string1405",
+"string1406",
+"string1407",
+"string1408",
+"string1409",
+"string1410",
+"string1411",
+"string1412",
+"string1413",
+"string1414",
+"string1415",
+"string1416",
+"string1417",
+"string1418",
+"string1419",
+"string1420",
+"string1421",
+"string1422",
+"string1423",
+"string1424",
+"string1425",
+"string1426",
+"string1427",
+"string1428",
+"string1429",
+"string1430",
+"string1431",
+"string1432",
+"string1433",
+"string1434",
+"string1435",
+"string1436",
+"string1437",
+"string1438",
+"string1439",
+"string1440",
+"string1441",
+"string1442",
+"string1443",
+"string1444",
+"string1445",
+"string1446",
+"string1447",
+"string1448",
+"string1449",
+"string1450",
+"string1451",
+"string1452",
+"string1453",
+"string1454",
+"string1455",
+"string1456",
+"string1457",
+"string1458",
+"string1459",
+"string1460",
+"string1461",
+"string1462",
+"string1463",
+"string1464",
+"string1465",
+"string1466",
+"string1467",
+"string1468",
+"string1469",
+"string1470",
+"string1471",
+"string1472",
+"string1473",
+"string1474",
+"string1475",
+"string1476",
+"string1477",
+"string1478",
+"string1479",
+"string1480",
+"string1481",
+"string1482",
+"string1483",
+"string1484",
+"string1485",
+"string1486",
+"string1487",
+"string1488",
+"string1489",
+"string1490",
+"string1491",
+"string1492",
+"string1493",
+"string1494",
+"string1495",
+"string1496",
+"string1497",
+"string1498",
+"string1499",
+"string1500",
+"string1501",
+"string1502",
+"string1503",
+"string1504",
+"string1505",
+"string1506",
+"string1507",
+"string1508",
+"string1509",
+"string1510",
+"string1511",
+"string1512",
+"string1513",
+"string1514",
+"string1515",
+"string1516",
+"string1517",
+"string1518",
+"string1519",
+"string1520",
+"string1521",
+"string1522",
+"string1523",
+"string1524",
+"string1525",
+"string1526",
+"string1527",
+"string1528",
+"string1529",
+"string1530",
+"string1531",
+"string1532",
+"string1533",
+"string1534",
+"string1535",
+"string1536",
+"string1537",
+"string1538",
+"string1539",
+"string1540",
+"string1541",
+"string1542",
+"string1543",
+"string1544",
+"string1545",
+"string1546",
+"string1547",
+"string1548",
+"string1549",
+"string1550",
+"string1551",
+"string1552",
+"string1553",
+"string1554",
+"string1555",
+"string1556",
+"string1557",
+"string1558",
+"string1559",
+"string1560",
+"string1561",
+"string1562",
+"string1563",
+"string1564",
+"string1565",
+"string1566",
+"string1567",
+"string1568",
+"string1569",
+"string1570",
+"string1571",
+"string1572",
+"string1573",
+"string1574",
+"string1575",
+"string1576",
+"string1577",
+"string1578",
+"string1579",
+"string1580",
+"string1581",
+"string1582",
+"string1583",
+"string1584",
+"string1585",
+"string1586",
+"string1587",
+"string1588",
+"string1589",
+"string1590",
+"string1591",
+"string1592",
+"string1593",
+"string1594",
+"string1595",
+"string1596",
+"string1597",
+"string1598",
+"string1599",
+"string1600",
+"string1601",
+"string1602",
+"string1603",
+"string1604",
+"string1605",
+"string1606",
+"string1607",
+"string1608",
+"string1609",
+"string1610",
+"string1611",
+"string1612",
+"string1613",
+"string1614",
+"string1615",
+"string1616",
+"string1617",
+"string1618",
+"string1619",
+"string1620",
+"string1621",
+"string1622",
+"string1623",
+"string1624",
+"string1625",
+"string1626",
+"string1627",
+"string1628",
+"string1629",
+"string1630",
+"string1631",
+"string1632",
+"string1633",
+"string1634",
+"string1635",
+"string1636",
+"string1637",
+"string1638",
+"string1639",
+"string1640",
+"string1641",
+"string1642",
+"string1643",
+"string1644",
+"string1645",
+"string1646",
+"string1647",
+"string1648",
+"string1649",
+"string1650",
+"string1651",
+"string1652",
+"string1653",
+"string1654",
+"string1655",
+"string1656",
+"string1657",
+"string1658",
+"string1659",
+"string1660",
+"string1661",
+"string1662",
+"string1663",
+"string1664",
+"string1665",
+"string1666",
+"string1667",
+"string1668",
+"string1669",
+"string1670",
+"string1671",
+"string1672",
+"string1673",
+"string1674",
+"string1675",
+"string1676",
+"string1677",
+"string1678",
+"string1679",
+"string1680",
+"string1681",
+"string1682",
+"string1683",
+"string1684",
+"string1685",
+"string1686",
+"string1687",
+"string1688",
+"string1689",
+"string1690",
+"string1691",
+"string1692",
+"string1693",
+"string1694",
+"string1695",
+"string1696",
+"string1697",
+"string1698",
+"string1699",
+"string1700",
+"string1701",
+"string1702",
+"string1703",
+"string1704",
+"string1705",
+"string1706",
+"string1707",
+"string1708",
+"string1709",
+"string1710",
+"string1711",
+"string1712",
+"string1713",
+"string1714",
+"string1715",
+"string1716",
+"string1717",
+"string1718",
+"string1719",
+"string1720",
+"string1721",
+"string1722",
+"string1723",
+"string1724",
+"string1725",
+"string1726",
+"string1727",
+"string1728",
+"string1729",
+"string1730",
+"string1731",
+"string1732",
+"string1733",
+"string1734",
+"string1735",
+"string1736",
+"string1737",
+"string1738",
+"string1739",
+"string1740",
+"string1741",
+"string1742",
+"string1743",
+"string1744",
+"string1745",
+"string1746",
+"string1747",
+"string1748",
+"string1749",
+"string1750",
+"string1751",
+"string1752",
+"string1753",
+"string1754",
+"string1755",
+"string1756",
+"string1757",
+"string1758",
+"string1759",
+"string1760",
+"string1761",
+"string1762",
+"string1763",
+"string1764",
+"string1765",
+"string1766",
+"string1767",
+"string1768",
+"string1769",
+"string1770",
+"string1771",
+"string1772",
+"string1773",
+"string1774",
+"string1775",
+"string1776",
+"string1777",
+"string1778",
+"string1779",
+"string1780",
+"string1781",
+"string1782",
+"string1783",
+"string1784",
+"string1785",
+"string1786",
+"string1787",
+"string1788",
+"string1789",
+"string1790",
+"string1791",
+"string1792",
+"string1793",
+"string1794",
+"string1795",
+"string1796",
+"string1797",
+"string1798",
+"string1799",
+"string1800",
+"string1801",
+"string1802",
+"string1803",
+"string1804",
+"string1805",
+"string1806",
+"string1807",
+"string1808",
+"string1809",
+"string1810",
+"string1811",
+"string1812",
+"string1813",
+"string1814",
+"string1815",
+"string1816",
+"string1817",
+"string1818",
+"string1819",
+"string1820",
+"string1821",
+"string1822",
+"string1823",
+"string1824",
+"string1825",
+"string1826",
+"string1827",
+"string1828",
+"string1829",
+"string1830",
+"string1831",
+"string1832",
+"string1833",
+"string1834",
+"string1835",
+"string1836",
+"string1837",
+"string1838",
+"string1839",
+"string1840",
+"string1841",
+"string1842",
+"string1843",
+"string1844",
+"string1845",
+"string1846",
+"string1847",
+"string1848",
+"string1849",
+"string1850",
+"string1851",
+"string1852",
+"string1853",
+"string1854",
+"string1855",
+"string1856",
+"string1857",
+"string1858",
+"string1859",
+"string1860",
+"string1861",
+"string1862",
+"string1863",
+"string1864",
+"string1865",
+"string1866",
+"string1867",
+"string1868",
+"string1869",
+"string1870",
+"string1871",
+"string1872",
+"string1873",
+"string1874",
+"string1875",
+"string1876",
+"string1877",
+"string1878",
+"string1879",
+"string1880",
+"string1881",
+"string1882",
+"string1883",
+"string1884",
+"string1885",
+"string1886",
+"string1887",
+"string1888",
+"string1889",
+"string1890",
+"string1891",
+"string1892",
+"string1893",
+"string1894",
+"string1895",
+"string1896",
+"string1897",
+"string1898",
+"string1899",
+"string1900",
+"string1901",
+"string1902",
+"string1903",
+"string1904",
+"string1905",
+"string1906",
+"string1907",
+"string1908",
+"string1909",
+"string1910",
+"string1911",
+"string1912",
+"string1913",
+"string1914",
+"string1915",
+"string1916",
+"string1917",
+"string1918",
+"string1919",
+"string1920",
+"string1921",
+"string1922",
+"string1923",
+"string1924",
+"string1925",
+"string1926",
+"string1927",
+"string1928",
+"string1929",
+"string1930",
+"string1931",
+"string1932",
+"string1933",
+"string1934",
+"string1935",
+"string1936",
+"string1937",
+"string1938",
+"string1939",
+"string1940",
+"string1941",
+"string1942",
+"string1943",
+"string1944",
+"string1945",
+"string1946",
+"string1947",
+"string1948",
+"string1949",
+"string1950",
+"string1951",
+"string1952",
+"string1953",
+"string1954",
+"string1955",
+"string1956",
+"string1957",
+"string1958",
+"string1959",
+"string1960",
+"string1961",
+"string1962",
+"string1963",
+"string1964",
+"string1965",
+"string1966",
+"string1967",
+"string1968",
+"string1969",
+"string1970",
+"string1971",
+"string1972",
+"string1973",
+"string1974",
+"string1975",
+"string1976",
+"string1977",
+"string1978",
+"string1979",
+"string1980",
+"string1981",
+"string1982",
+"string1983",
+"string1984",
+"string1985",
+"string1986",
+"string1987",
+"string1988",
+"string1989",
+"string1990",
+"string1991",
+"string1992",
+"string1993",
+"string1994",
+"string1995",
+"string1996",
+"string1997",
+"string1998",
+"string1999",
+"string2000",
+"string2001",
+"string2002",
+"string2003",
+"string2004",
+"string2005",
+"string2006",
+"string2007",
+"string2008",
+"string2009",
+"string2010",
+"string2011",
+"string2012",
+"string2013",
+"string2014",
+"string2015",
+"string2016",
+"string2017",
+"string2018",
+"string2019",
+"string2020",
+"string2021",
+"string2022",
+"string2023",
+"string2024",
+"string2025",
+"string2026",
+"string2027",
+"string2028",
+"string2029",
+"string2030",
+"string2031",
+"string2032",
+"string2033",
+"string2034",
+"string2035",
+"string2036",
+"string2037",
+"string2038",
+"string2039",
+"string2040",
+"string2041",
+"string2042",
+"string2043",
+"string2044",
+"string2045",
+"string2046",
+"string2047",
+"string2048",
+"string2049",
+"string2050",
+"string2051",
+"string2052",
+"string2053",
+"string2054",
+"string2055",
+"string2056",
+"string2057",
+"string2058",
+"string2059",
+"string2060",
+"string2061",
+"string2062",
+"string2063",
+"string2064",
+"string2065",
+"string2066",
+"string2067",
+"string2068",
+"string2069",
+"string2070",
+"string2071",
+"string2072",
+"string2073",
+"string2074",
+"string2075",
+"string2076",
+"string2077",
+"string2078",
+"string2079",
+"string2080",
+"string2081",
+"string2082",
+"string2083",
+"string2084",
+"string2085",
+"string2086",
+"string2087",
+"string2088",
+"string2089",
+"string2090",
+"string2091",
+"string2092",
+"string2093",
+"string2094",
+"string2095",
+"string2096",
+"string2097",
+"string2098",
+"string2099",
+"string2100",
+"string2101",
+"string2102",
+"string2103",
+"string2104",
+"string2105",
+"string2106",
+"string2107",
+"string2108",
+"string2109",
+"string2110",
+"string2111",
+"string2112",
+"string2113",
+"string2114",
+"string2115",
+"string2116",
+"string2117",
+"string2118",
+"string2119",
+"string2120",
+"string2121",
+"string2122",
+"string2123",
+"string2124",
+"string2125",
+"string2126",
+"string2127",
+"string2128",
+"string2129",
+"string2130",
+"string2131",
+"string2132",
+"string2133",
+"string2134",
+"string2135",
+"string2136",
+"string2137",
+"string2138",
+"string2139",
+"string2140",
+"string2141",
+"string2142",
+"string2143",
+"string2144",
+"string2145",
+"string2146",
+"string2147",
+"string2148",
+"string2149",
+"string2150",
+"string2151",
+"string2152",
+"string2153",
+"string2154",
+"string2155",
+"string2156",
+"string2157",
+"string2158",
+"string2159",
+"string2160",
+"string2161",
+"string2162",
+"string2163",
+"string2164",
+"string2165",
+"string2166",
+"string2167",
+"string2168",
+"string2169",
+"string2170",
+"string2171",
+"string2172",
+"string2173",
+"string2174",
+"string2175",
+"string2176",
+"string2177",
+"string2178",
+"string2179",
+"string2180",
+"string2181",
+"string2182",
+"string2183",
+"string2184",
+"string2185",
+"string2186",
+"string2187",
+"string2188",
+"string2189",
+"string2190",
+"string2191",
+"string2192",
+"string2193",
+"string2194",
+"string2195",
+"string2196",
+"string2197",
+"string2198",
+"string2199",
+"string2200",
+"string2201",
+"string2202",
+"string2203",
+"string2204",
+"string2205",
+"string2206",
+"string2207",
+"string2208",
+"string2209",
+"string2210",
+"string2211",
+"string2212",
+"string2213",
+"string2214",
+"string2215",
+"string2216",
+"string2217",
+"string2218",
+"string2219",
+"string2220",
+"string2221",
+"string2222",
+"string2223",
+"string2224",
+"string2225",
+"string2226",
+"string2227",
+"string2228",
+"string2229",
+"string2230",
+"string2231",
+"string2232",
+"string2233",
+"string2234",
+"string2235",
+"string2236",
+"string2237",
+"string2238",
+"string2239",
+"string2240",
+"string2241",
+"string2242",
+"string2243",
+"string2244",
+"string2245",
+"string2246",
+"string2247",
+"string2248",
+"string2249",
+"string2250",
+"string2251",
+"string2252",
+"string2253",
+"string2254",
+"string2255",
+"string2256",
+"string2257",
+"string2258",
+"string2259",
+"string2260",
+"string2261",
+"string2262",
+"string2263",
+"string2264",
+"string2265",
+"string2266",
+"string2267",
+"string2268",
+"string2269",
+"string2270",
+"string2271",
+"string2272",
+"string2273",
+"string2274",
+"string2275",
+"string2276",
+"string2277",
+"string2278",
+"string2279",
+"string2280",
+"string2281",
+"string2282",
+"string2283",
+"string2284",
+"string2285",
+"string2286",
+"string2287",
+"string2288",
+"string2289",
+"string2290",
+"string2291",
+"string2292",
+"string2293",
+"string2294",
+"string2295",
+"string2296",
+"string2297",
+"string2298",
+"string2299",
+"string2300",
+"string2301",
+"string2302",
+"string2303",
+"string2304",
+"string2305",
+"string2306",
+"string2307",
+"string2308",
+"string2309",
+"string2310",
+"string2311",
+"string2312",
+"string2313",
+"string2314",
+"string2315",
+"string2316",
+"string2317",
+"string2318",
+"string2319",
+"string2320",
+"string2321",
+"string2322",
+"string2323",
+"string2324",
+"string2325",
+"string2326",
+"string2327",
+"string2328",
+"string2329",
+"string2330",
+"string2331",
+"string2332",
+"string2333",
+"string2334",
+"string2335",
+"string2336",
+"string2337",
+"string2338",
+"string2339",
+"string2340",
+"string2341",
+"string2342",
+"string2343",
+"string2344",
+"string2345",
+"string2346",
+"string2347",
+"string2348",
+"string2349",
+"string2350",
+"string2351",
+"string2352",
+"string2353",
+"string2354",
+"string2355",
+"string2356",
+"string2357",
+"string2358",
+"string2359",
+"string2360",
+"string2361",
+"string2362",
+"string2363",
+"string2364",
+"string2365",
+"string2366",
+"string2367",
+"string2368",
+"string2369",
+"string2370",
+"string2371",
+"string2372",
+"string2373",
+"string2374",
+"string2375",
+"string2376",
+"string2377",
+"string2378",
+"string2379",
+"string2380",
+"string2381",
+"string2382",
+"string2383",
+"string2384",
+"string2385",
+"string2386",
+"string2387",
+"string2388",
+"string2389",
+"string2390",
+"string2391",
+"string2392",
+"string2393",
+"string2394",
+"string2395",
+"string2396",
+"string2397",
+"string2398",
+"string2399",
+"string2400",
+"string2401",
+"string2402",
+"string2403",
+"string2404",
+"string2405",
+"string2406",
+"string2407",
+"string2408",
+"string2409",
+"string2410",
+"string2411",
+"string2412",
+"string2413",
+"string2414",
+"string2415",
+"string2416",
+"string2417",
+"string2418",
+"string2419",
+"string2420",
+"string2421",
+"string2422",
+"string2423",
+"string2424",
+"string2425",
+"string2426",
+"string2427",
+"string2428",
+"string2429",
+"string2430",
+"string2431",
+"string2432",
+"string2433",
+"string2434",
+"string2435",
+"string2436",
+"string2437",
+"string2438",
+"string2439",
+"string2440",
+"string2441",
+"string2442",
+"string2443",
+"string2444",
+"string2445",
+"string2446",
+"string2447",
+"string2448",
+"string2449",
+"string2450",
+"string2451",
+"string2452",
+"string2453",
+"string2454",
+"string2455",
+"string2456",
+"string2457",
+"string2458",
+"string2459",
+"string2460",
+"string2461",
+"string2462",
+"string2463",
+"string2464",
+"string2465",
+"string2466",
+"string2467",
+"string2468",
+"string2469",
+"string2470",
+"string2471",
+"string2472",
+"string2473",
+"string2474",
+"string2475",
+"string2476",
+"string2477",
+"string2478",
+"string2479",
+"string2480",
+"string2481",
+"string2482",
+"string2483",
+"string2484",
+"string2485",
+"string2486",
+"string2487",
+"string2488",
+"string2489",
+"string2490",
+"string2491",
+"string2492",
+"string2493",
+"string2494",
+"string2495",
+"string2496",
+"string2497",
+"string2498",
+"string2499",
+"string2500",
+"string2501",
+"string2502",
+"string2503",
+"string2504",
+"string2505",
+"string2506",
+"string2507",
+"string2508",
+"string2509",
+"string2510",
+"string2511",
+"string2512",
+"string2513",
+"string2514",
+"string2515",
+"string2516",
+"string2517",
+"string2518",
+"string2519",
+"string2520",
+"string2521",
+"string2522",
+"string2523",
+"string2524",
+"string2525",
+"string2526",
+"string2527",
+"string2528",
+"string2529",
+"string2530",
+"string2531",
+"string2532",
+"string2533",
+"string2534",
+"string2535",
+"string2536",
+"string2537",
+"string2538",
+"string2539",
+"string2540",
+"string2541",
+"string2542",
+"string2543",
+"string2544",
+"string2545",
+"string2546",
+"string2547",
+"string2548",
+"string2549",
+"string2550",
+"string2551",
+"string2552",
+"string2553",
+"string2554",
+"string2555",
+"string2556",
+"string2557",
+"string2558",
+"string2559",
+"string2560",
+"string2561",
+"string2562",
+"string2563",
+"string2564",
+"string2565",
+"string2566",
+"string2567",
+"string2568",
+"string2569",
+"string2570",
+"string2571",
+"string2572",
+"string2573",
+"string2574",
+"string2575",
+"string2576",
+"string2577",
+"string2578",
+"string2579",
+"string2580",
+"string2581",
+"string2582",
+"string2583",
+"string2584",
+"string2585",
+"string2586",
+"string2587",
+"string2588",
+"string2589",
+"string2590",
+"string2591",
+"string2592",
+"string2593",
+"string2594",
+"string2595",
+"string2596",
+"string2597",
+"string2598",
+"string2599",
+"string2600",
+"string2601",
+"string2602",
+"string2603",
+"string2604",
+"string2605",
+"string2606",
+"string2607",
+"string2608",
+"string2609",
+"string2610",
+"string2611",
+"string2612",
+"string2613",
+"string2614",
+"string2615",
+"string2616",
+"string2617",
+"string2618",
+"string2619",
+"string2620",
+"string2621",
+"string2622",
+"string2623",
+"string2624",
+"string2625",
+"string2626",
+"string2627",
+"string2628",
+"string2629",
+"string2630",
+"string2631",
+"string2632",
+"string2633",
+"string2634",
+"string2635",
+"string2636",
+"string2637",
+"string2638",
+"string2639",
+"string2640",
+"string2641",
+"string2642",
+"string2643",
+"string2644",
+"string2645",
+"string2646",
+"string2647",
+"string2648",
+"string2649",
+"string2650",
+"string2651",
+"string2652",
+"string2653",
+"string2654",
+"string2655",
+"string2656",
+"string2657",
+"string2658",
+"string2659",
+"string2660",
+"string2661",
+"string2662",
+"string2663",
+"string2664",
+"string2665",
+"string2666",
+"string2667",
+"string2668",
+"string2669",
+"string2670",
+"string2671",
+"string2672",
+"string2673",
+"string2674",
+"string2675",
+"string2676",
+"string2677",
+"string2678",
+"string2679",
+"string2680",
+"string2681",
+"string2682",
+"string2683",
+"string2684",
+"string2685",
+"string2686",
+"string2687",
+"string2688",
+"string2689",
+"string2690",
+"string2691",
+"string2692",
+"string2693",
+"string2694",
+"string2695",
+"string2696",
+"string2697",
+"string2698",
+"string2699",
+"string2700",
+"string2701",
+"string2702",
+"string2703",
+"string2704",
+"string2705",
+"string2706",
+"string2707",
+"string2708",
+"string2709",
+"string2710",
+"string2711",
+"string2712",
+"string2713",
+"string2714",
+"string2715",
+"string2716",
+"string2717",
+"string2718",
+"string2719",
+"string2720",
+"string2721",
+"string2722",
+"string2723",
+"string2724",
+"string2725",
+"string2726",
+"string2727",
+"string2728",
+"string2729",
+"string2730",
+"string2731",
+"string2732",
+"string2733",
+"string2734",
+"string2735",
+"string2736",
+"string2737",
+"string2738",
+"string2739",
+"string2740",
+"string2741",
+"string2742",
+"string2743",
+"string2744",
+"string2745",
+"string2746",
+"string2747",
+"string2748",
+"string2749",
+"string2750",
+"string2751",
+"string2752",
+"string2753",
+"string2754",
+"string2755",
+"string2756",
+"string2757",
+"string2758",
+"string2759",
+"string2760",
+"string2761",
+"string2762",
+"string2763",
+"string2764",
+"string2765",
+"string2766",
+"string2767",
+"string2768",
+"string2769",
+"string2770",
+"string2771",
+"string2772",
+"string2773",
+"string2774",
+"string2775",
+"string2776",
+"string2777",
+"string2778",
+"string2779",
+"string2780",
+"string2781",
+"string2782",
+"string2783",
+"string2784",
+"string2785",
+"string2786",
+"string2787",
+"string2788",
+"string2789",
+"string2790",
+"string2791",
+"string2792",
+"string2793",
+"string2794",
+"string2795",
+"string2796",
+"string2797",
+"string2798",
+"string2799",
+"string2800",
+"string2801",
+"string2802",
+"string2803",
+"string2804",
+"string2805",
+"string2806",
+"string2807",
+"string2808",
+"string2809",
+"string2810",
+"string2811",
+"string2812",
+"string2813",
+"string2814",
+"string2815",
+"string2816",
+"string2817",
+"string2818",
+"string2819",
+"string2820",
+"string2821",
+"string2822",
+"string2823",
+"string2824",
+"string2825",
+"string2826",
+"string2827",
+"string2828",
+"string2829",
+"string2830",
+"string2831",
+"string2832",
+"string2833",
+"string2834",
+"string2835",
+"string2836",
+"string2837",
+"string2838",
+"string2839",
+"string2840",
+"string2841",
+"string2842",
+"string2843",
+"string2844",
+"string2845",
+"string2846",
+"string2847",
+"string2848",
+"string2849",
+"string2850",
+"string2851",
+"string2852",
+"string2853",
+"string2854",
+"string2855",
+"string2856",
+"string2857",
+"string2858",
+"string2859",
+"string2860",
+"string2861",
+"string2862",
+"string2863",
+"string2864",
+"string2865",
+"string2866",
+"string2867",
+"string2868",
+"string2869",
+"string2870",
+"string2871",
+"string2872",
+"string2873",
+"string2874",
+"string2875",
+"string2876",
+"string2877",
+"string2878",
+"string2879",
+"string2880",
+"string2881",
+"string2882",
+"string2883",
+"string2884",
+"string2885",
+"string2886",
+"string2887",
+"string2888",
+"string2889",
+"string2890",
+"string2891",
+"string2892",
+"string2893",
+"string2894",
+"string2895",
+"string2896",
+"string2897",
+"string2898",
+"string2899",
+"string2900",
+"string2901",
+"string2902",
+"string2903",
+"string2904",
+"string2905",
+"string2906",
+"string2907",
+"string2908",
+"string2909",
+"string2910",
+"string2911",
+"string2912",
+"string2913",
+"string2914",
+"string2915",
+"string2916",
+"string2917",
+"string2918",
+"string2919",
+"string2920",
+"string2921",
+"string2922",
+"string2923",
+"string2924",
+"string2925",
+"string2926",
+"string2927",
+"string2928",
+"string2929",
+"string2930",
+"string2931",
+"string2932",
+"string2933",
+"string2934",
+"string2935",
+"string2936",
+"string2937",
+"string2938",
+"string2939",
+"string2940",
+"string2941",
+"string2942",
+"string2943",
+"string2944",
+"string2945",
+"string2946",
+"string2947",
+"string2948",
+"string2949",
+"string2950",
+"string2951",
+"string2952",
+"string2953",
+"string2954",
+"string2955",
+"string2956",
+"string2957",
+"string2958",
+"string2959",
+"string2960",
+"string2961",
+"string2962",
+"string2963",
+"string2964",
+"string2965",
+"string2966",
+"string2967",
+"string2968",
+"string2969",
+"string2970",
+"string2971",
+"string2972",
+"string2973",
+"string2974",
+"string2975",
+"string2976",
+"string2977",
+"string2978",
+"string2979",
+"string2980",
+"string2981",
+"string2982",
+"string2983",
+"string2984",
+"string2985",
+"string2986",
+"string2987",
+"string2988",
+"string2989",
+"string2990",
+"string2991",
+"string2992",
+"string2993",
+"string2994",
+"string2995",
+"string2996",
+"string2997",
+"string2998",
+"string2999",
+"string3000",
+"string3001",
+"string3002",
+"string3003",
+"string3004",
+"string3005",
+"string3006",
+"string3007",
+"string3008",
+"string3009",
+"string3010",
+"string3011",
+"string3012",
+"string3013",
+"string3014",
+"string3015",
+"string3016",
+"string3017",
+"string3018",
+"string3019",
+"string3020",
+"string3021",
+"string3022",
+"string3023",
+"string3024",
+"string3025",
+"string3026",
+"string3027",
+"string3028",
+"string3029",
+"string3030",
+"string3031",
+"string3032",
+"string3033",
+"string3034",
+"string3035",
+"string3036",
+"string3037",
+"string3038",
+"string3039",
+"string3040",
+"string3041",
+"string3042",
+"string3043",
+"string3044",
+"string3045",
+"string3046",
+"string3047",
+"string3048",
+"string3049",
+"string3050",
+"string3051",
+"string3052",
+"string3053",
+"string3054",
+"string3055",
+"string3056",
+"string3057",
+"string3058",
+"string3059",
+"string3060",
+"string3061",
+"string3062",
+"string3063",
+"string3064",
+"string3065",
+"string3066",
+"string3067",
+"string3068",
+"string3069",
+"string3070",
+"string3071",
+"string3072",
+"string3073",
+"string3074",
+"string3075",
+"string3076",
+"string3077",
+"string3078",
+"string3079",
+"string3080",
+"string3081",
+"string3082",
+"string3083",
+"string3084",
+"string3085",
+"string3086",
+"string3087",
+"string3088",
+"string3089",
+"string3090",
+"string3091",
+"string3092",
+"string3093",
+"string3094",
+"string3095",
+"string3096",
+"string3097",
+"string3098",
+"string3099",
+"string3100",
+"string3101",
+"string3102",
+"string3103",
+"string3104",
+"string3105",
+"string3106",
+"string3107",
+"string3108",
+"string3109",
+"string3110",
+"string3111",
+"string3112",
+"string3113",
+"string3114",
+"string3115",
+"string3116",
+"string3117",
+"string3118",
+"string3119",
+"string3120",
+"string3121",
+"string3122",
+"string3123",
+"string3124",
+"string3125",
+"string3126",
+"string3127",
+"string3128",
+"string3129",
+"string3130",
+"string3131",
+"string3132",
+"string3133",
+"string3134",
+"string3135",
+"string3136",
+"string3137",
+"string3138",
+"string3139",
+"string3140",
+"string3141",
+"string3142",
+"string3143",
+"string3144",
+"string3145",
+"string3146",
+"string3147",
+"string3148",
+"string3149",
+"string3150",
+"string3151",
+"string3152",
+"string3153",
+"string3154",
+"string3155",
+"string3156",
+"string3157",
+"string3158",
+"string3159",
+"string3160",
+"string3161",
+"string3162",
+"string3163",
+"string3164",
+"string3165",
+"string3166",
+"string3167",
+"string3168",
+"string3169",
+"string3170",
+"string3171",
+"string3172",
+"string3173",
+"string3174",
+"string3175",
+"string3176",
+"string3177",
+"string3178",
+"string3179",
+"string3180",
+"string3181",
+"string3182",
+"string3183",
+"string3184",
+"string3185",
+"string3186",
+"string3187",
+"string3188",
+"string3189",
+"string3190",
+"string3191",
+"string3192",
+"string3193",
+"string3194",
+"string3195",
+"string3196",
+"string3197",
+"string3198",
+"string3199",
+"string3200",
+"string3201",
+"string3202",
+"string3203",
+"string3204",
+"string3205",
+"string3206",
+"string3207",
+"string3208",
+"string3209",
+"string3210",
+"string3211",
+"string3212",
+"string3213",
+"string3214",
+"string3215",
+"string3216",
+"string3217",
+"string3218",
+"string3219",
+"string3220",
+"string3221",
+"string3222",
+"string3223",
+"string3224",
+"string3225",
+"string3226",
+"string3227",
+"string3228",
+"string3229",
+"string3230",
+"string3231",
+"string3232",
+"string3233",
+"string3234",
+"string3235",
+"string3236",
+"string3237",
+"string3238",
+"string3239",
+"string3240",
+"string3241",
+"string3242",
+"string3243",
+"string3244",
+"string3245",
+"string3246",
+"string3247",
+"string3248",
+"string3249",
+"string3250",
+"string3251",
+"string3252",
+"string3253",
+"string3254",
+"string3255",
+"string3256",
+"string3257",
+"string3258",
+"string3259",
+"string3260",
+"string3261",
+"string3262",
+"string3263",
+"string3264",
+"string3265",
+"string3266",
+"string3267",
+"string3268",
+"string3269",
+"string3270",
+"string3271",
+"string3272",
+"string3273",
+"string3274",
+"string3275",
+"string3276",
+"string3277",
+"string3278",
+"string3279",
+"string3280",
+"string3281",
+"string3282",
+"string3283",
+"string3284",
+"string3285",
+"string3286",
+"string3287",
+"string3288",
+"string3289",
+"string3290",
+"string3291",
+"string3292",
+"string3293",
+"string3294",
+"string3295",
+"string3296",
+"string3297",
+"string3298",
+"string3299",
+"string3300",
+"string3301",
+"string3302",
+"string3303",
+"string3304",
+"string3305",
+"string3306",
+"string3307",
+"string3308",
+"string3309",
+"string3310",
+"string3311",
+"string3312",
+"string3313",
+"string3314",
+"string3315",
+"string3316",
+"string3317",
+"string3318",
+"string3319",
+"string3320",
+"string3321",
+"string3322",
+"string3323",
+"string3324",
+"string3325",
+"string3326",
+"string3327",
+"string3328",
+"string3329",
+"string3330",
+"string3331",
+"string3332",
+"string3333",
+"string3334",
+"string3335",
+"string3336",
+"string3337",
+"string3338",
+"string3339",
+"string3340",
+"string3341",
+"string3342",
+"string3343",
+"string3344",
+"string3345",
+"string3346",
+"string3347",
+"string3348",
+"string3349",
+"string3350",
+"string3351",
+"string3352",
+"string3353",
+"string3354",
+"string3355",
+"string3356",
+"string3357",
+"string3358",
+"string3359",
+"string3360",
+"string3361",
+"string3362",
+"string3363",
+"string3364",
+"string3365",
+"string3366",
+"string3367",
+"string3368",
+"string3369",
+"string3370",
+"string3371",
+"string3372",
+"string3373",
+"string3374",
+"string3375",
+"string3376",
+"string3377",
+"string3378",
+"string3379",
+"string3380",
+"string3381",
+"string3382",
+"string3383",
+"string3384",
+"string3385",
+"string3386",
+"string3387",
+"string3388",
+"string3389",
+"string3390",
+"string3391",
+"string3392",
+"string3393",
+"string3394",
+"string3395",
+"string3396",
+"string3397",
+"string3398",
+"string3399",
+"string3400",
+"string3401",
+"string3402",
+"string3403",
+"string3404",
+"string3405",
+"string3406",
+"string3407",
+"string3408",
+"string3409",
+"string3410",
+"string3411",
+"string3412",
+"string3413",
+"string3414",
+"string3415",
+"string3416",
+"string3417",
+"string3418",
+"string3419",
+"string3420",
+"string3421",
+"string3422",
+"string3423",
+"string3424",
+"string3425",
+"string3426",
+"string3427",
+"string3428",
+"string3429",
+"string3430",
+"string3431",
+"string3432",
+"string3433",
+"string3434",
+"string3435",
+"string3436",
+"string3437",
+"string3438",
+"string3439",
+"string3440",
+"string3441",
+"string3442",
+"string3443",
+"string3444",
+"string3445",
+"string3446",
+"string3447",
+"string3448",
+"string3449",
+"string3450",
+"string3451",
+"string3452",
+"string3453",
+"string3454",
+"string3455",
+"string3456",
+"string3457",
+"string3458",
+"string3459",
+"string3460",
+"string3461",
+"string3462",
+"string3463",
+"string3464",
+"string3465",
+"string3466",
+"string3467",
+"string3468",
+"string3469",
+"string3470",
+"string3471",
+"string3472",
+"string3473",
+"string3474",
+"string3475",
+"string3476",
+"string3477",
+"string3478",
+"string3479",
+"string3480",
+"string3481",
+"string3482",
+"string3483",
+"string3484",
+"string3485",
+"string3486",
+"string3487",
+"string3488",
+"string3489",
+"string3490",
+"string3491",
+"string3492",
+"string3493",
+"string3494",
+"string3495",
+"string3496",
+"string3497",
+"string3498",
+"string3499",
+"string3500",
+"string3501",
+"string3502",
+"string3503",
+"string3504",
+"string3505",
+"string3506",
+"string3507",
+"string3508",
+"string3509",
+"string3510",
+"string3511",
+"string3512",
+"string3513",
+"string3514",
+"string3515",
+"string3516",
+"string3517",
+"string3518",
+"string3519",
+"string3520",
+"string3521",
+"string3522",
+"string3523",
+"string3524",
+"string3525",
+"string3526",
+"string3527",
+"string3528",
+"string3529",
+"string3530",
+"string3531",
+"string3532",
+"string3533",
+"string3534",
+"string3535",
+"string3536",
+"string3537",
+"string3538",
+"string3539",
+"string3540",
+"string3541",
+"string3542",
+"string3543",
+"string3544",
+"string3545",
+"string3546",
+"string3547",
+"string3548",
+"string3549",
+"string3550",
+"string3551",
+"string3552",
+"string3553",
+"string3554",
+"string3555",
+"string3556",
+"string3557",
+"string3558",
+"string3559",
+"string3560",
+"string3561",
+"string3562",
+"string3563",
+"string3564",
+"string3565",
+"string3566",
+"string3567",
+"string3568",
+"string3569",
+"string3570",
+"string3571",
+"string3572",
+"string3573",
+"string3574",
+"string3575",
+"string3576",
+"string3577",
+"string3578",
+"string3579",
+"string3580",
+"string3581",
+"string3582",
+"string3583",
+"string3584",
+"string3585",
+"string3586",
+"string3587",
+"string3588",
+"string3589",
+"string3590",
+"string3591",
+"string3592",
+"string3593",
+"string3594",
+"string3595",
+"string3596",
+"string3597",
+"string3598",
+"string3599",
+"string3600",
+"string3601",
+"string3602",
+"string3603",
+"string3604",
+"string3605",
+"string3606",
+"string3607",
+"string3608",
+"string3609",
+"string3610",
+"string3611",
+"string3612",
+"string3613",
+"string3614",
+"string3615",
+"string3616",
+"string3617",
+"string3618",
+"string3619",
+"string3620",
+"string3621",
+"string3622",
+"string3623",
+"string3624",
+"string3625",
+"string3626",
+"string3627",
+"string3628",
+"string3629",
+"string3630",
+"string3631",
+"string3632",
+"string3633",
+"string3634",
+"string3635",
+"string3636",
+"string3637",
+"string3638",
+"string3639",
+"string3640",
+"string3641",
+"string3642",
+"string3643",
+"string3644",
+"string3645",
+"string3646",
+"string3647",
+"string3648",
+"string3649",
+"string3650",
+"string3651",
+"string3652",
+"string3653",
+"string3654",
+"string3655",
+"string3656",
+"string3657",
+"string3658",
+"string3659",
+"string3660",
+"string3661",
+"string3662",
+"string3663",
+"string3664",
+"string3665",
+"string3666",
+"string3667",
+"string3668",
+"string3669",
+"string3670",
+"string3671",
+"string3672",
+"string3673",
+"string3674",
+"string3675",
+"string3676",
+"string3677",
+"string3678",
+"string3679",
+"string3680",
+"string3681",
+"string3682",
+"string3683",
+"string3684",
+"string3685",
+"string3686",
+"string3687",
+"string3688",
+"string3689",
+"string3690",
+"string3691",
+"string3692",
+"string3693",
+"string3694",
+"string3695",
+"string3696",
+"string3697",
+"string3698",
+"string3699",
+"string3700",
+"string3701",
+"string3702",
+"string3703",
+"string3704",
+"string3705",
+"string3706",
+"string3707",
+"string3708",
+"string3709",
+"string3710",
+"string3711",
+"string3712",
+"string3713",
+"string3714",
+"string3715",
+"string3716",
+"string3717",
+"string3718",
+"string3719",
+"string3720",
+"string3721",
+"string3722",
+"string3723",
+"string3724",
+"string3725",
+"string3726",
+"string3727",
+"string3728",
+"string3729",
+"string3730",
+"string3731",
+"string3732",
+"string3733",
+"string3734",
+"string3735",
+"string3736",
+"string3737",
+"string3738",
+"string3739",
+"string3740",
+"string3741",
+"string3742",
+"string3743",
+"string3744",
+"string3745",
+"string3746",
+"string3747",
+"string3748",
+"string3749",
+"string3750",
+"string3751",
+"string3752",
+"string3753",
+"string3754",
+"string3755",
+"string3756",
+"string3757",
+"string3758",
+"string3759",
+"string3760",
+"string3761",
+"string3762",
+"string3763",
+"string3764",
+"string3765",
+"string3766",
+"string3767",
+"string3768",
+"string3769",
+"string3770",
+"string3771",
+"string3772",
+"string3773",
+"string3774",
+"string3775",
+"string3776",
+"string3777",
+"string3778",
+"string3779",
+"string3780",
+"string3781",
+"string3782",
+"string3783",
+"string3784",
+"string3785",
+"string3786",
+"string3787",
+"string3788",
+"string3789",
+"string3790",
+"string3791",
+"string3792",
+"string3793",
+"string3794",
+"string3795",
+"string3796",
+"string3797",
+"string3798",
+"string3799",
+"string3800",
+"string3801",
+"string3802",
+"string3803",
+"string3804",
+"string3805",
+"string3806",
+"string3807",
+"string3808",
+"string3809",
+"string3810",
+"string3811",
+"string3812",
+"string3813",
+"string3814",
+"string3815",
+"string3816",
+"string3817",
+"string3818",
+"string3819",
+"string3820",
+"string3821",
+"string3822",
+"string3823",
+"string3824",
+"string3825",
+"string3826",
+"string3827",
+"string3828",
+"string3829",
+"string3830",
+"string3831",
+"string3832",
+"string3833",
+"string3834",
+"string3835",
+"string3836",
+"string3837",
+"string3838",
+"string3839",
+"string3840",
+"string3841",
+"string3842",
+"string3843",
+"string3844",
+"string3845",
+"string3846",
+"string3847",
+"string3848",
+"string3849",
+"string3850",
+"string3851",
+"string3852",
+"string3853",
+"string3854",
+"string3855",
+"string3856",
+"string3857",
+"string3858",
+"string3859",
+"string3860",
+"string3861",
+"string3862",
+"string3863",
+"string3864",
+"string3865",
+"string3866",
+"string3867",
+"string3868",
+"string3869",
+"string3870",
+"string3871",
+"string3872",
+"string3873",
+"string3874",
+"string3875",
+"string3876",
+"string3877",
+"string3878",
+"string3879",
+"string3880",
+"string3881",
+"string3882",
+"string3883",
+"string3884",
+"string3885",
+"string3886",
+"string3887",
+"string3888",
+"string3889",
+"string3890",
+"string3891",
+"string3892",
+"string3893",
+"string3894",
+"string3895",
+"string3896",
+"string3897",
+"string3898",
+"string3899",
+"string3900",
+"string3901",
+"string3902",
+"string3903",
+"string3904",
+"string3905",
+"string3906",
+"string3907",
+"string3908",
+"string3909",
+"string3910",
+"string3911",
+"string3912",
+"string3913",
+"string3914",
+"string3915",
+"string3916",
+"string3917",
+"string3918",
+"string3919",
+"string3920",
+"string3921",
+"string3922",
+"string3923",
+"string3924",
+"string3925",
+"string3926",
+"string3927",
+"string3928",
+"string3929",
+"string3930",
+"string3931",
+"string3932",
+"string3933",
+"string3934",
+"string3935",
+"string3936",
+"string3937",
+"string3938",
+"string3939",
+"string3940",
+"string3941",
+"string3942",
+"string3943",
+"string3944",
+"string3945",
+"string3946",
+"string3947",
+"string3948",
+"string3949",
+"string3950",
+"string3951",
+"string3952",
+"string3953",
+"string3954",
+"string3955",
+"string3956",
+"string3957",
+"string3958",
+"string3959",
+"string3960",
+"string3961",
+"string3962",
+"string3963",
+"string3964",
+"string3965",
+"string3966",
+"string3967",
+"string3968",
+"string3969",
+"string3970",
+"string3971",
+"string3972",
+"string3973",
+"string3974",
+"string3975",
+"string3976",
+"string3977",
+"string3978",
+"string3979",
+"string3980",
+"string3981",
+"string3982",
+"string3983",
+"string3984",
+"string3985",
+"string3986",
+"string3987",
+"string3988",
+"string3989",
+"string3990",
+"string3991",
+"string3992",
+"string3993",
+"string3994",
+"string3995",
+"string3996",
+"string3997",
+"string3998",
+"string3999",
+"string4000",
+"string4001",
+"string4002",
+"string4003",
+"string4004",
+"string4005",
+"string4006",
+"string4007",
+"string4008",
+"string4009",
+"string4010",
+"string4011",
+"string4012",
+"string4013",
+"string4014",
+"string4015",
+"string4016",
+"string4017",
+"string4018",
+"string4019",
+"string4020",
+"string4021",
+"string4022",
+"string4023",
+"string4024",
+"string4025",
+"string4026",
+"string4027",
+"string4028",
+"string4029",
+"string4030",
+"string4031",
+"string4032",
+"string4033",
+"string4034",
+"string4035",
+"string4036",
+"string4037",
+"string4038",
+"string4039",
+"string4040",
+"string4041",
+"string4042",
+"string4043",
+"string4044",
+"string4045",
+"string4046",
+"string4047",
+"string4048",
+"string4049",
+"string4050",
+"string4051",
+"string4052",
+"string4053",
+"string4054",
+"string4055",
+"string4056",
+"string4057",
+"string4058",
+"string4059",
+"string4060",
+"string4061",
+"string4062",
+"string4063",
+"string4064",
+"string4065",
+"string4066",
+"string4067",
+"string4068",
+"string4069",
+"string4070",
+"string4071",
+"string4072",
+"string4073",
+"string4074",
+"string4075",
+"string4076",
+"string4077",
+"string4078",
+"string4079",
+"string4080",
+"string4081",
+"string4082",
+"string4083",
+"string4084",
+"string4085",
+"string4086",
+"string4087",
+"string4088",
+"string4089",
+"string4090",
+"string4091",
+"string4092",
+"string4093",
+"string4094",
+"string4095",
+"string4096",
+"string4097",
+"string4098",
+"string4099",
+"string4100",
+"string4101",
+"string4102",
+"string4103",
+"string4104",
+"string4105",
+"string4106",
+"string4107",
+"string4108",
+"string4109",
+"string4110",
+"string4111",
+"string4112",
+"string4113",
+"string4114",
+"string4115",
+"string4116",
+"string4117",
+"string4118",
+"string4119",
+"string4120",
+"string4121",
+"string4122",
+"string4123",
+"string4124",
+"string4125",
+"string4126",
+"string4127",
+"string4128",
+"string4129",
+"string4130",
+"string4131",
+"string4132",
+"string4133",
+"string4134",
+"string4135",
+"string4136",
+"string4137",
+"string4138",
+"string4139",
+"string4140",
+"string4141",
+"string4142",
+"string4143",
+"string4144",
+"string4145",
+"string4146",
+"string4147",
+"string4148",
+"string4149",
+"string4150",
+"string4151",
+"string4152",
+"string4153",
+"string4154",
+"string4155",
+"string4156",
+"string4157",
+"string4158",
+"string4159",
+"string4160",
+"string4161",
+"string4162",
+"string4163",
+"string4164",
+"string4165",
+"string4166",
+"string4167",
+"string4168",
+"string4169",
+"string4170",
+"string4171",
+"string4172",
+"string4173",
+"string4174",
+"string4175",
+"string4176",
+"string4177",
+"string4178",
+"string4179",
+"string4180",
+"string4181",
+"string4182",
+"string4183",
+"string4184",
+"string4185",
+"string4186",
+"string4187",
+"string4188",
+"string4189",
+"string4190",
+"string4191",
+"string4192",
+"string4193",
+"string4194",
+"string4195",
+"string4196",
+"string4197",
+"string4198",
+"string4199",
+"string4200",
+"string4201",
+"string4202",
+"string4203",
+"string4204",
+"string4205",
+"string4206",
+"string4207",
+"string4208",
+"string4209",
+"string4210",
+"string4211",
+"string4212",
+"string4213",
+"string4214",
+"string4215",
+"string4216",
+"string4217",
+"string4218",
+"string4219",
+"string4220",
+"string4221",
+"string4222",
+"string4223",
+"string4224",
+"string4225",
+"string4226",
+"string4227",
+"string4228",
+"string4229",
+"string4230",
+"string4231",
+"string4232",
+"string4233",
+"string4234",
+"string4235",
+"string4236",
+"string4237",
+"string4238",
+"string4239",
+"string4240",
+"string4241",
+"string4242",
+"string4243",
+"string4244",
+"string4245",
+"string4246",
+"string4247",
+"string4248",
+"string4249",
+"string4250",
+"string4251",
+"string4252",
+"string4253",
+"string4254",
+"string4255",
+"string4256",
+"string4257",
+"string4258",
+"string4259",
+"string4260",
+"string4261",
+"string4262",
+"string4263",
+"string4264",
+"string4265",
+"string4266",
+"string4267",
+"string4268",
+"string4269",
+"string4270",
+"string4271",
+"string4272",
+"string4273",
+"string4274",
+"string4275",
+"string4276",
+"string4277",
+"string4278",
+"string4279",
+"string4280",
+"string4281",
+"string4282",
+"string4283",
+"string4284",
+"string4285",
+"string4286",
+"string4287",
+"string4288",
+"string4289",
+"string4290",
+"string4291",
+"string4292",
+"string4293",
+"string4294",
+"string4295",
+"string4296",
+"string4297",
+"string4298",
+"string4299",
+"string4300",
+"string4301",
+"string4302",
+"string4303",
+"string4304",
+"string4305",
+"string4306",
+"string4307",
+"string4308",
+"string4309",
+"string4310",
+"string4311",
+"string4312",
+"string4313",
+"string4314",
+"string4315",
+"string4316",
+"string4317",
+"string4318",
+"string4319",
+"string4320",
+"string4321",
+"string4322",
+"string4323",
+"string4324",
+"string4325",
+"string4326",
+"string4327",
+"string4328",
+"string4329",
+"string4330",
+"string4331",
+"string4332",
+"string4333",
+"string4334",
+"string4335",
+"string4336",
+"string4337",
+"string4338",
+"string4339",
+"string4340",
+"string4341",
+"string4342",
+"string4343",
+"string4344",
+"string4345",
+"string4346",
+"string4347",
+"string4348",
+"string4349",
+"string4350",
+"string4351",
+"string4352",
+"string4353",
+"string4354",
+"string4355",
+"string4356",
+"string4357",
+"string4358",
+"string4359",
+"string4360",
+"string4361",
+"string4362",
+"string4363",
+"string4364",
+"string4365",
+"string4366",
+"string4367",
+"string4368",
+"string4369",
+"string4370",
+"string4371",
+"string4372",
+"string4373",
+"string4374",
+"string4375",
+"string4376",
+"string4377",
+"string4378",
+"string4379",
+"string4380",
+"string4381",
+"string4382",
+"string4383",
+"string4384",
+"string4385",
+"string4386",
+"string4387",
+"string4388",
+"string4389",
+"string4390",
+"string4391",
+"string4392",
+"string4393",
+"string4394",
+"string4395",
+"string4396",
+"string4397",
+"string4398",
+"string4399",
+"string4400",
+"string4401",
+"string4402",
+"string4403",
+"string4404",
+"string4405",
+"string4406",
+"string4407",
+"string4408",
+"string4409",
+"string4410",
+"string4411",
+"string4412",
+"string4413",
+"string4414",
+"string4415",
+"string4416",
+"string4417",
+"string4418",
+"string4419",
+"string4420",
+"string4421",
+"string4422",
+"string4423",
+"string4424",
+"string4425",
+"string4426",
+"string4427",
+"string4428",
+"string4429",
+"string4430",
+"string4431",
+"string4432",
+"string4433",
+"string4434",
+"string4435",
+"string4436",
+"string4437",
+"string4438",
+"string4439",
+"string4440",
+"string4441",
+"string4442",
+"string4443",
+"string4444",
+"string4445",
+"string4446",
+"string4447",
+"string4448",
+"string4449",
+"string4450",
+"string4451",
+"string4452",
+"string4453",
+"string4454",
+"string4455",
+"string4456",
+"string4457",
+"string4458",
+"string4459",
+"string4460",
+"string4461",
+"string4462",
+"string4463",
+"string4464",
+"string4465",
+"string4466",
+"string4467",
+"string4468",
+"string4469",
+"string4470",
+"string4471",
+"string4472",
+"string4473",
+"string4474",
+"string4475",
+"string4476",
+"string4477",
+"string4478",
+"string4479",
+"string4480",
+"string4481",
+"string4482",
+"string4483",
+"string4484",
+"string4485",
+"string4486",
+"string4487",
+"string4488",
+"string4489",
+"string4490",
+"string4491",
+"string4492",
+"string4493",
+"string4494",
+"string4495",
+"string4496",
+"string4497",
+"string4498",
+"string4499",
+"string4500",
+"string4501",
+"string4502",
+"string4503",
+"string4504",
+"string4505",
+"string4506",
+"string4507",
+"string4508",
+"string4509",
+"string4510",
+"string4511",
+"string4512",
+"string4513",
+"string4514",
+"string4515",
+"string4516",
+"string4517",
+"string4518",
+"string4519",
+"string4520",
+"string4521",
+"string4522",
+"string4523",
+"string4524",
+"string4525",
+"string4526",
+"string4527",
+"string4528",
+"string4529",
+"string4530",
+"string4531",
+"string4532",
+"string4533",
+"string4534",
+"string4535",
+"string4536",
+"string4537",
+"string4538",
+"string4539",
+"string4540",
+"string4541",
+"string4542",
+"string4543",
+"string4544",
+"string4545",
+"string4546",
+"string4547",
+"string4548",
+"string4549",
+"string4550",
+"string4551",
+"string4552",
+"string4553",
+"string4554",
+"string4555",
+"string4556",
+"string4557",
+"string4558",
+"string4559",
+"string4560",
+"string4561",
+"string4562",
+"string4563",
+"string4564",
+"string4565",
+"string4566",
+"string4567",
+"string4568",
+"string4569",
+"string4570",
+"string4571",
+"string4572",
+"string4573",
+"string4574",
+"string4575",
+"string4576",
+"string4577",
+"string4578",
+"string4579",
+"string4580",
+"string4581",
+"string4582",
+"string4583",
+"string4584",
+"string4585",
+"string4586",
+"string4587",
+"string4588",
+"string4589",
+"string4590",
+"string4591",
+"string4592",
+"string4593",
+"string4594",
+"string4595",
+"string4596",
+"string4597",
+"string4598",
+"string4599",
+"string4600",
+"string4601",
+"string4602",
+"string4603",
+"string4604",
+"string4605",
+"string4606",
+"string4607",
+"string4608",
+"string4609",
+"string4610",
+"string4611",
+"string4612",
+"string4613",
+"string4614",
+"string4615",
+"string4616",
+"string4617",
+"string4618",
+"string4619",
+"string4620",
+"string4621",
+"string4622",
+"string4623",
+"string4624",
+"string4625",
+"string4626",
+"string4627",
+"string4628",
+"string4629",
+"string4630",
+"string4631",
+"string4632",
+"string4633",
+"string4634",
+"string4635",
+"string4636",
+"string4637",
+"string4638",
+"string4639",
+"string4640",
+"string4641",
+"string4642",
+"string4643",
+"string4644",
+"string4645",
+"string4646",
+"string4647",
+"string4648",
+"string4649",
+"string4650",
+"string4651",
+"string4652",
+"string4653",
+"string4654",
+"string4655",
+"string4656",
+"string4657",
+"string4658",
+"string4659",
+"string4660",
+"string4661",
+"string4662",
+"string4663",
+"string4664",
+"string4665",
+"string4666",
+"string4667",
+"string4668",
+"string4669",
+"string4670",
+"string4671",
+"string4672",
+"string4673",
+"string4674",
+"string4675",
+"string4676",
+"string4677",
+"string4678",
+"string4679",
+"string4680",
+"string4681",
+"string4682",
+"string4683",
+"string4684",
+"string4685",
+"string4686",
+"string4687",
+"string4688",
+"string4689",
+"string4690",
+"string4691",
+"string4692",
+"string4693",
+"string4694",
+"string4695",
+"string4696",
+"string4697",
+"string4698",
+"string4699",
+"string4700",
+"string4701",
+"string4702",
+"string4703",
+"string4704",
+"string4705",
+"string4706",
+"string4707",
+"string4708",
+"string4709",
+"string4710",
+"string4711",
+"string4712",
+"string4713",
+"string4714",
+"string4715",
+"string4716",
+"string4717",
+"string4718",
+"string4719",
+"string4720",
+"string4721",
+"string4722",
+"string4723",
+"string4724",
+"string4725",
+"string4726",
+"string4727",
+"string4728",
+"string4729",
+"string4730",
+"string4731",
+"string4732",
+"string4733",
+"string4734",
+"string4735",
+"string4736",
+"string4737",
+"string4738",
+"string4739",
+"string4740",
+"string4741",
+"string4742",
+"string4743",
+"string4744",
+"string4745",
+"string4746",
+"string4747",
+"string4748",
+"string4749",
+"string4750",
+"string4751",
+"string4752",
+"string4753",
+"string4754",
+"string4755",
+"string4756",
+"string4757",
+"string4758",
+"string4759",
+"string4760",
+"string4761",
+"string4762",
+"string4763",
+"string4764",
+"string4765",
+"string4766",
+"string4767",
+"string4768",
+"string4769",
+"string4770",
+"string4771",
+"string4772",
+"string4773",
+"string4774",
+"string4775",
+"string4776",
+"string4777",
+"string4778",
+"string4779",
+"string4780",
+"string4781",
+"string4782",
+"string4783",
+"string4784",
+"string4785",
+"string4786",
+"string4787",
+"string4788",
+"string4789",
+"string4790",
+"string4791",
+"string4792",
+"string4793",
+"string4794",
+"string4795",
+"string4796",
+"string4797",
+"string4798",
+"string4799",
+"string4800",
+"string4801",
+"string4802",
+"string4803",
+"string4804",
+"string4805",
+"string4806",
+"string4807",
+"string4808",
+"string4809",
+"string4810",
+"string4811",
+"string4812",
+"string4813",
+"string4814",
+"string4815",
+"string4816",
+"string4817",
+"string4818",
+"string4819",
+"string4820",
+"string4821",
+"string4822",
+"string4823",
+"string4824",
+"string4825",
+"string4826",
+"string4827",
+"string4828",
+"string4829",
+"string4830",
+"string4831",
+"string4832",
+"string4833",
+"string4834",
+"string4835",
+"string4836",
+"string4837",
+"string4838",
+"string4839",
+"string4840",
+"string4841",
+"string4842",
+"string4843",
+"string4844",
+"string4845",
+"string4846",
+"string4847",
+"string4848",
+"string4849",
+"string4850",
+"string4851",
+"string4852",
+"string4853",
+"string4854",
+"string4855",
+"string4856",
+"string4857",
+"string4858",
+"string4859",
+"string4860",
+"string4861",
+"string4862",
+"string4863",
+"string4864",
+"string4865",
+"string4866",
+"string4867",
+"string4868",
+"string4869",
+"string4870",
+"string4871",
+"string4872",
+"string4873",
+"string4874",
+"string4875",
+"string4876",
+"string4877",
+"string4878",
+"string4879",
+"string4880",
+"string4881",
+"string4882",
+"string4883",
+"string4884",
+"string4885",
+"string4886",
+"string4887",
+"string4888",
+"string4889",
+"string4890",
+"string4891",
+"string4892",
+"string4893",
+"string4894",
+"string4895",
+"string4896",
+"string4897",
+"string4898",
+"string4899",
+"string4900",
+"string4901",
+"string4902",
+"string4903",
+"string4904",
+"string4905",
+"string4906",
+"string4907",
+"string4908",
+"string4909",
+"string4910",
+"string4911",
+"string4912",
+"string4913",
+"string4914",
+"string4915",
+"string4916",
+"string4917",
+"string4918",
+"string4919",
+"string4920",
+"string4921",
+"string4922",
+"string4923",
+"string4924",
+"string4925",
+"string4926",
+"string4927",
+"string4928",
+"string4929",
+"string4930",
+"string4931",
+"string4932",
+"string4933",
+"string4934",
+"string4935",
+"string4936",
+"string4937",
+"string4938",
+"string4939",
+"string4940",
+"string4941",
+"string4942",
+"string4943",
+"string4944",
+"string4945",
+"string4946",
+"string4947",
+"string4948",
+"string4949",
+"string4950",
+"string4951",
+"string4952",
+"string4953",
+"string4954",
+"string4955",
+"string4956",
+"string4957",
+"string4958",
+"string4959",
+"string4960",
+"string4961",
+"string4962",
+"string4963",
+"string4964",
+"string4965",
+"string4966",
+"string4967",
+"string4968",
+"string4969",
+"string4970",
+"string4971",
+"string4972",
+"string4973",
+"string4974",
+"string4975",
+"string4976",
+"string4977",
+"string4978",
+"string4979",
+"string4980",
+"string4981",
+"string4982",
+"string4983",
+"string4984",
+"string4985",
+"string4986",
+"string4987",
+"string4988",
+"string4989",
+"string4990",
+"string4991",
+"string4992",
+"string4993",
+"string4994",
+"string4995",
+"string4996",
+"string4997",
+"string4998",
+"string4999",
+"string5000",
+"string5001",
+"string5002",
+"string5003",
+"string5004",
+"string5005",
+"string5006",
+"string5007",
+"string5008",
+"string5009",
+"string5010",
+"string5011",
+"string5012",
+"string5013",
+"string5014",
+"string5015",
+"string5016",
+"string5017",
+"string5018",
+"string5019",
+"string5020",
+"string5021",
+"string5022",
+"string5023",
+"string5024",
+"string5025",
+"string5026",
+"string5027",
+"string5028",
+"string5029",
+"string5030",
+"string5031",
+"string5032",
+"string5033",
+"string5034",
+"string5035",
+"string5036",
+"string5037",
+"string5038",
+"string5039",
+"string5040",
+"string5041",
+"string5042",
+"string5043",
+"string5044",
+"string5045",
+"string5046",
+"string5047",
+"string5048",
+"string5049",
+"string5050",
+"string5051",
+"string5052",
+"string5053",
+"string5054",
+"string5055",
+"string5056",
+"string5057",
+"string5058",
+"string5059",
+"string5060",
+"string5061",
+"string5062",
+"string5063",
+"string5064",
+"string5065",
+"string5066",
+"string5067",
+"string5068",
+"string5069",
+"string5070",
+"string5071",
+"string5072",
+"string5073",
+"string5074",
+"string5075",
+"string5076",
+"string5077",
+"string5078",
+"string5079",
+"string5080",
+"string5081",
+"string5082",
+"string5083",
+"string5084",
+"string5085",
+"string5086",
+"string5087",
+"string5088",
+"string5089",
+"string5090",
+"string5091",
+"string5092",
+"string5093",
+"string5094",
+"string5095",
+"string5096",
+"string5097",
+"string5098",
+"string5099",
+"string5100",
+"string5101",
+"string5102",
+"string5103",
+"string5104",
+"string5105",
+"string5106",
+"string5107",
+"string5108",
+"string5109",
+"string5110",
+"string5111",
+"string5112",
+"string5113",
+"string5114",
+"string5115",
+"string5116",
+"string5117",
+"string5118",
+"string5119",
+"string5120",
+"string5121",
+"string5122",
+"string5123",
+"string5124",
+"string5125",
+"string5126",
+"string5127",
+"string5128",
+"string5129",
+"string5130",
+"string5131",
+"string5132",
+"string5133",
+"string5134",
+"string5135",
+"string5136",
+"string5137",
+"string5138",
+"string5139",
+"string5140",
+"string5141",
+"string5142",
+"string5143",
+"string5144",
+"string5145",
+"string5146",
+"string5147",
+"string5148",
+"string5149",
+"string5150",
+"string5151",
+"string5152",
+"string5153",
+"string5154",
+"string5155",
+"string5156",
+"string5157",
+"string5158",
+"string5159",
+"string5160",
+"string5161",
+"string5162",
+"string5163",
+"string5164",
+"string5165",
+"string5166",
+"string5167",
+"string5168",
+"string5169",
+"string5170",
+"string5171",
+"string5172",
+"string5173",
+"string5174",
+"string5175",
+"string5176",
+"string5177",
+"string5178",
+"string5179",
+"string5180",
+"string5181",
+"string5182",
+"string5183",
+"string5184",
+"string5185",
+"string5186",
+"string5187",
+"string5188",
+"string5189",
+"string5190",
+"string5191",
+"string5192",
+"string5193",
+"string5194",
+"string5195",
+"string5196",
+"string5197",
+"string5198",
+"string5199",
+"string5200",
+"string5201",
+"string5202",
+"string5203",
+"string5204",
+"string5205",
+"string5206",
+"string5207",
+"string5208",
+"string5209",
+"string5210",
+"string5211",
+"string5212",
+"string5213",
+"string5214",
+"string5215",
+"string5216",
+"string5217",
+"string5218",
+"string5219",
+"string5220",
+"string5221",
+"string5222",
+"string5223",
+"string5224",
+"string5225",
+"string5226",
+"string5227",
+"string5228",
+"string5229",
+"string5230",
+"string5231",
+"string5232",
+"string5233",
+"string5234",
+"string5235",
+"string5236",
+"string5237",
+"string5238",
+"string5239",
+"string5240",
+"string5241",
+"string5242",
+"string5243",
+"string5244",
+"string5245",
+"string5246",
+"string5247",
+"string5248",
+"string5249",
+"string5250",
+"string5251",
+"string5252",
+"string5253",
+"string5254",
+"string5255",
+"string5256",
+"string5257",
+"string5258",
+"string5259",
+"string5260",
+"string5261",
+"string5262",
+"string5263",
+"string5264",
+"string5265",
+"string5266",
+"string5267",
+"string5268",
+"string5269",
+"string5270",
+"string5271",
+"string5272",
+"string5273",
+"string5274",
+"string5275",
+"string5276",
+"string5277",
+"string5278",
+"string5279",
+"string5280",
+"string5281",
+"string5282",
+"string5283",
+"string5284",
+"string5285",
+"string5286",
+"string5287",
+"string5288",
+"string5289",
+"string5290",
+"string5291",
+"string5292",
+"string5293",
+"string5294",
+"string5295",
+"string5296",
+"string5297",
+"string5298",
+"string5299",
+"string5300",
+"string5301",
+"string5302",
+"string5303",
+"string5304",
+"string5305",
+"string5306",
+"string5307",
+"string5308",
+"string5309",
+"string5310",
+"string5311",
+"string5312",
+"string5313",
+"string5314",
+"string5315",
+"string5316",
+"string5317",
+"string5318",
+"string5319",
+"string5320",
+"string5321",
+"string5322",
+"string5323",
+"string5324",
+"string5325",
+"string5326",
+"string5327",
+"string5328",
+"string5329",
+"string5330",
+"string5331",
+"string5332",
+"string5333",
+"string5334",
+"string5335",
+"string5336",
+"string5337",
+"string5338",
+"string5339",
+"string5340",
+"string5341",
+"string5342",
+"string5343",
+"string5344",
+"string5345",
+"string5346",
+"string5347",
+"string5348",
+"string5349",
+"string5350",
+"string5351",
+"string5352",
+"string5353",
+"string5354",
+"string5355",
+"string5356",
+"string5357",
+"string5358",
+"string5359",
+"string5360",
+"string5361",
+"string5362",
+"string5363",
+"string5364",
+"string5365",
+"string5366",
+"string5367",
+"string5368",
+"string5369",
+"string5370",
+"string5371",
+"string5372",
+"string5373",
+"string5374",
+"string5375",
+"string5376",
+"string5377",
+"string5378",
+"string5379",
+"string5380",
+"string5381",
+"string5382",
+"string5383",
+"string5384",
+"string5385",
+"string5386",
+"string5387",
+"string5388",
+"string5389",
+"string5390",
+"string5391",
+"string5392",
+"string5393",
+"string5394",
+"string5395",
+"string5396",
+"string5397",
+"string5398",
+"string5399",
+"string5400",
+"string5401",
+"string5402",
+"string5403",
+"string5404",
+"string5405",
+"string5406",
+"string5407",
+"string5408",
+"string5409",
+"string5410",
+"string5411",
+"string5412",
+"string5413",
+"string5414",
+"string5415",
+"string5416",
+"string5417",
+"string5418",
+"string5419",
+"string5420",
+"string5421",
+"string5422",
+"string5423",
+"string5424",
+"string5425",
+"string5426",
+"string5427",
+"string5428",
+"string5429",
+"string5430",
+"string5431",
+"string5432",
+"string5433",
+"string5434",
+"string5435",
+"string5436",
+"string5437",
+"string5438",
+"string5439",
+"string5440",
+"string5441",
+"string5442",
+"string5443",
+"string5444",
+"string5445",
+"string5446",
+"string5447",
+"string5448",
+"string5449",
+"string5450",
+"string5451",
+"string5452",
+"string5453",
+"string5454",
+"string5455",
+"string5456",
+"string5457",
+"string5458",
+"string5459",
+"string5460",
+"string5461",
+"string5462",
+"string5463",
+"string5464",
+"string5465",
+"string5466",
+"string5467",
+"string5468",
+"string5469",
+"string5470",
+"string5471",
+"string5472",
+"string5473",
+"string5474",
+"string5475",
+"string5476",
+"string5477",
+"string5478",
+"string5479",
+"string5480",
+"string5481",
+"string5482",
+"string5483",
+"string5484",
+"string5485",
+"string5486",
+"string5487",
+"string5488",
+"string5489",
+"string5490",
+"string5491",
+"string5492",
+"string5493",
+"string5494",
+"string5495",
+"string5496",
+"string5497",
+"string5498",
+"string5499",
+"string5500",
+"string5501",
+"string5502",
+"string5503",
+"string5504",
+"string5505",
+"string5506",
+"string5507",
+"string5508",
+"string5509",
+"string5510",
+"string5511",
+"string5512",
+"string5513",
+"string5514",
+"string5515",
+"string5516",
+"string5517",
+"string5518",
+"string5519",
+"string5520",
+"string5521",
+"string5522",
+"string5523",
+"string5524",
+"string5525",
+"string5526",
+"string5527",
+"string5528",
+"string5529",
+"string5530",
+"string5531",
+"string5532",
+"string5533",
+"string5534",
+"string5535",
+"string5536",
+"string5537",
+"string5538",
+"string5539",
+"string5540",
+"string5541",
+"string5542",
+"string5543",
+"string5544",
+"string5545",
+"string5546",
+"string5547",
+"string5548",
+"string5549",
+"string5550",
+"string5551",
+"string5552",
+"string5553",
+"string5554",
+"string5555",
+"string5556",
+"string5557",
+"string5558",
+"string5559",
+"string5560",
+"string5561",
+"string5562",
+"string5563",
+"string5564",
+"string5565",
+"string5566",
+"string5567",
+"string5568",
+"string5569",
+"string5570",
+"string5571",
+"string5572",
+"string5573",
+"string5574",
+"string5575",
+"string5576",
+"string5577",
+"string5578",
+"string5579",
+"string5580",
+"string5581",
+"string5582",
+"string5583",
+"string5584",
+"string5585",
+"string5586",
+"string5587",
+"string5588",
+"string5589",
+"string5590",
+"string5591",
+"string5592",
+"string5593",
+"string5594",
+"string5595",
+"string5596",
+"string5597",
+"string5598",
+"string5599",
+"string5600",
+"string5601",
+"string5602",
+"string5603",
+"string5604",
+"string5605",
+"string5606",
+"string5607",
+"string5608",
+"string5609",
+"string5610",
+"string5611",
+"string5612",
+"string5613",
+"string5614",
+"string5615",
+"string5616",
+"string5617",
+"string5618",
+"string5619",
+"string5620",
+"string5621",
+"string5622",
+"string5623",
+"string5624",
+"string5625",
+"string5626",
+"string5627",
+"string5628",
+"string5629",
+"string5630",
+"string5631",
+"string5632",
+"string5633",
+"string5634",
+"string5635",
+"string5636",
+"string5637",
+"string5638",
+"string5639",
+"string5640",
+"string5641",
+"string5642",
+"string5643",
+"string5644",
+"string5645",
+"string5646",
+"string5647",
+"string5648",
+"string5649",
+"string5650",
+"string5651",
+"string5652",
+"string5653",
+"string5654",
+"string5655",
+"string5656",
+"string5657",
+"string5658",
+"string5659",
+"string5660",
+"string5661",
+"string5662",
+"string5663",
+"string5664",
+"string5665",
+"string5666",
+"string5667",
+"string5668",
+"string5669",
+"string5670",
+"string5671",
+"string5672",
+"string5673",
+"string5674",
+"string5675",
+"string5676",
+"string5677",
+"string5678",
+"string5679",
+"string5680",
+"string5681",
+"string5682",
+"string5683",
+"string5684",
+"string5685",
+"string5686",
+"string5687",
+"string5688",
+"string5689",
+"string5690",
+"string5691",
+"string5692",
+"string5693",
+"string5694",
+"string5695",
+"string5696",
+"string5697",
+"string5698",
+"string5699",
+"string5700",
+"string5701",
+"string5702",
+"string5703",
+"string5704",
+"string5705",
+"string5706",
+"string5707",
+"string5708",
+"string5709",
+"string5710",
+"string5711",
+"string5712",
+"string5713",
+"string5714",
+"string5715",
+"string5716",
+"string5717",
+"string5718",
+"string5719",
+"string5720",
+"string5721",
+"string5722",
+"string5723",
+"string5724",
+"string5725",
+"string5726",
+"string5727",
+"string5728",
+"string5729",
+"string5730",
+"string5731",
+"string5732",
+"string5733",
+"string5734",
+"string5735",
+"string5736",
+"string5737",
+"string5738",
+"string5739",
+"string5740",
+"string5741",
+"string5742",
+"string5743",
+"string5744",
+"string5745",
+"string5746",
+"string5747",
+"string5748",
+"string5749",
+"string5750",
+"string5751",
+"string5752",
+"string5753",
+"string5754",
+"string5755",
+"string5756",
+"string5757",
+"string5758",
+"string5759",
+"string5760",
+"string5761",
+"string5762",
+"string5763",
+"string5764",
+"string5765",
+"string5766",
+"string5767",
+"string5768",
+"string5769",
+"string5770",
+"string5771",
+"string5772",
+"string5773",
+"string5774",
+"string5775",
+"string5776",
+"string5777",
+"string5778",
+"string5779",
+"string5780",
+"string5781",
+"string5782",
+"string5783",
+"string5784",
+"string5785",
+"string5786",
+"string5787",
+"string5788",
+"string5789",
+"string5790",
+"string5791",
+"string5792",
+"string5793",
+"string5794",
+"string5795",
+"string5796",
+"string5797",
+"string5798",
+"string5799",
+"string5800",
+"string5801",
+"string5802",
+"string5803",
+"string5804",
+"string5805",
+"string5806",
+"string5807",
+"string5808",
+"string5809",
+"string5810",
+"string5811",
+"string5812",
+"string5813",
+"string5814",
+"string5815",
+"string5816",
+"string5817",
+"string5818",
+"string5819",
+"string5820",
+"string5821",
+"string5822",
+"string5823",
+"string5824",
+"string5825",
+"string5826",
+"string5827",
+"string5828",
+"string5829",
+"string5830",
+"string5831",
+"string5832",
+"string5833",
+"string5834",
+"string5835",
+"string5836",
+"string5837",
+"string5838",
+"string5839",
+"string5840",
+"string5841",
+"string5842",
+"string5843",
+"string5844",
+"string5845",
+"string5846",
+"string5847",
+"string5848",
+"string5849",
+"string5850",
+"string5851",
+"string5852",
+"string5853",
+"string5854",
+"string5855",
+"string5856",
+"string5857",
+"string5858",
+"string5859",
+"string5860",
+"string5861",
+"string5862",
+"string5863",
+"string5864",
+"string5865",
+"string5866",
+"string5867",
+"string5868",
+"string5869",
+"string5870",
+"string5871",
+"string5872",
+"string5873",
+"string5874",
+"string5875",
+"string5876",
+"string5877",
+"string5878",
+"string5879",
+"string5880",
+"string5881",
+"string5882",
+"string5883",
+"string5884",
+"string5885",
+"string5886",
+"string5887",
+"string5888",
+"string5889",
+"string5890",
+"string5891",
+"string5892",
+"string5893",
+"string5894",
+"string5895",
+"string5896",
+"string5897",
+"string5898",
+"string5899",
+"string5900",
+"string5901",
+"string5902",
+"string5903",
+"string5904",
+"string5905",
+"string5906",
+"string5907",
+"string5908",
+"string5909",
+"string5910",
+"string5911",
+"string5912",
+"string5913",
+"string5914",
+"string5915",
+"string5916",
+"string5917",
+"string5918",
+"string5919",
+"string5920",
+"string5921",
+"string5922",
+"string5923",
+"string5924",
+"string5925",
+"string5926",
+"string5927",
+"string5928",
+"string5929",
+"string5930",
+"string5931",
+"string5932",
+"string5933",
+"string5934",
+"string5935",
+"string5936",
+"string5937",
+"string5938",
+"string5939",
+"string5940",
+"string5941",
+"string5942",
+"string5943",
+"string5944",
+"string5945",
+"string5946",
+"string5947",
+"string5948",
+"string5949",
+"string5950",
+"string5951",
+"string5952",
+"string5953",
+"string5954",
+"string5955",
+"string5956",
+"string5957",
+"string5958",
+"string5959",
+"string5960",
+"string5961",
+"string5962",
+"string5963",
+"string5964",
+"string5965",
+"string5966",
+"string5967",
+"string5968",
+"string5969",
+"string5970",
+"string5971",
+"string5972",
+"string5973",
+"string5974",
+"string5975",
+"string5976",
+"string5977",
+"string5978",
+"string5979",
+"string5980",
+"string5981",
+"string5982",
+"string5983",
+"string5984",
+"string5985",
+"string5986",
+"string5987",
+"string5988",
+"string5989",
+"string5990",
+"string5991",
+"string5992",
+"string5993",
+"string5994",
+"string5995",
+"string5996",
+"string5997",
+"string5998",
+"string5999",
+"string6000",
+"string6001",
+"string6002",
+"string6003",
+"string6004",
+"string6005",
+"string6006",
+"string6007",
+"string6008",
+"string6009",
+"string6010",
+"string6011",
+"string6012",
+"string6013",
+"string6014",
+"string6015",
+"string6016",
+"string6017",
+"string6018",
+"string6019",
+"string6020",
+"string6021",
+"string6022",
+"string6023",
+"string6024",
+"string6025",
+"string6026",
+"string6027",
+"string6028",
+"string6029",
+"string6030",
+"string6031",
+"string6032",
+"string6033",
+"string6034",
+"string6035",
+"string6036",
+"string6037",
+"string6038",
+"string6039",
+"string6040",
+"string6041",
+"string6042",
+"string6043",
+"string6044",
+"string6045",
+"string6046",
+"string6047",
+"string6048",
+"string6049",
+"string6050",
+"string6051",
+"string6052",
+"string6053",
+"string6054",
+"string6055",
+"string6056",
+"string6057",
+"string6058",
+"string6059",
+"string6060",
+"string6061",
+"string6062",
+"string6063",
+"string6064",
+"string6065",
+"string6066",
+"string6067",
+"string6068",
+"string6069",
+"string6070",
+"string6071",
+"string6072",
+"string6073",
+"string6074",
+"string6075",
+"string6076",
+"string6077",
+"string6078",
+"string6079",
+"string6080",
+"string6081",
+"string6082",
+"string6083",
+"string6084",
+"string6085",
+"string6086",
+"string6087",
+"string6088",
+"string6089",
+"string6090",
+"string6091",
+"string6092",
+"string6093",
+"string6094",
+"string6095",
+"string6096",
+"string6097",
+"string6098",
+"string6099",
+"string6100",
+"string6101",
+"string6102",
+"string6103",
+"string6104",
+"string6105",
+"string6106",
+"string6107",
+"string6108",
+"string6109",
+"string6110",
+"string6111",
+"string6112",
+"string6113",
+"string6114",
+"string6115",
+"string6116",
+"string6117",
+"string6118",
+"string6119",
+"string6120",
+"string6121",
+"string6122",
+"string6123",
+"string6124",
+"string6125",
+"string6126",
+"string6127",
+"string6128",
+"string6129",
+"string6130",
+"string6131",
+"string6132",
+"string6133",
+"string6134",
+"string6135",
+"string6136",
+"string6137",
+"string6138",
+"string6139",
+"string6140",
+"string6141",
+"string6142",
+"string6143",
+"string6144",
+"string6145",
+"string6146",
+"string6147",
+"string6148",
+"string6149",
+"string6150",
+"string6151",
+"string6152",
+"string6153",
+"string6154",
+"string6155",
+"string6156",
+"string6157",
+"string6158",
+"string6159",
+"string6160",
+"string6161",
+"string6162",
+"string6163",
+"string6164",
+"string6165",
+"string6166",
+"string6167",
+"string6168",
+"string6169",
+"string6170",
+"string6171",
+"string6172",
+"string6173",
+"string6174",
+"string6175",
+"string6176",
+"string6177",
+"string6178",
+"string6179",
+"string6180",
+"string6181",
+"string6182",
+"string6183",
+"string6184",
+"string6185",
+"string6186",
+"string6187",
+"string6188",
+"string6189",
+"string6190",
+"string6191",
+"string6192",
+"string6193",
+"string6194",
+"string6195",
+"string6196",
+"string6197",
+"string6198",
+"string6199",
+"string6200",
+"string6201",
+"string6202",
+"string6203",
+"string6204",
+"string6205",
+"string6206",
+"string6207",
+"string6208",
+"string6209",
+"string6210",
+"string6211",
+"string6212",
+"string6213",
+"string6214",
+"string6215",
+"string6216",
+"string6217",
+"string6218",
+"string6219",
+"string6220",
+"string6221",
+"string6222",
+"string6223",
+"string6224",
+"string6225",
+"string6226",
+"string6227",
+"string6228",
+"string6229",
+"string6230",
+"string6231",
+"string6232",
+"string6233",
+"string6234",
+"string6235",
+"string6236",
+"string6237",
+"string6238",
+"string6239",
+"string6240",
+"string6241",
+"string6242",
+"string6243",
+"string6244",
+"string6245",
+"string6246",
+"string6247",
+"string6248",
+"string6249",
+"string6250",
+"string6251",
+"string6252",
+"string6253",
+"string6254",
+"string6255",
+"string6256",
+"string6257",
+"string6258",
+"string6259",
+"string6260",
+"string6261",
+"string6262",
+"string6263",
+"string6264",
+"string6265",
+"string6266",
+"string6267",
+"string6268",
+"string6269",
+"string6270",
+"string6271",
+"string6272",
+"string6273",
+"string6274",
+"string6275",
+"string6276",
+"string6277",
+"string6278",
+"string6279",
+"string6280",
+"string6281",
+"string6282",
+"string6283",
+"string6284",
+"string6285",
+"string6286",
+"string6287",
+"string6288",
+"string6289",
+"string6290",
+"string6291",
+"string6292",
+"string6293",
+"string6294",
+"string6295",
+"string6296",
+"string6297",
+"string6298",
+"string6299",
+"string6300",
+"string6301",
+"string6302",
+"string6303",
+"string6304",
+"string6305",
+"string6306",
+"string6307",
+"string6308",
+"string6309",
+"string6310",
+"string6311",
+"string6312",
+"string6313",
+"string6314",
+"string6315",
+"string6316",
+"string6317",
+"string6318",
+"string6319",
+"string6320",
+"string6321",
+"string6322",
+"string6323",
+"string6324",
+"string6325",
+"string6326",
+"string6327",
+"string6328",
+"string6329",
+"string6330",
+"string6331",
+"string6332",
+"string6333",
+"string6334",
+"string6335",
+"string6336",
+"string6337",
+"string6338",
+"string6339",
+"string6340",
+"string6341",
+"string6342",
+"string6343",
+"string6344",
+"string6345",
+"string6346",
+"string6347",
+"string6348",
+"string6349",
+"string6350",
+"string6351",
+"string6352",
+"string6353",
+"string6354",
+"string6355",
+"string6356",
+"string6357",
+"string6358",
+"string6359",
+"string6360",
+"string6361",
+"string6362",
+"string6363",
+"string6364",
+"string6365",
+"string6366",
+"string6367",
+"string6368",
+"string6369",
+"string6370",
+"string6371",
+"string6372",
+"string6373",
+"string6374",
+"string6375",
+"string6376",
+"string6377",
+"string6378",
+"string6379",
+"string6380",
+"string6381",
+"string6382",
+"string6383",
+"string6384",
+"string6385",
+"string6386",
+"string6387",
+"string6388",
+"string6389",
+"string6390",
+"string6391",
+"string6392",
+"string6393",
+"string6394",
+"string6395",
+"string6396",
+"string6397",
+"string6398",
+"string6399",
+"string6400",
+"string6401",
+"string6402",
+"string6403",
+"string6404",
+"string6405",
+"string6406",
+"string6407",
+"string6408",
+"string6409",
+"string6410",
+"string6411",
+"string6412",
+"string6413",
+"string6414",
+"string6415",
+"string6416",
+"string6417",
+"string6418",
+"string6419",
+"string6420",
+"string6421",
+"string6422",
+"string6423",
+"string6424",
+"string6425",
+"string6426",
+"string6427",
+"string6428",
+"string6429",
+"string6430",
+"string6431",
+"string6432",
+"string6433",
+"string6434",
+"string6435",
+"string6436",
+"string6437",
+"string6438",
+"string6439",
+"string6440",
+"string6441",
+"string6442",
+"string6443",
+"string6444",
+"string6445",
+"string6446",
+"string6447",
+"string6448",
+"string6449",
+"string6450",
+"string6451",
+"string6452",
+"string6453",
+"string6454",
+"string6455",
+"string6456",
+"string6457",
+"string6458",
+"string6459",
+"string6460",
+"string6461",
+"string6462",
+"string6463",
+"string6464",
+"string6465",
+"string6466",
+"string6467",
+"string6468",
+"string6469",
+"string6470",
+"string6471",
+"string6472",
+"string6473",
+"string6474",
+"string6475",
+"string6476",
+"string6477",
+"string6478",
+"string6479",
+"string6480",
+"string6481",
+"string6482",
+"string6483",
+"string6484",
+"string6485",
+"string6486",
+"string6487",
+"string6488",
+"string6489",
+"string6490",
+"string6491",
+"string6492",
+"string6493",
+"string6494",
+"string6495",
+"string6496",
+"string6497",
+"string6498",
+"string6499",
+"string6500",
+"string6501",
+"string6502",
+"string6503",
+"string6504",
+"string6505",
+"string6506",
+"string6507",
+"string6508",
+"string6509",
+"string6510",
+"string6511",
+"string6512",
+"string6513",
+"string6514",
+"string6515",
+"string6516",
+"string6517",
+"string6518",
+"string6519",
+"string6520",
+"string6521",
+"string6522",
+"string6523",
+"string6524",
+"string6525",
+"string6526",
+"string6527",
+"string6528",
+"string6529",
+"string6530",
+"string6531",
+"string6532",
+"string6533",
+"string6534",
+"string6535",
+"string6536",
+"string6537",
+"string6538",
+"string6539",
+"string6540",
+"string6541",
+"string6542",
+"string6543",
+"string6544",
+"string6545",
+"string6546",
+"string6547",
+"string6548",
+"string6549",
+"string6550",
+"string6551",
+"string6552",
+"string6553",
+"string6554",
+"string6555",
+"string6556",
+"string6557",
+"string6558",
+"string6559",
+"string6560",
+"string6561",
+"string6562",
+"string6563",
+"string6564",
+"string6565",
+"string6566",
+"string6567",
+"string6568",
+"string6569",
+"string6570",
+"string6571",
+"string6572",
+"string6573",
+"string6574",
+"string6575",
+"string6576",
+"string6577",
+"string6578",
+"string6579",
+"string6580",
+"string6581",
+"string6582",
+"string6583",
+"string6584",
+"string6585",
+"string6586",
+"string6587",
+"string6588",
+"string6589",
+"string6590",
+"string6591",
+"string6592",
+"string6593",
+"string6594",
+"string6595",
+"string6596",
+"string6597",
+"string6598",
+"string6599",
+"string6600",
+"string6601",
+"string6602",
+"string6603",
+"string6604",
+"string6605",
+"string6606",
+"string6607",
+"string6608",
+"string6609",
+"string6610",
+"string6611",
+"string6612",
+"string6613",
+"string6614",
+"string6615",
+"string6616",
+"string6617",
+"string6618",
+"string6619",
+"string6620",
+"string6621",
+"string6622",
+"string6623",
+"string6624",
+"string6625",
+"string6626",
+"string6627",
+"string6628",
+"string6629",
+"string6630",
+"string6631",
+"string6632",
+"string6633",
+"string6634",
+"string6635",
+"string6636",
+"string6637",
+"string6638",
+"string6639",
+"string6640",
+"string6641",
+"string6642",
+"string6643",
+"string6644",
+"string6645",
+"string6646",
+"string6647",
+"string6648",
+"string6649",
+"string6650",
+"string6651",
+"string6652",
+"string6653",
+"string6654",
+"string6655",
+"string6656",
+"string6657",
+"string6658",
+"string6659",
+"string6660",
+"string6661",
+"string6662",
+"string6663",
+"string6664",
+"string6665",
+"string6666",
+"string6667",
+"string6668",
+"string6669",
+"string6670",
+"string6671",
+"string6672",
+"string6673",
+"string6674",
+"string6675",
+"string6676",
+"string6677",
+"string6678",
+"string6679",
+"string6680",
+"string6681",
+"string6682",
+"string6683",
+"string6684",
+"string6685",
+"string6686",
+"string6687",
+"string6688",
+"string6689",
+"string6690",
+"string6691",
+"string6692",
+"string6693",
+"string6694",
+"string6695",
+"string6696",
+"string6697",
+"string6698",
+"string6699",
+"string6700",
+"string6701",
+"string6702",
+"string6703",
+"string6704",
+"string6705",
+"string6706",
+"string6707",
+"string6708",
+"string6709",
+"string6710",
+"string6711",
+"string6712",
+"string6713",
+"string6714",
+"string6715",
+"string6716",
+"string6717",
+"string6718",
+"string6719",
+"string6720",
+"string6721",
+"string6722",
+"string6723",
+"string6724",
+"string6725",
+"string6726",
+"string6727",
+"string6728",
+"string6729",
+"string6730",
+"string6731",
+"string6732",
+"string6733",
+"string6734",
+"string6735",
+"string6736",
+"string6737",
+"string6738",
+"string6739",
+"string6740",
+"string6741",
+"string6742",
+"string6743",
+"string6744",
+"string6745",
+"string6746",
+"string6747",
+"string6748",
+"string6749",
+"string6750",
+"string6751",
+"string6752",
+"string6753",
+"string6754",
+"string6755",
+"string6756",
+"string6757",
+"string6758",
+"string6759",
+"string6760",
+"string6761",
+"string6762",
+"string6763",
+"string6764",
+"string6765",
+"string6766",
+"string6767",
+"string6768",
+"string6769",
+"string6770",
+"string6771",
+"string6772",
+"string6773",
+"string6774",
+"string6775",
+"string6776",
+"string6777",
+"string6778",
+"string6779",
+"string6780",
+"string6781",
+"string6782",
+"string6783",
+"string6784",
+"string6785",
+"string6786",
+"string6787",
+"string6788",
+"string6789",
+"string6790",
+"string6791",
+"string6792",
+"string6793",
+"string6794",
+"string6795",
+"string6796",
+"string6797",
+"string6798",
+"string6799",
+"string6800",
+"string6801",
+"string6802",
+"string6803",
+"string6804",
+"string6805",
+"string6806",
+"string6807",
+"string6808",
+"string6809",
+"string6810",
+"string6811",
+"string6812",
+"string6813",
+"string6814",
+"string6815",
+"string6816",
+"string6817",
+"string6818",
+"string6819",
+"string6820",
+"string6821",
+"string6822",
+"string6823",
+"string6824",
+"string6825",
+"string6826",
+"string6827",
+"string6828",
+"string6829",
+"string6830",
+"string6831",
+"string6832",
+"string6833",
+"string6834",
+"string6835",
+"string6836",
+"string6837",
+"string6838",
+"string6839",
+"string6840",
+"string6841",
+"string6842",
+"string6843",
+"string6844",
+"string6845",
+"string6846",
+"string6847",
+"string6848",
+"string6849",
+"string6850",
+"string6851",
+"string6852",
+"string6853",
+"string6854",
+"string6855",
+"string6856",
+"string6857",
+"string6858",
+"string6859",
+"string6860",
+"string6861",
+"string6862",
+"string6863",
+"string6864",
+"string6865",
+"string6866",
+"string6867",
+"string6868",
+"string6869",
+"string6870",
+"string6871",
+"string6872",
+"string6873",
+"string6874",
+"string6875",
+"string6876",
+"string6877",
+"string6878",
+"string6879",
+"string6880",
+"string6881",
+"string6882",
+"string6883",
+"string6884",
+"string6885",
+"string6886",
+"string6887",
+"string6888",
+"string6889",
+"string6890",
+"string6891",
+"string6892",
+"string6893",
+"string6894",
+"string6895",
+"string6896",
+"string6897",
+"string6898",
+"string6899",
+"string6900",
+"string6901",
+"string6902",
+"string6903",
+"string6904",
+"string6905",
+"string6906",
+"string6907",
+"string6908",
+"string6909",
+"string6910",
+"string6911",
+"string6912",
+"string6913",
+"string6914",
+"string6915",
+"string6916",
+"string6917",
+"string6918",
+"string6919",
+"string6920",
+"string6921",
+"string6922",
+"string6923",
+"string6924",
+"string6925",
+"string6926",
+"string6927",
+"string6928",
+"string6929",
+"string6930",
+"string6931",
+"string6932",
+"string6933",
+"string6934",
+"string6935",
+"string6936",
+"string6937",
+"string6938",
+"string6939",
+"string6940",
+"string6941",
+"string6942",
+"string6943",
+"string6944",
+"string6945",
+"string6946",
+"string6947",
+"string6948",
+"string6949",
+"string6950",
+"string6951",
+"string6952",
+"string6953",
+"string6954",
+"string6955",
+"string6956",
+"string6957",
+"string6958",
+"string6959",
+"string6960",
+"string6961",
+"string6962",
+"string6963",
+"string6964",
+"string6965",
+"string6966",
+"string6967",
+"string6968",
+"string6969",
+"string6970",
+"string6971",
+"string6972",
+"string6973",
+"string6974",
+"string6975",
+"string6976",
+"string6977",
+"string6978",
+"string6979",
+"string6980",
+"string6981",
+"string6982",
+"string6983",
+"string6984",
+"string6985",
+"string6986",
+"string6987",
+"string6988",
+"string6989",
+"string6990",
+"string6991",
+"string6992",
+"string6993",
+"string6994",
+"string6995",
+"string6996",
+"string6997",
+"string6998",
+"string6999",
+"string7000",
+"string7001",
+"string7002",
+"string7003",
+"string7004",
+"string7005",
+"string7006",
+"string7007",
+"string7008",
+"string7009",
+"string7010",
+"string7011",
+"string7012",
+"string7013",
+"string7014",
+"string7015",
+"string7016",
+"string7017",
+"string7018",
+"string7019",
+"string7020",
+"string7021",
+"string7022",
+"string7023",
+"string7024",
+"string7025",
+"string7026",
+"string7027",
+"string7028",
+"string7029",
+"string7030",
+"string7031",
+"string7032",
+"string7033",
+"string7034",
+"string7035",
+"string7036",
+"string7037",
+"string7038",
+"string7039",
+"string7040",
+"string7041",
+"string7042",
+"string7043",
+"string7044",
+"string7045",
+"string7046",
+"string7047",
+"string7048",
+"string7049",
+"string7050",
+"string7051",
+"string7052",
+"string7053",
+"string7054",
+"string7055",
+"string7056",
+"string7057",
+"string7058",
+"string7059",
+"string7060",
+"string7061",
+"string7062",
+"string7063",
+"string7064",
+"string7065",
+"string7066",
+"string7067",
+"string7068",
+"string7069",
+"string7070",
+"string7071",
+"string7072",
+"string7073",
+"string7074",
+"string7075",
+"string7076",
+"string7077",
+"string7078",
+"string7079",
+"string7080",
+"string7081",
+"string7082",
+"string7083",
+"string7084",
+"string7085",
+"string7086",
+"string7087",
+"string7088",
+"string7089",
+"string7090",
+"string7091",
+"string7092",
+"string7093",
+"string7094",
+"string7095",
+"string7096",
+"string7097",
+"string7098",
+"string7099",
+"string7100",
+"string7101",
+"string7102",
+"string7103",
+"string7104",
+"string7105",
+"string7106",
+"string7107",
+"string7108",
+"string7109",
+"string7110",
+"string7111",
+"string7112",
+"string7113",
+"string7114",
+"string7115",
+"string7116",
+"string7117",
+"string7118",
+"string7119",
+"string7120",
+"string7121",
+"string7122",
+"string7123",
+"string7124",
+"string7125",
+"string7126",
+"string7127",
+"string7128",
+"string7129",
+"string7130",
+"string7131",
+"string7132",
+"string7133",
+"string7134",
+"string7135",
+"string7136",
+"string7137",
+"string7138",
+"string7139",
+"string7140",
+"string7141",
+"string7142",
+"string7143",
+"string7144",
+"string7145",
+"string7146",
+"string7147",
+"string7148",
+"string7149",
+"string7150",
+"string7151",
+"string7152",
+"string7153",
+"string7154",
+"string7155",
+"string7156",
+"string7157",
+"string7158",
+"string7159",
+"string7160",
+"string7161",
+"string7162",
+"string7163",
+"string7164",
+"string7165",
+"string7166",
+"string7167",
+"string7168",
+"string7169",
+"string7170",
+"string7171",
+"string7172",
+"string7173",
+"string7174",
+"string7175",
+"string7176",
+"string7177",
+"string7178",
+"string7179",
+"string7180",
+"string7181",
+"string7182",
+"string7183",
+"string7184",
+"string7185",
+"string7186",
+"string7187",
+"string7188",
+"string7189",
+"string7190",
+"string7191",
+"string7192",
+"string7193",
+"string7194",
+"string7195",
+"string7196",
+"string7197",
+"string7198",
+"string7199",
+"string7200",
+"string7201",
+"string7202",
+"string7203",
+"string7204",
+"string7205",
+"string7206",
+"string7207",
+"string7208",
+"string7209",
+"string7210",
+"string7211",
+"string7212",
+"string7213",
+"string7214",
+"string7215",
+"string7216",
+"string7217",
+"string7218",
+"string7219",
+"string7220",
+"string7221",
+"string7222",
+"string7223",
+"string7224",
+"string7225",
+"string7226",
+"string7227",
+"string7228",
+"string7229",
+"string7230",
+"string7231",
+"string7232",
+"string7233",
+"string7234",
+"string7235",
+"string7236",
+"string7237",
+"string7238",
+"string7239",
+"string7240",
+"string7241",
+"string7242",
+"string7243",
+"string7244",
+"string7245",
+"string7246",
+"string7247",
+"string7248",
+"string7249",
+"string7250",
+"string7251",
+"string7252",
+"string7253",
+"string7254",
+"string7255",
+"string7256",
+"string7257",
+"string7258",
+"string7259",
+"string7260",
+"string7261",
+"string7262",
+"string7263",
+"string7264",
+"string7265",
+"string7266",
+"string7267",
+"string7268",
+"string7269",
+"string7270",
+"string7271",
+"string7272",
+"string7273",
+"string7274",
+"string7275",
+"string7276",
+"string7277",
+"string7278",
+"string7279",
+"string7280",
+"string7281",
+"string7282",
+"string7283",
+"string7284",
+"string7285",
+"string7286",
+"string7287",
+"string7288",
+"string7289",
+"string7290",
+"string7291",
+"string7292",
+"string7293",
+"string7294",
+"string7295",
+"string7296",
+"string7297",
+"string7298",
+"string7299",
+"string7300",
+"string7301",
+"string7302",
+"string7303",
+"string7304",
+"string7305",
+"string7306",
+"string7307",
+"string7308",
+"string7309",
+"string7310",
+"string7311",
+"string7312",
+"string7313",
+"string7314",
+"string7315",
+"string7316",
+"string7317",
+"string7318",
+"string7319",
+"string7320",
+"string7321",
+"string7322",
+"string7323",
+"string7324",
+"string7325",
+"string7326",
+"string7327",
+"string7328",
+"string7329",
+"string7330",
+"string7331",
+"string7332",
+"string7333",
+"string7334",
+"string7335",
+"string7336",
+"string7337",
+"string7338",
+"string7339",
+"string7340",
+"string7341",
+"string7342",
+"string7343",
+"string7344",
+"string7345",
+"string7346",
+"string7347",
+"string7348",
+"string7349",
+"string7350",
+"string7351",
+"string7352",
+"string7353",
+"string7354",
+"string7355",
+"string7356",
+"string7357",
+"string7358",
+"string7359",
+"string7360",
+"string7361",
+"string7362",
+"string7363",
+"string7364",
+"string7365",
+"string7366",
+"string7367",
+"string7368",
+"string7369",
+"string7370",
+"string7371",
+"string7372",
+"string7373",
+"string7374",
+"string7375",
+"string7376",
+"string7377",
+"string7378",
+"string7379",
+"string7380",
+"string7381",
+"string7382",
+"string7383",
+"string7384",
+"string7385",
+"string7386",
+"string7387",
+"string7388",
+"string7389",
+"string7390",
+"string7391",
+"string7392",
+"string7393",
+"string7394",
+"string7395",
+"string7396",
+"string7397",
+"string7398",
+"string7399",
+"string7400",
+"string7401",
+"string7402",
+"string7403",
+"string7404",
+"string7405",
+"string7406",
+"string7407",
+"string7408",
+"string7409",
+"string7410",
+"string7411",
+"string7412",
+"string7413",
+"string7414",
+"string7415",
+"string7416",
+"string7417",
+"string7418",
+"string7419",
+"string7420",
+"string7421",
+"string7422",
+"string7423",
+"string7424",
+"string7425",
+"string7426",
+"string7427",
+"string7428",
+"string7429",
+"string7430",
+"string7431",
+"string7432",
+"string7433",
+"string7434",
+"string7435",
+"string7436",
+"string7437",
+"string7438",
+"string7439",
+"string7440",
+"string7441",
+"string7442",
+"string7443",
+"string7444",
+"string7445",
+"string7446",
+"string7447",
+"string7448",
+"string7449",
+"string7450",
+"string7451",
+"string7452",
+"string7453",
+"string7454",
+"string7455",
+"string7456",
+"string7457",
+"string7458",
+"string7459",
+"string7460",
+"string7461",
+"string7462",
+"string7463",
+"string7464",
+"string7465",
+"string7466",
+"string7467",
+"string7468",
+"string7469",
+"string7470",
+"string7471",
+"string7472",
+"string7473",
+"string7474",
+"string7475",
+"string7476",
+"string7477",
+"string7478",
+"string7479",
+"string7480",
+"string7481",
+"string7482",
+"string7483",
+"string7484",
+"string7485",
+"string7486",
+"string7487",
+"string7488",
+"string7489",
+"string7490",
+"string7491",
+"string7492",
+"string7493",
+"string7494",
+"string7495",
+"string7496",
+"string7497",
+"string7498",
+"string7499",
+"string7500",
+"string7501",
+"string7502",
+"string7503",
+"string7504",
+"string7505",
+"string7506",
+"string7507",
+"string7508",
+"string7509",
+"string7510",
+"string7511",
+"string7512",
+"string7513",
+"string7514",
+"string7515",
+"string7516",
+"string7517",
+"string7518",
+"string7519",
+"string7520",
+"string7521",
+"string7522",
+"string7523",
+"string7524",
+"string7525",
+"string7526",
+"string7527",
+"string7528",
+"string7529",
+"string7530",
+"string7531",
+"string7532",
+"string7533",
+"string7534",
+"string7535",
+"string7536",
+"string7537",
+"string7538",
+"string7539",
+"string7540",
+"string7541",
+"string7542",
+"string7543",
+"string7544",
+"string7545",
+"string7546",
+"string7547",
+"string7548",
+"string7549",
+"string7550",
+"string7551",
+"string7552",
+"string7553",
+"string7554",
+"string7555",
+"string7556",
+"string7557",
+"string7558",
+"string7559",
+"string7560",
+"string7561",
+"string7562",
+"string7563",
+"string7564",
+"string7565",
+"string7566",
+"string7567",
+"string7568",
+"string7569",
+"string7570",
+"string7571",
+"string7572",
+"string7573",
+"string7574",
+"string7575",
+"string7576",
+"string7577",
+"string7578",
+"string7579",
+"string7580",
+"string7581",
+"string7582",
+"string7583",
+"string7584",
+"string7585",
+"string7586",
+"string7587",
+"string7588",
+"string7589",
+"string7590",
+"string7591",
+"string7592",
+"string7593",
+"string7594",
+"string7595",
+"string7596",
+"string7597",
+"string7598",
+"string7599",
+"string7600",
+"string7601",
+"string7602",
+"string7603",
+"string7604",
+"string7605",
+"string7606",
+"string7607",
+"string7608",
+"string7609",
+"string7610",
+"string7611",
+"string7612",
+"string7613",
+"string7614",
+"string7615",
+"string7616",
+"string7617",
+"string7618",
+"string7619",
+"string7620",
+"string7621",
+"string7622",
+"string7623",
+"string7624",
+"string7625",
+"string7626",
+"string7627",
+"string7628",
+"string7629",
+"string7630",
+"string7631",
+"string7632",
+"string7633",
+"string7634",
+"string7635",
+"string7636",
+"string7637",
+"string7638",
+"string7639",
+"string7640",
+"string7641",
+"string7642",
+"string7643",
+"string7644",
+"string7645",
+"string7646",
+"string7647",
+"string7648",
+"string7649",
+"string7650",
+"string7651",
+"string7652",
+"string7653",
+"string7654",
+"string7655",
+"string7656",
+"string7657",
+"string7658",
+"string7659",
+"string7660",
+"string7661",
+"string7662",
+"string7663",
+"string7664",
+"string7665",
+"string7666",
+"string7667",
+"string7668",
+"string7669",
+"string7670",
+"string7671",
+"string7672",
+"string7673",
+"string7674",
+"string7675",
+"string7676",
+"string7677",
+"string7678",
+"string7679",
+"string7680",
+"string7681",
+"string7682",
+"string7683",
+"string7684",
+"string7685",
+"string7686",
+"string7687",
+"string7688",
+"string7689",
+"string7690",
+"string7691",
+"string7692",
+"string7693",
+"string7694",
+"string7695",
+"string7696",
+"string7697",
+"string7698",
+"string7699",
+"string7700",
+"string7701",
+"string7702",
+"string7703",
+"string7704",
+"string7705",
+"string7706",
+"string7707",
+"string7708",
+"string7709",
+"string7710",
+"string7711",
+"string7712",
+"string7713",
+"string7714",
+"string7715",
+"string7716",
+"string7717",
+"string7718",
+"string7719",
+"string7720",
+"string7721",
+"string7722",
+"string7723",
+"string7724",
+"string7725",
+"string7726",
+"string7727",
+"string7728",
+"string7729",
+"string7730",
+"string7731",
+"string7732",
+"string7733",
+"string7734",
+"string7735",
+"string7736",
+"string7737",
+"string7738",
+"string7739",
+"string7740",
+"string7741",
+"string7742",
+"string7743",
+"string7744",
+"string7745",
+"string7746",
+"string7747",
+"string7748",
+"string7749",
+"string7750",
+"string7751",
+"string7752",
+"string7753",
+"string7754",
+"string7755",
+"string7756",
+"string7757",
+"string7758",
+"string7759",
+"string7760",
+"string7761",
+"string7762",
+"string7763",
+"string7764",
+"string7765",
+"string7766",
+"string7767",
+"string7768",
+"string7769",
+"string7770",
+"string7771",
+"string7772",
+"string7773",
+"string7774",
+"string7775",
+"string7776",
+"string7777",
+"string7778",
+"string7779",
+"string7780",
+"string7781",
+"string7782",
+"string7783",
+"string7784",
+"string7785",
+"string7786",
+"string7787",
+"string7788",
+"string7789",
+"string7790",
+"string7791",
+"string7792",
+"string7793",
+"string7794",
+"string7795",
+"string7796",
+"string7797",
+"string7798",
+"string7799",
+"string7800",
+"string7801",
+"string7802",
+"string7803",
+"string7804",
+"string7805",
+"string7806",
+"string7807",
+"string7808",
+"string7809",
+"string7810",
+"string7811",
+"string7812",
+"string7813",
+"string7814",
+"string7815",
+"string7816",
+"string7817",
+"string7818",
+"string7819",
+"string7820",
+"string7821",
+"string7822",
+"string7823",
+"string7824",
+"string7825",
+"string7826",
+"string7827",
+"string7828",
+"string7829",
+"string7830",
+"string7831",
+"string7832",
+"string7833",
+"string7834",
+"string7835",
+"string7836",
+"string7837",
+"string7838",
+"string7839",
+"string7840",
+"string7841",
+"string7842",
+"string7843",
+"string7844",
+"string7845",
+"string7846",
+"string7847",
+"string7848",
+"string7849",
+"string7850",
+"string7851",
+"string7852",
+"string7853",
+"string7854",
+"string7855",
+"string7856",
+"string7857",
+"string7858",
+"string7859",
+"string7860",
+"string7861",
+"string7862",
+"string7863",
+"string7864",
+"string7865",
+"string7866",
+"string7867",
+"string7868",
+"string7869",
+"string7870",
+"string7871",
+"string7872",
+"string7873",
+"string7874",
+"string7875",
+"string7876",
+"string7877",
+"string7878",
+"string7879",
+"string7880",
+"string7881",
+"string7882",
+"string7883",
+"string7884",
+"string7885",
+"string7886",
+"string7887",
+"string7888",
+"string7889",
+"string7890",
+"string7891",
+"string7892",
+"string7893",
+"string7894",
+"string7895",
+"string7896",
+"string7897",
+"string7898",
+"string7899",
+"string7900",
+"string7901",
+"string7902",
+"string7903",
+"string7904",
+"string7905",
+"string7906",
+"string7907",
+"string7908",
+"string7909",
+"string7910",
+"string7911",
+"string7912",
+"string7913",
+"string7914",
+"string7915",
+"string7916",
+"string7917",
+"string7918",
+"string7919",
+"string7920",
+"string7921",
+"string7922",
+"string7923",
+"string7924",
+"string7925",
+"string7926",
+"string7927",
+"string7928",
+"string7929",
+"string7930",
+"string7931",
+"string7932",
+"string7933",
+"string7934",
+"string7935",
+"string7936",
+"string7937",
+"string7938",
+"string7939",
+"string7940",
+"string7941",
+"string7942",
+"string7943",
+"string7944",
+"string7945",
+"string7946",
+"string7947",
+"string7948",
+"string7949",
+"string7950",
+"string7951",
+"string7952",
+"string7953",
+"string7954",
+"string7955",
+"string7956",
+"string7957",
+"string7958",
+"string7959",
+"string7960",
+"string7961",
+"string7962",
+"string7963",
+"string7964",
+"string7965",
+"string7966",
+"string7967",
+"string7968",
+"string7969",
+"string7970",
+"string7971",
+"string7972",
+"string7973",
+"string7974",
+"string7975",
+"string7976",
+"string7977",
+"string7978",
+"string7979",
+"string7980",
+"string7981",
+"string7982",
+"string7983",
+"string7984",
+"string7985",
+"string7986",
+"string7987",
+"string7988",
+"string7989",
+"string7990",
+"string7991",
+"string7992",
+"string7993",
+"string7994",
+"string7995",
+"string7996",
+"string7997",
+"string7998",
+"string7999",
+"string8000",
+"string8001",
+"string8002",
+"string8003",
+"string8004",
+"string8005",
+"string8006",
+"string8007",
+"string8008",
+"string8009",
+"string8010",
+"string8011",
+"string8012",
+"string8013",
+"string8014",
+"string8015",
+"string8016",
+"string8017",
+"string8018",
+"string8019",
+"string8020",
+"string8021",
+"string8022",
+"string8023",
+"string8024",
+"string8025",
+"string8026",
+"string8027",
+"string8028",
+"string8029",
+"string8030",
+"string8031",
+"string8032",
+"string8033",
+"string8034",
+"string8035",
+"string8036",
+"string8037",
+"string8038",
+"string8039",
+"string8040",
+"string8041",
+"string8042",
+"string8043",
+"string8044",
+"string8045",
+"string8046",
+"string8047",
+"string8048",
+"string8049",
+"string8050",
+"string8051",
+"string8052",
+"string8053",
+"string8054",
+"string8055",
+"string8056",
+"string8057",
+"string8058",
+"string8059",
+"string8060",
+"string8061",
+"string8062",
+"string8063",
+"string8064",
+"string8065",
+"string8066",
+"string8067",
+"string8068",
+"string8069",
+"string8070",
+"string8071",
+"string8072",
+"string8073",
+"string8074",
+"string8075",
+"string8076",
+"string8077",
+"string8078",
+"string8079",
+"string8080",
+"string8081",
+"string8082",
+"string8083",
+"string8084",
+"string8085",
+"string8086",
+"string8087",
+"string8088",
+"string8089",
+"string8090",
+"string8091",
+"string8092",
+"string8093",
+"string8094",
+"string8095",
+"string8096",
+"string8097",
+"string8098",
+"string8099",
+"string8100",
+"string8101",
+"string8102",
+"string8103",
+"string8104",
+"string8105",
+"string8106",
+"string8107",
+"string8108",
+"string8109",
+"string8110",
+"string8111",
+"string8112",
+"string8113",
+"string8114",
+"string8115",
+"string8116",
+"string8117",
+"string8118",
+"string8119",
+"string8120",
+"string8121",
+"string8122",
+"string8123",
+"string8124",
+"string8125",
+"string8126",
+"string8127",
+"string8128",
+"string8129",
+"string8130",
+"string8131",
+"string8132",
+"string8133",
+"string8134",
+"string8135",
+"string8136",
+"string8137",
+"string8138",
+"string8139",
+"string8140",
+"string8141",
+"string8142",
+"string8143",
+"string8144",
+"string8145",
+"string8146",
+"string8147",
+"string8148",
+"string8149",
+"string8150",
+"string8151",
+"string8152",
+"string8153",
+"string8154",
+"string8155",
+"string8156",
+"string8157",
+"string8158",
+"string8159",
+"string8160",
+"string8161",
+"string8162",
+"string8163",
+"string8164",
+"string8165",
+"string8166",
+"string8167",
+"string8168",
+"string8169",
+"string8170",
+"string8171",
+"string8172",
+"string8173",
+"string8174",
+"string8175",
+"string8176",
+"string8177",
+"string8178",
+"string8179",
+"string8180",
+"string8181",
+"string8182",
+"string8183",
+"string8184",
+"string8185",
+"string8186",
+"string8187",
+"string8188",
+"string8189",
+"string8190",
+"string8191",
+"string8192",
+"string8193",
+"string8194",
+"string8195",
+"string8196",
+"string8197",
+"string8198",
+"string8199",
+"string8200",
+"string8201",
+"string8202",
+"string8203",
+"string8204",
+"string8205",
+"string8206",
+"string8207",
+"string8208",
+"string8209",
+"string8210",
+"string8211",
+"string8212",
+"string8213",
+"string8214",
+"string8215",
+"string8216",
+"string8217",
+"string8218",
+"string8219",
+"string8220",
+"string8221",
+"string8222",
+"string8223",
+"string8224",
+"string8225",
+"string8226",
+"string8227",
+"string8228",
+"string8229",
+"string8230",
+"string8231",
+"string8232",
+"string8233",
+"string8234",
+"string8235",
+"string8236",
+"string8237",
+"string8238",
+"string8239",
+"string8240",
+"string8241",
+"string8242",
+"string8243",
+"string8244",
+"string8245",
+"string8246",
+"string8247",
+"string8248",
+"string8249",
+"string8250",
+"string8251",
+"string8252",
+"string8253",
+"string8254",
+"string8255",
+"string8256",
+"string8257",
+"string8258",
+"string8259",
+"string8260",
+"string8261",
+"string8262",
+"string8263",
+"string8264",
+"string8265",
+"string8266",
+"string8267",
+"string8268",
+"string8269",
+"string8270",
+"string8271",
+"string8272",
+"string8273",
+"string8274",
+"string8275",
+"string8276",
+"string8277",
+"string8278",
+"string8279",
+"string8280",
+"string8281",
+"string8282",
+"string8283",
+"string8284",
+"string8285",
+"string8286",
+"string8287",
+"string8288",
+"string8289",
+"string8290",
+"string8291",
+"string8292",
+"string8293",
+"string8294",
+"string8295",
+"string8296",
+"string8297",
+"string8298",
+"string8299",
+"string8300",
+"string8301",
+"string8302",
+"string8303",
+"string8304",
+"string8305",
+"string8306",
+"string8307",
+"string8308",
+"string8309",
+"string8310",
+"string8311",
+"string8312",
+"string8313",
+"string8314",
+"string8315",
+"string8316",
+"string8317",
+"string8318",
+"string8319",
+"string8320",
+"string8321",
+"string8322",
+"string8323",
+"string8324",
+"string8325",
+"string8326",
+"string8327",
+"string8328",
+"string8329",
+"string8330",
+"string8331",
+"string8332",
+"string8333",
+"string8334",
+"string8335",
+"string8336",
+"string8337",
+"string8338",
+"string8339",
+"string8340",
+"string8341",
+"string8342",
+"string8343",
+"string8344",
+"string8345",
+"string8346",
+"string8347",
+"string8348",
+"string8349",
+"string8350",
+"string8351",
+"string8352",
+"string8353",
+"string8354",
+"string8355",
+"string8356",
+"string8357",
+"string8358",
+"string8359",
+"string8360",
+"string8361",
+"string8362",
+"string8363",
+"string8364",
+"string8365",
+"string8366",
+"string8367",
+"string8368",
+"string8369",
+"string8370",
+"string8371",
+"string8372",
+"string8373",
+"string8374",
+"string8375",
+"string8376",
+"string8377",
+"string8378",
+"string8379",
+"string8380",
+"string8381",
+"string8382",
+"string8383",
+"string8384",
+"string8385",
+"string8386",
+"string8387",
+"string8388",
+"string8389",
+"string8390",
+"string8391",
+"string8392",
+"string8393",
+"string8394",
+"string8395",
+"string8396",
+"string8397",
+"string8398",
+"string8399",
+"string8400",
+"string8401",
+"string8402",
+"string8403",
+"string8404",
+"string8405",
+"string8406",
+"string8407",
+"string8408",
+"string8409",
+"string8410",
+"string8411",
+"string8412",
+"string8413",
+"string8414",
+"string8415",
+"string8416",
+"string8417",
+"string8418",
+"string8419",
+"string8420",
+"string8421",
+"string8422",
+"string8423",
+"string8424",
+"string8425",
+"string8426",
+"string8427",
+"string8428",
+"string8429",
+"string8430",
+"string8431",
+"string8432",
+"string8433",
+"string8434",
+"string8435",
+"string8436",
+"string8437",
+"string8438",
+"string8439",
+"string8440",
+"string8441",
+"string8442",
+"string8443",
+"string8444",
+"string8445",
+"string8446",
+"string8447",
+"string8448",
+"string8449",
+"string8450",
+"string8451",
+"string8452",
+"string8453",
+"string8454",
+"string8455",
+"string8456",
+"string8457",
+"string8458",
+"string8459",
+"string8460",
+"string8461",
+"string8462",
+"string8463",
+"string8464",
+"string8465",
+"string8466",
+"string8467",
+"string8468",
+"string8469",
+"string8470",
+"string8471",
+"string8472",
+"string8473",
+"string8474",
+"string8475",
+"string8476",
+"string8477",
+"string8478",
+"string8479",
+"string8480",
+"string8481",
+"string8482",
+"string8483",
+"string8484",
+"string8485",
+"string8486",
+"string8487",
+"string8488",
+"string8489",
+"string8490",
+"string8491",
+"string8492",
+"string8493",
+"string8494",
+"string8495",
+"string8496",
+"string8497",
+"string8498",
+"string8499",
+"string8500",
+"string8501",
+"string8502",
+"string8503",
+"string8504",
+"string8505",
+"string8506",
+"string8507",
+"string8508",
+"string8509",
+"string8510",
+"string8511",
+"string8512",
+"string8513",
+"string8514",
+"string8515",
+"string8516",
+"string8517",
+"string8518",
+"string8519",
+"string8520",
+"string8521",
+"string8522",
+"string8523",
+"string8524",
+"string8525",
+"string8526",
+"string8527",
+"string8528",
+"string8529",
+"string8530",
+"string8531",
+"string8532",
+"string8533",
+"string8534",
+"string8535",
+"string8536",
+"string8537",
+"string8538",
+"string8539",
+"string8540",
+"string8541",
+"string8542",
+"string8543",
+"string8544",
+"string8545",
+"string8546",
+"string8547",
+"string8548",
+"string8549",
+"string8550",
+"string8551",
+"string8552",
+"string8553",
+"string8554",
+"string8555",
+"string8556",
+"string8557",
+"string8558",
+"string8559",
+"string8560",
+"string8561",
+"string8562",
+"string8563",
+"string8564",
+"string8565",
+"string8566",
+"string8567",
+"string8568",
+"string8569",
+"string8570",
+"string8571",
+"string8572",
+"string8573",
+"string8574",
+"string8575",
+"string8576",
+"string8577",
+"string8578",
+"string8579",
+"string8580",
+"string8581",
+"string8582",
+"string8583",
+"string8584",
+"string8585",
+"string8586",
+"string8587",
+"string8588",
+"string8589",
+"string8590",
+"string8591",
+"string8592",
+"string8593",
+"string8594",
+"string8595",
+"string8596",
+"string8597",
+"string8598",
+"string8599",
+"string8600",
+"string8601",
+"string8602",
+"string8603",
+"string8604",
+"string8605",
+"string8606",
+"string8607",
+"string8608",
+"string8609",
+"string8610",
+"string8611",
+"string8612",
+"string8613",
+"string8614",
+"string8615",
+"string8616",
+"string8617",
+"string8618",
+"string8619",
+"string8620",
+"string8621",
+"string8622",
+"string8623",
+"string8624",
+"string8625",
+"string8626",
+"string8627",
+"string8628",
+"string8629",
+"string8630",
+"string8631",
+"string8632",
+"string8633",
+"string8634",
+"string8635",
+"string8636",
+"string8637",
+"string8638",
+"string8639",
+"string8640",
+"string8641",
+"string8642",
+"string8643",
+"string8644",
+"string8645",
+"string8646",
+"string8647",
+"string8648",
+"string8649",
+"string8650",
+"string8651",
+"string8652",
+"string8653",
+"string8654",
+"string8655",
+"string8656",
+"string8657",
+"string8658",
+"string8659",
+"string8660",
+"string8661",
+"string8662",
+"string8663",
+"string8664",
+"string8665",
+"string8666",
+"string8667",
+"string8668",
+"string8669",
+"string8670",
+"string8671",
+"string8672",
+"string8673",
+"string8674",
+"string8675",
+"string8676",
+"string8677",
+"string8678",
+"string8679",
+"string8680",
+"string8681",
+"string8682",
+"string8683",
+"string8684",
+"string8685",
+"string8686",
+"string8687",
+"string8688",
+"string8689",
+"string8690",
+"string8691",
+"string8692",
+"string8693",
+"string8694",
+"string8695",
+"string8696",
+"string8697",
+"string8698",
+"string8699",
+"string8700",
+"string8701",
+"string8702",
+"string8703",
+"string8704",
+"string8705",
+"string8706",
+"string8707",
+"string8708",
+"string8709",
+"string8710",
+"string8711",
+"string8712",
+"string8713",
+"string8714",
+"string8715",
+"string8716",
+"string8717",
+"string8718",
+"string8719",
+"string8720",
+"string8721",
+"string8722",
+"string8723",
+"string8724",
+"string8725",
+"string8726",
+"string8727",
+"string8728",
+"string8729",
+"string8730",
+"string8731",
+"string8732",
+"string8733",
+"string8734",
+"string8735",
+"string8736",
+"string8737",
+"string8738",
+"string8739",
+"string8740",
+"string8741",
+"string8742",
+"string8743",
+"string8744",
+"string8745",
+"string8746",
+"string8747",
+"string8748",
+"string8749",
+"string8750",
+"string8751",
+"string8752",
+"string8753",
+"string8754",
+"string8755",
+"string8756",
+"string8757",
+"string8758",
+"string8759",
+"string8760",
+"string8761",
+"string8762",
+"string8763",
+"string8764",
+"string8765",
+"string8766",
+"string8767",
+"string8768",
+"string8769",
+"string8770",
+"string8771",
+"string8772",
+"string8773",
+"string8774",
+"string8775",
+"string8776",
+"string8777",
+"string8778",
+"string8779",
+"string8780",
+"string8781",
+"string8782",
+"string8783",
+"string8784",
+"string8785",
+"string8786",
+"string8787",
+"string8788",
+"string8789",
+"string8790",
+"string8791",
+"string8792",
+"string8793",
+"string8794",
+"string8795",
+"string8796",
+"string8797",
+"string8798",
+"string8799",
+"string8800",
+"string8801",
+"string8802",
+"string8803",
+"string8804",
+"string8805",
+"string8806",
+"string8807",
+"string8808",
+"string8809",
+"string8810",
+"string8811",
+"string8812",
+"string8813",
+"string8814",
+"string8815",
+"string8816",
+"string8817",
+"string8818",
+"string8819",
+"string8820",
+"string8821",
+"string8822",
+"string8823",
+"string8824",
+"string8825",
+"string8826",
+"string8827",
+"string8828",
+"string8829",
+"string8830",
+"string8831",
+"string8832",
+"string8833",
+"string8834",
+"string8835",
+"string8836",
+"string8837",
+"string8838",
+"string8839",
+"string8840",
+"string8841",
+"string8842",
+"string8843",
+"string8844",
+"string8845",
+"string8846",
+"string8847",
+"string8848",
+"string8849",
+"string8850",
+"string8851",
+"string8852",
+"string8853",
+"string8854",
+"string8855",
+"string8856",
+"string8857",
+"string8858",
+"string8859",
+"string8860",
+"string8861",
+"string8862",
+"string8863",
+"string8864",
+"string8865",
+"string8866",
+"string8867",
+"string8868",
+"string8869",
+"string8870",
+"string8871",
+"string8872",
+"string8873",
+"string8874",
+"string8875",
+"string8876",
+"string8877",
+"string8878",
+"string8879",
+"string8880",
+"string8881",
+"string8882",
+"string8883",
+"string8884",
+"string8885",
+"string8886",
+"string8887",
+"string8888",
+"string8889",
+"string8890",
+"string8891",
+"string8892",
+"string8893",
+"string8894",
+"string8895",
+"string8896",
+"string8897",
+"string8898",
+"string8899",
+"string8900",
+"string8901",
+"string8902",
+"string8903",
+"string8904",
+"string8905",
+"string8906",
+"string8907",
+"string8908",
+"string8909",
+"string8910",
+"string8911",
+"string8912",
+"string8913",
+"string8914",
+"string8915",
+"string8916",
+"string8917",
+"string8918",
+"string8919",
+"string8920",
+"string8921",
+"string8922",
+"string8923",
+"string8924",
+"string8925",
+"string8926",
+"string8927",
+"string8928",
+"string8929",
+"string8930",
+"string8931",
+"string8932",
+"string8933",
+"string8934",
+"string8935",
+"string8936",
+"string8937",
+"string8938",
+"string8939",
+"string8940",
+"string8941",
+"string8942",
+"string8943",
+"string8944",
+"string8945",
+"string8946",
+"string8947",
+"string8948",
+"string8949",
+"string8950",
+"string8951",
+"string8952",
+"string8953",
+"string8954",
+"string8955",
+"string8956",
+"string8957",
+"string8958",
+"string8959",
+"string8960",
+"string8961",
+"string8962",
+"string8963",
+"string8964",
+"string8965",
+"string8966",
+"string8967",
+"string8968",
+"string8969",
+"string8970",
+"string8971",
+"string8972",
+"string8973",
+"string8974",
+"string8975",
+"string8976",
+"string8977",
+"string8978",
+"string8979",
+"string8980",
+"string8981",
+"string8982",
+"string8983",
+"string8984",
+"string8985",
+"string8986",
+"string8987",
+"string8988",
+"string8989",
+"string8990",
+"string8991",
+"string8992",
+"string8993",
+"string8994",
+"string8995",
+"string8996",
+"string8997",
+"string8998",
+"string8999",
+"string9000",
+"string9001",
+"string9002",
+"string9003",
+"string9004",
+"string9005",
+"string9006",
+"string9007",
+"string9008",
+"string9009",
+"string9010",
+"string9011",
+"string9012",
+"string9013",
+"string9014",
+"string9015",
+"string9016",
+"string9017",
+"string9018",
+"string9019",
+"string9020",
+"string9021",
+"string9022",
+"string9023",
+"string9024",
+"string9025",
+"string9026",
+"string9027",
+"string9028",
+"string9029",
+"string9030",
+"string9031",
+"string9032",
+"string9033",
+"string9034",
+"string9035",
+"string9036",
+"string9037",
+"string9038",
+"string9039",
+"string9040",
+"string9041",
+"string9042",
+"string9043",
+"string9044",
+"string9045",
+"string9046",
+"string9047",
+"string9048",
+"string9049",
+"string9050",
+"string9051",
+"string9052",
+"string9053",
+"string9054",
+"string9055",
+"string9056",
+"string9057",
+"string9058",
+"string9059",
+"string9060",
+"string9061",
+"string9062",
+"string9063",
+"string9064",
+"string9065",
+"string9066",
+"string9067",
+"string9068",
+"string9069",
+"string9070",
+"string9071",
+"string9072",
+"string9073",
+"string9074",
+"string9075",
+"string9076",
+"string9077",
+"string9078",
+"string9079",
+"string9080",
+"string9081",
+"string9082",
+"string9083",
+"string9084",
+"string9085",
+"string9086",
+"string9087",
+"string9088",
+"string9089",
+"string9090",
+"string9091",
+"string9092",
+"string9093",
+"string9094",
+"string9095",
+"string9096",
+"string9097",
+"string9098",
+"string9099",
+"string9100",
+"string9101",
+"string9102",
+"string9103",
+"string9104",
+"string9105",
+"string9106",
+"string9107",
+"string9108",
+"string9109",
+"string9110",
+"string9111",
+"string9112",
+"string9113",
+"string9114",
+"string9115",
+"string9116",
+"string9117",
+"string9118",
+"string9119",
+"string9120",
+"string9121",
+"string9122",
+"string9123",
+"string9124",
+"string9125",
+"string9126",
+"string9127",
+"string9128",
+"string9129",
+"string9130",
+"string9131",
+"string9132",
+"string9133",
+"string9134",
+"string9135",
+"string9136",
+"string9137",
+"string9138",
+"string9139",
+"string9140",
+"string9141",
+"string9142",
+"string9143",
+"string9144",
+"string9145",
+"string9146",
+"string9147",
+"string9148",
+"string9149",
+"string9150",
+"string9151",
+"string9152",
+"string9153",
+"string9154",
+"string9155",
+"string9156",
+"string9157",
+"string9158",
+"string9159",
+"string9160",
+"string9161",
+"string9162",
+"string9163",
+"string9164",
+"string9165",
+"string9166",
+"string9167",
+"string9168",
+"string9169",
+"string9170",
+"string9171",
+"string9172",
+"string9173",
+"string9174",
+"string9175",
+"string9176",
+"string9177",
+"string9178",
+"string9179",
+"string9180",
+"string9181",
+"string9182",
+"string9183",
+"string9184",
+"string9185",
+"string9186",
+"string9187",
+"string9188",
+"string9189",
+"string9190",
+"string9191",
+"string9192",
+"string9193",
+"string9194",
+"string9195",
+"string9196",
+"string9197",
+"string9198",
+"string9199",
+"string9200",
+"string9201",
+"string9202",
+"string9203",
+"string9204",
+"string9205",
+"string9206",
+"string9207",
+"string9208",
+"string9209",
+"string9210",
+"string9211",
+"string9212",
+"string9213",
+"string9214",
+"string9215",
+"string9216",
+"string9217",
+"string9218",
+"string9219",
+"string9220",
+"string9221",
+"string9222",
+"string9223",
+"string9224",
+"string9225",
+"string9226",
+"string9227",
+"string9228",
+"string9229",
+"string9230",
+"string9231",
+"string9232",
+"string9233",
+"string9234",
+"string9235",
+"string9236",
+"string9237",
+"string9238",
+"string9239",
+"string9240",
+"string9241",
+"string9242",
+"string9243",
+"string9244",
+"string9245",
+"string9246",
+"string9247",
+"string9248",
+"string9249",
+"string9250",
+"string9251",
+"string9252",
+"string9253",
+"string9254",
+"string9255",
+"string9256",
+"string9257",
+"string9258",
+"string9259",
+"string9260",
+"string9261",
+"string9262",
+"string9263",
+"string9264",
+"string9265",
+"string9266",
+"string9267",
+"string9268",
+"string9269",
+"string9270",
+"string9271",
+"string9272",
+"string9273",
+"string9274",
+"string9275",
+"string9276",
+"string9277",
+"string9278",
+"string9279",
+"string9280",
+"string9281",
+"string9282",
+"string9283",
+"string9284",
+"string9285",
+"string9286",
+"string9287",
+"string9288",
+"string9289",
+"string9290",
+"string9291",
+"string9292",
+"string9293",
+"string9294",
+"string9295",
+"string9296",
+"string9297",
+"string9298",
+"string9299",
+"string9300",
+"string9301",
+"string9302",
+"string9303",
+"string9304",
+"string9305",
+"string9306",
+"string9307",
+"string9308",
+"string9309",
+"string9310",
+"string9311",
+"string9312",
+"string9313",
+"string9314",
+"string9315",
+"string9316",
+"string9317",
+"string9318",
+"string9319",
+"string9320",
+"string9321",
+"string9322",
+"string9323",
+"string9324",
+"string9325",
+"string9326",
+"string9327",
+"string9328",
+"string9329",
+"string9330",
+"string9331",
+"string9332",
+"string9333",
+"string9334",
+"string9335",
+"string9336",
+"string9337",
+"string9338",
+"string9339",
+"string9340",
+"string9341",
+"string9342",
+"string9343",
+"string9344",
+"string9345",
+"string9346",
+"string9347",
+"string9348",
+"string9349",
+"string9350",
+"string9351",
+"string9352",
+"string9353",
+"string9354",
+"string9355",
+"string9356",
+"string9357",
+"string9358",
+"string9359",
+"string9360",
+"string9361",
+"string9362",
+"string9363",
+"string9364",
+"string9365",
+"string9366",
+"string9367",
+"string9368",
+"string9369",
+"string9370",
+"string9371",
+"string9372",
+"string9373",
+"string9374",
+"string9375",
+"string9376",
+"string9377",
+"string9378",
+"string9379",
+"string9380",
+"string9381",
+"string9382",
+"string9383",
+"string9384",
+"string9385",
+"string9386",
+"string9387",
+"string9388",
+"string9389",
+"string9390",
+"string9391",
+"string9392",
+"string9393",
+"string9394",
+"string9395",
+"string9396",
+"string9397",
+"string9398",
+"string9399",
+"string9400",
+"string9401",
+"string9402",
+"string9403",
+"string9404",
+"string9405",
+"string9406",
+"string9407",
+"string9408",
+"string9409",
+"string9410",
+"string9411",
+"string9412",
+"string9413",
+"string9414",
+"string9415",
+"string9416",
+"string9417",
+"string9418",
+"string9419",
+"string9420",
+"string9421",
+"string9422",
+"string9423",
+"string9424",
+"string9425",
+"string9426",
+"string9427",
+"string9428",
+"string9429",
+"string9430",
+"string9431",
+"string9432",
+"string9433",
+"string9434",
+"string9435",
+"string9436",
+"string9437",
+"string9438",
+"string9439",
+"string9440",
+"string9441",
+"string9442",
+"string9443",
+"string9444",
+"string9445",
+"string9446",
+"string9447",
+"string9448",
+"string9449",
+"string9450",
+"string9451",
+"string9452",
+"string9453",
+"string9454",
+"string9455",
+"string9456",
+"string9457",
+"string9458",
+"string9459",
+"string9460",
+"string9461",
+"string9462",
+"string9463",
+"string9464",
+"string9465",
+"string9466",
+"string9467",
+"string9468",
+"string9469",
+"string9470",
+"string9471",
+"string9472",
+"string9473",
+"string9474",
+"string9475",
+"string9476",
+"string9477",
+"string9478",
+"string9479",
+"string9480",
+"string9481",
+"string9482",
+"string9483",
+"string9484",
+"string9485",
+"string9486",
+"string9487",
+"string9488",
+"string9489",
+"string9490",
+"string9491",
+"string9492",
+"string9493",
+"string9494",
+"string9495",
+"string9496",
+"string9497",
+"string9498",
+"string9499",
+"string9500",
+"string9501",
+"string9502",
+"string9503",
+"string9504",
+"string9505",
+"string9506",
+"string9507",
+"string9508",
+"string9509",
+"string9510",
+"string9511",
+"string9512",
+"string9513",
+"string9514",
+"string9515",
+"string9516",
+"string9517",
+"string9518",
+"string9519",
+"string9520",
+"string9521",
+"string9522",
+"string9523",
+"string9524",
+"string9525",
+"string9526",
+"string9527",
+"string9528",
+"string9529",
+"string9530",
+"string9531",
+"string9532",
+"string9533",
+"string9534",
+"string9535",
+"string9536",
+"string9537",
+"string9538",
+"string9539",
+"string9540",
+"string9541",
+"string9542",
+"string9543",
+"string9544",
+"string9545",
+"string9546",
+"string9547",
+"string9548",
+"string9549",
+"string9550",
+"string9551",
+"string9552",
+"string9553",
+"string9554",
+"string9555",
+"string9556",
+"string9557",
+"string9558",
+"string9559",
+"string9560",
+"string9561",
+"string9562",
+"string9563",
+"string9564",
+"string9565",
+"string9566",
+"string9567",
+"string9568",
+"string9569",
+"string9570",
+"string9571",
+"string9572",
+"string9573",
+"string9574",
+"string9575",
+"string9576",
+"string9577",
+"string9578",
+"string9579",
+"string9580",
+"string9581",
+"string9582",
+"string9583",
+"string9584",
+"string9585",
+"string9586",
+"string9587",
+"string9588",
+"string9589",
+"string9590",
+"string9591",
+"string9592",
+"string9593",
+"string9594",
+"string9595",
+"string9596",
+"string9597",
+"string9598",
+"string9599",
+"string9600",
+"string9601",
+"string9602",
+"string9603",
+"string9604",
+"string9605",
+"string9606",
+"string9607",
+"string9608",
+"string9609",
+"string9610",
+"string9611",
+"string9612",
+"string9613",
+"string9614",
+"string9615",
+"string9616",
+"string9617",
+"string9618",
+"string9619",
+"string9620",
+"string9621",
+"string9622",
+"string9623",
+"string9624",
+"string9625",
+"string9626",
+"string9627",
+"string9628",
+"string9629",
+"string9630",
+"string9631",
+"string9632",
+"string9633",
+"string9634",
+"string9635",
+"string9636",
+"string9637",
+"string9638",
+"string9639",
+"string9640",
+"string9641",
+"string9642",
+"string9643",
+"string9644",
+"string9645",
+"string9646",
+"string9647",
+"string9648",
+"string9649",
+"string9650",
+"string9651",
+"string9652",
+"string9653",
+"string9654",
+"string9655",
+"string9656",
+"string9657",
+"string9658",
+"string9659",
+"string9660",
+"string9661",
+"string9662",
+"string9663",
+"string9664",
+"string9665",
+"string9666",
+"string9667",
+"string9668",
+"string9669",
+"string9670",
+"string9671",
+"string9672",
+"string9673",
+"string9674",
+"string9675",
+"string9676",
+"string9677",
+"string9678",
+"string9679",
+"string9680",
+"string9681",
+"string9682",
+"string9683",
+"string9684",
+"string9685",
+"string9686",
+"string9687",
+"string9688",
+"string9689",
+"string9690",
+"string9691",
+"string9692",
+"string9693",
+"string9694",
+"string9695",
+"string9696",
+"string9697",
+"string9698",
+"string9699",
+"string9700",
+"string9701",
+"string9702",
+"string9703",
+"string9704",
+"string9705",
+"string9706",
+"string9707",
+"string9708",
+"string9709",
+"string9710",
+"string9711",
+"string9712",
+"string9713",
+"string9714",
+"string9715",
+"string9716",
+"string9717",
+"string9718",
+"string9719",
+"string9720",
+"string9721",
+"string9722",
+"string9723",
+"string9724",
+"string9725",
+"string9726",
+"string9727",
+"string9728",
+"string9729",
+"string9730",
+"string9731",
+"string9732",
+"string9733",
+"string9734",
+"string9735",
+"string9736",
+"string9737",
+"string9738",
+"string9739",
+"string9740",
+"string9741",
+"string9742",
+"string9743",
+"string9744",
+"string9745",
+"string9746",
+"string9747",
+"string9748",
+"string9749",
+"string9750",
+"string9751",
+"string9752",
+"string9753",
+"string9754",
+"string9755",
+"string9756",
+"string9757",
+"string9758",
+"string9759",
+"string9760",
+"string9761",
+"string9762",
+"string9763",
+"string9764",
+"string9765",
+"string9766",
+"string9767",
+"string9768",
+"string9769",
+"string9770",
+"string9771",
+"string9772",
+"string9773",
+"string9774",
+"string9775",
+"string9776",
+"string9777",
+"string9778",
+"string9779",
+"string9780",
+"string9781",
+"string9782",
+"string9783",
+"string9784",
+"string9785",
+"string9786",
+"string9787",
+"string9788",
+"string9789",
+"string9790",
+"string9791",
+"string9792",
+"string9793",
+"string9794",
+"string9795",
+"string9796",
+"string9797",
+"string9798",
+"string9799",
+"string9800",
+"string9801",
+"string9802",
+"string9803",
+"string9804",
+"string9805",
+"string9806",
+"string9807",
+"string9808",
+"string9809",
+"string9810",
+"string9811",
+"string9812",
+"string9813",
+"string9814",
+"string9815",
+"string9816",
+"string9817",
+"string9818",
+"string9819",
+"string9820",
+"string9821",
+"string9822",
+"string9823",
+"string9824",
+"string9825",
+"string9826",
+"string9827",
+"string9828",
+"string9829",
+"string9830",
+"string9831",
+"string9832",
+"string9833",
+"string9834",
+"string9835",
+"string9836",
+"string9837",
+"string9838",
+"string9839",
+"string9840",
+"string9841",
+"string9842",
+"string9843",
+"string9844",
+"string9845",
+"string9846",
+"string9847",
+"string9848",
+"string9849",
+"string9850",
+"string9851",
+"string9852",
+"string9853",
+"string9854",
+"string9855",
+"string9856",
+"string9857",
+"string9858",
+"string9859",
+"string9860",
+"string9861",
+"string9862",
+"string9863",
+"string9864",
+"string9865",
+"string9866",
+"string9867",
+"string9868",
+"string9869",
+"string9870",
+"string9871",
+"string9872",
+"string9873",
+"string9874",
+"string9875",
+"string9876",
+"string9877",
+"string9878",
+"string9879",
+"string9880",
+"string9881",
+"string9882",
+"string9883",
+"string9884",
+"string9885",
+"string9886",
+"string9887",
+"string9888",
+"string9889",
+"string9890",
+"string9891",
+"string9892",
+"string9893",
+"string9894",
+"string9895",
+"string9896",
+"string9897",
+"string9898",
+"string9899",
+"string9900",
+"string9901",
+"string9902",
+"string9903",
+"string9904",
+"string9905",
+"string9906",
+"string9907",
+"string9908",
+"string9909",
+"string9910",
+"string9911",
+"string9912",
+"string9913",
+"string9914",
+"string9915",
+"string9916",
+"string9917",
+"string9918",
+"string9919",
+"string9920",
+"string9921",
+"string9922",
+"string9923",
+"string9924",
+"string9925",
+"string9926",
+"string9927",
+"string9928",
+"string9929",
+"string9930",
+"string9931",
+"string9932",
+"string9933",
+"string9934",
+"string9935",
+"string9936",
+"string9937",
+"string9938",
+"string9939",
+"string9940",
+"string9941",
+"string9942",
+"string9943",
+"string9944",
+"string9945",
+"string9946",
+"string9947",
+"string9948",
+"string9949",
+"string9950",
+"string9951",
+"string9952",
+"string9953",
+"string9954",
+"string9955",
+"string9956",
+"string9957",
+"string9958",
+"string9959",
+"string9960",
+"string9961",
+"string9962",
+"string9963",
+"string9964",
+"string9965",
+"string9966",
+"string9967",
+"string9968",
+"string9969",
+"string9970",
+"string9971",
+"string9972",
+"string9973",
+"string9974",
+"string9975",
+"string9976",
+"string9977",
+"string9978",
+"string9979",
+"string9980",
+"string9981",
+"string9982",
+"string9983",
+"string9984",
+"string9985",
+"string9986",
+"string9987",
+"string9988",
+"string9989",
+"string9990",
+"string9991",
+"string9992",
+"string9993",
+"string9994",
+"string9995",
+"string9996",
+"string9997",
+"string9998",
+"string9999"
+];
+
+print(largeInteger[0]);
+print(largeInteger[9999]);
+print(largeDouble[0]);
+print(largeDouble[9999]);
+print(largeObject[0]);
+print(largeObject[1]);
+print(largeObject[2]);
+print(largeObject[3]);
+print(largeObject[4]);
+print(largeObject[5]);
+print(largeObject[6]);
+print(largeObject[9999+6]);
+
+var array = [];
+for (var i = 0; i < 5; i++) {
+    array[i] = [10, 20, 30];
+}
+
+array[3][1] = 9999;
+print(array[3][1], array[1][1]);
+
diff --git a/nashorn/test/script/basic/NASHORN-534.js.EXPECTED b/nashorn/test/script/basic/NASHORN-534.js.EXPECTED
new file mode 100644
index 0000000..769407a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-534.js.EXPECTED
@@ -0,0 +1,13 @@
+0
+9999
+0.1
+9999.1
+true
+1
+1.234
+null
+undefined
+undefined
+string0
+string9999
+9999 20
\ No newline at end of file
diff --git a/nashorn/test/script/basic/NASHORN-535.js b/nashorn/test/script/basic/NASHORN-535.js
new file mode 100644
index 0000000..57abfc4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-535.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-535 : Property name of an AccessNode is assigned variable symbol.
+ *
+ * @test
+ * @run
+ */
+
+function Foo() {
+  this.a = "a";
+  this.b = "b";
+}
+
+(function() {
+var foo = new Foo();
+delete foo.b;
+print(foo.b);
+})();
+(function() {
+"use strict";
+var foo = new Foo();
+delete foo.b;
+print(foo.b);
+})();
diff --git a/nashorn/test/script/basic/NASHORN-535.js.EXPECTED b/nashorn/test/script/basic/NASHORN-535.js.EXPECTED
new file mode 100644
index 0000000..d4f80bf
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-535.js.EXPECTED
@@ -0,0 +1,2 @@
+undefined
+undefined
diff --git a/nashorn/test/script/basic/NASHORN-544.js b/nashorn/test/script/basic/NASHORN-544.js
new file mode 100644
index 0000000..87c6cae
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-544.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-544 : exception trace should contain thrown message
+ *
+ * @test
+ * @run
+ */
+
+function AssertionError(msg) {
+    this.message = msg;
+}
+
+AssertionError.prototype = Object.create(Error.prototype);
+AssertionError.prototype.name = "AssertionError";
+
+var e = new AssertionError("failed!");
+try {
+    throw e;
+} catch(e) {
+    // check that nashornException has the right message
+    if (e.nashornException.getMessage() != 'AssertionError: failed!') {
+        fail("AssertionError's message is not correct");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-55.js b/nashorn/test/script/basic/NASHORN-55.js
new file mode 100644
index 0000000..58576a1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-55.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-55 :  When converting Boolean JS object, converted primitive boolean value should always be true.
+ *
+ * @test
+ * @run
+ */
+
+if (! (new Boolean(false))) {
+    print("ERROR: new Boolean(false) should be true");
+}
+
+if (! (new Boolean())) {
+    print("ERROR: new Boolean() should be true");
+}
diff --git a/nashorn/test/script/basic/NASHORN-554.js b/nashorn/test/script/basic/NASHORN-554.js
new file mode 100644
index 0000000..4c7ae87
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-554.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-554 : String character index iteration is wrong
+ *
+ * @test
+ * @run
+ */
+
+var s = new String("hello");
+for (i in s) {
+   print(i + " -> " + s[i]);
+}
+
+for each (c in s) {
+   print(c);
+}
+
+
diff --git a/nashorn/test/script/basic/NASHORN-554.js.EXPECTED b/nashorn/test/script/basic/NASHORN-554.js.EXPECTED
new file mode 100644
index 0000000..9f72588
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-554.js.EXPECTED
@@ -0,0 +1,10 @@
+0 -> h
+1 -> e
+2 -> l
+3 -> l
+4 -> o
+h
+e
+l
+l
+o
diff --git a/nashorn/test/script/basic/NASHORN-556.js b/nashorn/test/script/basic/NASHORN-556.js
new file mode 100644
index 0000000..5cb164a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-556.js
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-556: Need more tests to exercise code in jdk.nashorn.internal.runtime.array package.
+ *
+ * @test
+ * @run
+ */
+
+function p() {
+  var s = "";
+  for each (var i in arguments) {
+    s += ((i !== undefined) ? i : "") + ",";
+  }
+  s = s.length != 0 ? s.substr(0, s.length - 1) : s;
+  print(s);
+}
+
+function assertEq(expected, actual) {
+  if (actual !== expected && !(isNaN(actual) && isNaN(expected))) {
+    throw "expected=" + expected + " actual=" + actual;
+  }
+}
+
+function f1() {
+  // (NoTypeArrayData)
+  var empty = {};
+  empty.length = 10;
+  Java.toJavaArray(empty);
+  delete empty[0];
+  Array.prototype.slice.call(empty, 0, 1);
+  Array.prototype.pop.call(empty);
+  Array.prototype.shift.call(empty);
+  empty = {};
+  empty[0] = eval("84") >>> 1; assertEq(42, empty[0]);
+  empty = {};
+  Array.prototype.unshift.call(empty, "x"); assertEq("x", empty[0]);
+  empty = {};
+  empty[0] = 8.4; assertEq(8.4, empty[0]);
+}
+
+function f2() {
+  // DeletedArrayFilter
+  var deleted = [,1,,2,,3,,4,,];
+  assertEq(2, Java.toJavaArray(deleted)[3]);
+  assertEq(undefined, deleted.pop());
+  assertEq(4, deleted.pop());
+  deleted.unshift(5);
+  p.apply(null, deleted);
+  assertEq(5, deleted.shift());
+  print(deleted.slice(0,3), deleted.slice(1,7));
+  assertEq(1, deleted[3] >>> 1);
+  deleted[3] = eval("84") >>> 1; assertEq(42, deleted[3]);
+  p.apply(null, deleted);
+}
+
+function f3() {
+  // DeletedRangeArrayFilter
+  var delrange = [1,2,3,,,,,,,,,,];
+  Java.toJavaArray(delrange);
+  delrange.unshift(4);
+  p.apply(null, delrange);
+  print(delrange.slice(1,3), delrange.slice(2,6));
+  assertEq(4, delrange.shift());
+}
+
+function f4() {
+  // NumberArrayData
+  var num = [1.1,2.2,3.3,4.4,5.5];
+  Java.toJavaArray(num);
+  assertEq(2, num[3] >>> 1);
+  assertEq(5, num[4] | 0);
+  assertEq(5.5, num.pop());
+  num.unshift(13.37);
+  print(num.slice(1,4));
+  assertEq(13.37, num.shift());
+  p.apply(null, num);
+  num.length = 20;
+  delete num[0];
+  num[0] = eval("14") >>> 1;
+}
+
+function f5() {
+  // ObjectArrayData
+  var obj = [2,"two",3.14,"pi",14,"fourteen"];
+  Java.toJavaArray(obj);
+  assertEq(-12.86, obj[2] - 16);
+  assertEq(7, obj[4] >>> 1);
+  obj.unshift("one");
+  obj[0] = 1.3;
+  obj[0] = eval("14") >>> 1;
+  assertEq(7, obj.shift());
+  p.apply(null, obj);
+}
+
+function f6() {
+  // SparseArrayData
+  var sparse = [9,8,7,6,5,4,3,2,1];
+  sparse[0x76543210] = 84;
+  assertEq(42, sparse[0x76543210] >>> 1);
+  assertEq(42, sparse[0x76543210] - 42);
+  assertEq(85, sparse[0x76543210] | 1);
+  sparse[0x76543210] = 7.2;
+  sparse[0x76543210] = eval("84") >>> 1;
+  sparse.unshift(10);
+  print(sparse.slice(0,12));
+  print(sparse.slice(0x76543209, 0x76543213));
+  assertEq(10, sparse.shift());
+  assertEq(42, sparse.pop());
+  sparse.length = 1024*1024;
+  sparse.push(sparse.length);
+  delete sparse[sparse.length-1];
+  //print(Java.toJavaArray(sparse).length);
+  (function(){}).apply(null, sparse);
+}
+
+function f7() {
+  // UndefinedArrayFilter
+  var undef = [1,2,3,4,5,undefined,7,8,9,19];
+  Java.toJavaArray(undef);
+  assertEq(4, undef[8] >>> 1);
+  var tmp = undef[9] >>> 1;
+  undef[8] = tmp;
+  undef.unshift(21);
+  print(undef.slice(0, 4), undef.slice(4, 5));
+  assertEq(21, undef.shift());
+  undef.push(20);
+  assertEq(20, undef.pop());
+  assertEq(19, undef.pop());
+  p.apply(null, undef);
+  undef.length = 20;
+}
+
+function f8() {
+  // LongArrayData
+  var j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+  Java.toJavaArray(j);
+  p.apply(null, j);
+  assertEq(43, j[3] >>> 1);
+  assertEq(36, j[4] - 11);
+  j.unshift(eval("14") >>> 1);
+  print(j.slice(0,4));
+  assertEq(7, j.shift());
+  assertEq(47, j.pop());
+  j.push("asdf");
+  j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+  j.length = 3;
+  j[0] = 13;
+  j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+  delete j[0];
+  j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+  j.length = 20;
+  j[0] = 13.37;
+}
+
+function f9() {
+  // FrozenArrayFilter
+  var a1 = [10,11,12,13,14,15];
+  Object.freeze(a1);
+  assertEq(true, Object.isFrozen(a1));
+  Object.getOwnPropertyDescriptor(a1, 0);
+  a1[1] = 1;
+  a1[2] = eval("14") >>> 1;
+  a1[3] = 3.14;
+  a1[4] = "asdf";
+  print(a1.slice(1,4));
+  a1.length = 20;
+}
+
+function f10() {
+  // SealedArrayFilter
+  var a1 = [10,11,12,13,14,15];
+  Object.seal(a1);
+  assertEq(true, Object.isSealed(a1));
+  Object.getOwnPropertyDescriptor(a1, 0);
+  a1[1] = 1;
+  a1[2] = eval("14") >>> 1;
+  a1[3] = 3.14;
+  a1[4] = "asdf";
+  print(a1.slice(1,4));
+  delete a1[0];
+  a1.length = 20;
+}
+
+f1();
+f2();
+f3();
+f4();
+f5();
+f6();
+f7();
+f8();
+f9();
+f10();
+
diff --git a/nashorn/test/script/basic/NASHORN-556.js.EXPECTED b/nashorn/test/script/basic/NASHORN-556.js.EXPECTED
new file mode 100644
index 0000000..765d69f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-556.js.EXPECTED
@@ -0,0 +1,16 @@
+5,,1,,2,,3,
+,1, 1,,2,,3,
+,1,,42,,3,
+4,1,2,3,,,,,,,,,
+1,2 2,3,,
+1.1,2.2,3.3
+1.1,2.2,3.3,4.4
+2,two,3.14,pi,14,fourteen
+10,9,8,7,6,5,4,3,2,1,,
+,,,,,,,,42
+21,1,2,3 4
+1,2,3,4,5,,7,8,9
+23,37,42,86,47
+7,23,37,42
+11,12,13
+1,7,3.14
diff --git a/nashorn/test/script/basic/NASHORN-56.js b/nashorn/test/script/basic/NASHORN-56.js
new file mode 100644
index 0000000..4722845
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-56.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-56: Assignment to global variables and type inference.
+ *
+ * @test
+ * @run
+ */
+
+var undefined = 1;
+print(undefined);
+
+eval("var x; function func() { x = 'world'; }");
+var x = 34;
+func();
+print(x);
+
+Object.defineProperty(this, 'y', {writable: false, value: 'hello'});
+var y = 34;
+print(y);
diff --git a/nashorn/test/script/basic/NASHORN-56.js.EXPECTED b/nashorn/test/script/basic/NASHORN-56.js.EXPECTED
new file mode 100644
index 0000000..244f73c
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-56.js.EXPECTED
@@ -0,0 +1,3 @@
+undefined
+world
+hello
diff --git a/nashorn/test/script/basic/NASHORN-562.js b/nashorn/test/script/basic/NASHORN-562.js
new file mode 100644
index 0000000..2754cba
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-562.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-562: AssertionError: Only return value on stack allowed at return point.
+ *
+ * @test
+ * @run
+ */
+
+function test() {
+  var arr = [1,2,3,7];
+  arr[arr.indexOf(2)]++;
+  return "" + arr;
+}
+if (test() !== "1,3,3,7") {
+  throw test();
+}
diff --git a/nashorn/test/script/basic/NASHORN-565.js b/nashorn/test/script/basic/NASHORN-565.js
new file mode 100644
index 0000000..ad789ce
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-565.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-565: ADD specialization is broken.
+ *
+ * @test
+ * @run
+ */
+
+var s = "42";
+var t = 3.14;
+var u = (s + t) - 0; print(u);
+var v = (s + 2) | 0; print(v);
+var w = (new Number(s) + Number.POSITIVE_INFINITY) | 0; print(w); // check correct int32 conversion
+var x = (new Number(s) + Number.POSITIVE_INFINITY) >>> 0; print(x); // check correct uint32 conversion
+var y = (parseInt(0xdeadf00d) + 0xdeadffff00d) >>> 1; print(y); // check correct long->uint32 conversion
+var z = (new Number(s) + Number.POSITIVE_INFINITY) - 0; print(z); // check correct double conversion
diff --git a/nashorn/test/script/basic/NASHORN-565.js.EXPECTED b/nashorn/test/script/basic/NASHORN-565.js.EXPECTED
new file mode 100644
index 0000000..8259e4f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-565.js.EXPECTED
@@ -0,0 +1,6 @@
+423.14
+422
+0
+0
+1599533069
+Infinity
diff --git a/nashorn/test/script/basic/NASHORN-575.js b/nashorn/test/script/basic/NASHORN-575.js
new file mode 100644
index 0000000..4eda079
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-575.js
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * NASHORN-575 : JSON parser throws AssertionError
+ *
+ * @test
+ * @run
+ */
+
+try {
+    JSON.parse('// foo');
+} catch (error) {
+    print(error);
+}
+try {
+    JSON.parse('/* foo */');
+} catch (error) {
+    print(error);
+}
+try {
+    JSON.parse('/foo/');
+} catch (error) {
+    print(error);
+}
+try {
+    JSON.parse('{"foo" : "bar" // foo }');
+} catch (error) {
+    print(error);
+}
+try {
+    JSON.parse('{"foo" : "bar" /* foo */ }');
+} catch (error) {
+    print(error);
+}
+try {
+    JSON.parse('{"foo" : /foo/}');
+} catch (error) {
+    print(error);
+}
diff --git a/nashorn/test/script/basic/NASHORN-575.js.EXPECTED b/nashorn/test/script/basic/NASHORN-575.js.EXPECTED
new file mode 100644
index 0000000..c0d7e3e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-575.js.EXPECTED
@@ -0,0 +1,18 @@
+SyntaxError: Invalid JSON: <json>:1:0 Expected json literal but found /
+// foo
+^
+SyntaxError: Invalid JSON: <json>:1:0 Expected json literal but found /
+/* foo */
+^
+SyntaxError: Invalid JSON: <json>:1:0 Expected json literal but found /
+/foo/
+^
+SyntaxError: Invalid JSON: <json>:1:15 Expected , or } but found /
+{"foo" : "bar" // foo }
+               ^
+SyntaxError: Invalid JSON: <json>:1:15 Expected , or } but found /
+{"foo" : "bar" /* foo */ }
+               ^
+SyntaxError: Invalid JSON: <json>:1:9 Expected json literal but found /
+{"foo" : /foo/}
+         ^
diff --git a/nashorn/test/script/basic/NASHORN-58.js b/nashorn/test/script/basic/NASHORN-58.js
new file mode 100644
index 0000000..b0aeaa4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-58.js
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-58
+ *
+ * @test
+ * @run
+ */
+
+function test1() {
+    var x = 1;
+    try { 
+	print('try'); 
+	x = 2; 
+    } catch(e) {
+	print('catch');
+    } finally { 
+	print('finally');
+	x = 3; 
+    }
+    print(x);
+}
+
+function test2() {
+    var x = 1;
+    try {
+	print('try');
+    } finally {
+	print('finally');
+	x = 2;
+    }
+    print(x);
+}
+
+function test3() {
+    try {
+	return 2;
+    } finally {
+	return 3;
+    }
+}
+
+function test4() {
+    try {
+	x = 1;
+	print(x);
+	try {
+	    x = 2;
+	    print(x);
+	} finally {
+	    x = 3;
+	    print(x)
+	    try {
+		x = 4;
+		print(x);
+	    } finally {
+		x = 5;
+		print(x);
+	    }
+	}
+	print(x)
+    } finally {
+	x = 6;
+	print(x);
+    }
+    print(x);
+}
+
+function test5() {
+    try {
+	x = 1;
+	print(x);
+	try {
+	    x = 2;
+	    print(x);
+	} finally {
+	    x = 3;
+	    print(x)
+	    try {
+		x = 4;
+		print(x);
+	    } finally {
+		x = 5;
+		return x;
+	    }
+	}
+	print(x)
+    } finally {
+	x = 6;
+	return x;
+    }
+}
+
+function test6() {
+    try {
+	throw new Error("testing");
+    } catch (ex) {
+	print(ex);
+	return;
+    } finally {
+	print("finally");
+    }
+}
+
+function test7() {
+    var e = new Error("no message");
+    var i = 3;
+    try {
+        throw e;
+    } catch (ex) {
+    } finally {
+        i++;
+    }
+    if (i != 4) {
+	print("FAIL");
+    }
+    print("SUCCESS");
+}
+
+
+test1();
+test2();
+print(test3());
+test4();
+print(test5())
+test6();
+test7();
+
diff --git a/nashorn/test/script/basic/NASHORN-58.js.EXPECTED b/nashorn/test/script/basic/NASHORN-58.js.EXPECTED
new file mode 100644
index 0000000..3a6a63a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-58.js.EXPECTED
@@ -0,0 +1,23 @@
+try
+finally
+3
+try
+finally
+2
+3
+1
+2
+3
+4
+5
+5
+6
+6
+1
+2
+3
+4
+6
+Error: testing
+finally
+SUCCESS
diff --git a/nashorn/test/script/basic/NASHORN-59.js b/nashorn/test/script/basic/NASHORN-59.js
new file mode 100644
index 0000000..1379fa6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-59.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-59 :  Attempting to call RegExp methods on non-regexp objects should result in TypeError exception.
+ *
+ * @test
+ * @run
+ */
+
+Object.prototype.exec = RegExp.prototype.exec;
+
+try {
+    ".".exec();
+    print("ERROR: should have thrown TypeError");
+} catch (e) {
+    if ((e instanceof TypeError) !== true) {
+        print("ERROR: TypeError expected");
+    }
+    print(e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-59.js.EXPECTED b/nashorn/test/script/basic/NASHORN-59.js.EXPECTED
new file mode 100644
index 0000000..d397a804
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-59.js.EXPECTED
@@ -0,0 +1 @@
+TypeError: . is not a RegExp
diff --git a/nashorn/test/script/basic/NASHORN-592.js b/nashorn/test/script/basic/NASHORN-592.js
new file mode 100644
index 0000000..cbc2984
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-592.js
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-592: test all combos of field types and getters and setters
+ *
+ * @test
+ * @run
+ */
+
+//fortype undefined
+var a;
+
+print(a & 0xff);
+print(a >>> 1);
+print(a * 2);
+print(a + "hej!");
+
+var b;
+b = 17;   //set undefined->int
+
+print(b & 0xff);
+print(b >>> 1);
+print(b * 2);
+print(b + "hej!");
+
+var c;
+c = 17.4711 //set undefined->double
+
+print(c & 0xff);
+print(c >>> 1);
+print(c * 2);
+print(c + "hej!");
+
+var d; // set undefined->double
+d = "Fame and fortune Salamander Yahoo!";
+
+print(d & 0xff);
+print(d >>> 1);
+print(d * 2);
+print(d + "hej!");
+
+// now we have exhausted all getters and undefined->everything setters.
+
+
+var e = 23; // int to everything setters,
+e = 24;     //int to int
+print(e);
+e = (22222 >>> 1); //int to long;
+print(e);
+e = 23.23;  //int to double
+print(e);
+e = 23;     //double to int - still double
+print(e);
+print(e & 0xff);
+e = "Have some pie!" //double to string
+print(e);
+e = 4711.17;
+print(e); //still an object not a double
+
+
+var f = (23222 >>> 1); // long to everything setters,
+f = 34344 >>> 1;     //long to long
+print(f);
+f = 23; //long to int - still long
+print(f);
+f = 23.23;  //long to double
+print(f);
+f = 23;     //double to int - still double
+print(f);
+print(f & 0xff);
+f = "Have some pie!" //double to string
+print(f);
+f = 4711.17;
+print(f); //still an object not a double
+
+var g = 4811.16;
+g = 23; //still double
+print(g);
+g = (222 >>> 1); //still double
+print(g);
+g = 4711.16; //double->double
+print(g);
+g = "I like cake!";
+print(g);  //object to various
+print(g & 0xff);
+print(g * 2);
+print(g >>> 2);
+print(g);
+
+var h = {x:17, y:17.4711, z:"salamander"};
+print(h.x);
+print(h.y);
+print(h.z);
+h.x = 4711.17;
+h.y = "axolotl";
+h.z = "lizard";
+print(h.x);
+print(h.y);
+print(h.z);
diff --git a/nashorn/test/script/basic/NASHORN-592.js.EXPECTED b/nashorn/test/script/basic/NASHORN-592.js.EXPECTED
new file mode 100644
index 0000000..8ff2cd4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-592.js.EXPECTED
@@ -0,0 +1,44 @@
+0
+0
+NaN
+undefinedhej!
+17
+8
+34
+17hej!
+17
+8
+34.9422
+17.4711hej!
+0
+0
+NaN
+Fame and fortune Salamander Yahoo!hej!
+24
+11111
+23.23
+23
+23
+Have some pie!
+4711.17
+17172
+23
+23.23
+23
+23
+Have some pie!
+4711.17
+23
+111
+4711.16
+I like cake!
+0
+NaN
+0
+I like cake!
+17
+17.4711
+salamander
+4711.17
+axolotl
+lizard
diff --git a/nashorn/test/script/basic/NASHORN-597.js b/nashorn/test/script/basic/NASHORN-597.js
new file mode 100644
index 0000000..7195b05
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-597.js
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-597 :  Conditional catch does not rethrow if it is the last catch clause
+ *
+ * @test
+ * @run
+ */
+
+try {
+    throw new String("t1");
+} catch (e if e instanceof String) {
+    print("ok:", e);
+}
+
+try {
+    throw new Error("t2");
+} catch (s if s instanceof String) {
+    print("err:", s);
+} catch (e if e instanceof Error) {
+    print("ok:", e.name);
+} catch (e) {
+    print("err:", e);
+} finally {
+    print("finally run");
+}
+
+try {
+    throw new Error("t2");
+} catch (s if s instanceof String) {
+    print("err:", s);
+} catch (e) {
+    print("ok:", e.name);
+} finally {
+    print("finally run");
+}
+
+var obj = new Object();
+
+try {
+    try {
+        throw obj;
+    } catch (s if s instanceof String) {
+        print("err:", s);
+    } catch (e if e instanceof RegExp) {
+        print("err:", e);
+    }
+} catch (o) {
+    print("ok:", o === obj);
+}
+
+try {
+    try {
+        throw obj;
+    } catch (s if s instanceof String) {
+        print("err:", s);
+    } finally {
+        print("finally run");
+    }
+} catch (o if o === obj) {
+    print("ok:", o);
+}
diff --git a/nashorn/test/script/basic/NASHORN-597.js.EXPECTED b/nashorn/test/script/basic/NASHORN-597.js.EXPECTED
new file mode 100644
index 0000000..1c8fa94
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-597.js.EXPECTED
@@ -0,0 +1,8 @@
+ok: t1
+ok: Error
+finally run
+ok: Error
+finally run
+ok: true
+finally run
+ok: [object Object]
diff --git a/nashorn/test/script/basic/NASHORN-60.js b/nashorn/test/script/basic/NASHORN-60.js
new file mode 100644
index 0000000..338c237
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-60.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-60 :  For illegal regular expressions, proper error message is not set in SyntaxError.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    var x = new RegExp("2**");
+    print(x);
+} catch(e) {
+    print(e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-60.js.EXPECTED b/nashorn/test/script/basic/NASHORN-60.js.EXPECTED
new file mode 100644
index 0000000..adb367b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-60.js.EXPECTED
@@ -0,0 +1,3 @@
+SyntaxError: Dangling meta character '*' near index 2
+2**
+  ^
diff --git a/nashorn/test/script/basic/NASHORN-609.js b/nashorn/test/script/basic/NASHORN-609.js
new file mode 100644
index 0000000..5c84f01
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-609.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-609: ASSIGN_SHR result is converted to INT (should be UINT32).
+ *
+ * @test
+ * @run
+ */
+function test() {
+    var shr = -1;
+    print(shr >>>= 0, shr);
+    var shr2 = 0xffffffff;
+    print(shr2 >>>= 0, shr2);
+    var shr3 = "-1";
+    print(shr3 >>>= 0, shr3);
+    var shr4 = -1.5;
+    print(shr4 >>>= 0, shr4);
+    var shr5 = 0xffffffffff;
+    print(shr5 >>>= 0, shr5);
+}
+test();
+
diff --git a/nashorn/test/script/basic/NASHORN-609.js.EXPECTED b/nashorn/test/script/basic/NASHORN-609.js.EXPECTED
new file mode 100644
index 0000000..6091342
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-609.js.EXPECTED
@@ -0,0 +1,5 @@
+4294967295 4294967295
+4294967295 4294967295
+4294967295 4294967295
+4294967295 4294967295
+4294967295 4294967295
diff --git a/nashorn/test/script/basic/NASHORN-61.js b/nashorn/test/script/basic/NASHORN-61.js
new file mode 100644
index 0000000..0c7f235
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-61.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-61 :  With statement should convert with expression to object type.
+ *
+ * @test
+ * @run
+ */
+
+var str = "hello";
+
+with(str) {
+    print("indexOf('l') is " + indexOf('l'));
+}
diff --git a/nashorn/test/script/basic/NASHORN-61.js.EXPECTED b/nashorn/test/script/basic/NASHORN-61.js.EXPECTED
new file mode 100644
index 0000000..a33299d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-61.js.EXPECTED
@@ -0,0 +1 @@
+indexOf('l') is 2
diff --git a/nashorn/test/script/basic/NASHORN-62.js b/nashorn/test/script/basic/NASHORN-62.js
new file mode 100644
index 0000000..a3ba6e2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-62.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-62 :  Callsite not guarded property
+ *
+ * @test
+ * @run
+ */
+
+function X() {}
+X.prototype.toString = function() {
+    return  this.name;
+}
+
+function Y() {
+}
+
+Y.prototype = Object.create(X.prototype);
+Y.prototype.name = "Y";
+
+var y = new Y();
+
+function Z() {
+}
+
+Z.prototype = Object.create(X.prototype);
+Z.prototype.name = "Z";
+var z = new Z();
+
+print("y.toString() " + y.toString());
+print("z.toString() " + z.toString());
diff --git a/nashorn/test/script/basic/NASHORN-62.js.EXPECTED b/nashorn/test/script/basic/NASHORN-62.js.EXPECTED
new file mode 100644
index 0000000..5a4ae30
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-62.js.EXPECTED
@@ -0,0 +1,2 @@
+y.toString() Y
+z.toString() Z
diff --git a/nashorn/test/script/basic/NASHORN-620.js b/nashorn/test/script/basic/NASHORN-620.js
new file mode 100644
index 0000000..ce99528
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-620.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * NASHORN-620: Trailing comma at the end of an array literal should be ignored.
+ *
+ * @test
+ * @run
+ */
+
+print([].length);
+print([,].length);
+print([,,].length);
+print([,4,].length);
+print([1,,3,].length);
diff --git a/nashorn/test/script/basic/NASHORN-620.js.EXPECTED b/nashorn/test/script/basic/NASHORN-620.js.EXPECTED
new file mode 100644
index 0000000..dac65b1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-620.js.EXPECTED
@@ -0,0 +1,5 @@
+0
+1
+2
+2
+3
diff --git a/nashorn/test/script/basic/NASHORN-623.js b/nashorn/test/script/basic/NASHORN-623.js
new file mode 100644
index 0000000..8ecdb13
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-623.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-623 : JSON parser does not allow negative integer
+ *
+ * @test
+ * @run
+ */
+
+var obj = JSON.parse("{ \"test\" : -1 }");
+if (obj.test != -1) {
+    fail("expected obj.test to be -1, got " + obj.test);
+}
+
+obj = JSON.parse("{ \"test\" : [3, -2] }");
+if (obj.test[1] != -2) {
+    fail("expected obj.test[1] to be -2, got " + obj.test[1]);
+}
+
+obj = JSON.parse("{ \"test\": { \"foo\": -3 } }");
+if (obj.test.foo != -3) {
+    fail("expected obj.test.foo to be -3, got " + obj.test.foo);
+}
+
+try {
+    JSON.parse("{ \"test\" : -xxx }");
+    fail("should have thrown SyntaxError");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+        fail("expected SyntaxError, got " + e);
+    }
+    print(e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-623.js.EXPECTED b/nashorn/test/script/basic/NASHORN-623.js.EXPECTED
new file mode 100644
index 0000000..5755489
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-623.js.EXPECTED
@@ -0,0 +1,3 @@
+SyntaxError: Invalid JSON: <json>:1:12 Expected number but found ident
+{ "test" : -xxx }
+            ^
diff --git a/nashorn/test/script/basic/NASHORN-627.js b/nashorn/test/script/basic/NASHORN-627.js
new file mode 100644
index 0000000..07662ff
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-627.js
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-627 : Make NativeDate fully ECMA compliant
+ *
+ * @test
+ * @option -timezone=Europe/Vienna
+ * @run
+ */
+
+// constructor, toString, getTime, toISOString. EXPECTED is from spidermonkey
+function printDate(d) {
+    print(d, d.getTime(), d.toISOString());
+}
+for (var i = -10; i < 380; i++) {
+    printDate(new Date(70, 0, i));
+}
+for (var i = -10; i < 380; i++) {
+    printDate(new Date(2011, 0, i, 17, 0, 59));
+}
+for (var i = -10; i < 380; i++) {
+    printDate(new Date(2012, 0, i, 12, 30, 10, 500));
+}
+
+[
+    '2012-03-01 09:00',
+    '2012-03-01 08:00 +0000',
+    '2012/03/01 08:00 GMT+0000',
+    '03/01/2012, 08:00 AM UT',
+    '01 March 12 08:00 +0000',
+    'Mar 01 08:00:00 UT 2012',
+    'Sat, 01-Mar-2012 08:00:00 UT',
+    'Sat, 01 Mar 2012 08:00:00 UT',
+    'Mar 01 2012 08:00:00 UT',
+    'Saturday, 01-Mar-2012 08:00:00 UT',
+    '01 Mar 2012 08:00 +0000',
+
+    'Sat, 01-Mar-2012 03:00:00 EST',
+    'Sat, 01 Mar 2012 03:00:00 EST',
+    'Mar 01 2012 03:00:00 EST',
+    'Saturday, 01-Mar-2012 03:00:00 EST',
+    '01 Mar 2012 03:00 -0500',
+
+    'Sat, 01-Mar-2012 04:00:00 EDT',
+    'Sat, 01 Mar 2012 04:00:00 EDT',
+    'Mar 01 2012 04:00:00 EDT',
+    'Saturday, 01-Mar-2012 04:00:00 EDT',
+    '01 Mar 2012 04:00 -0400',
+
+    'Sat, 01-Mar-2012 02:00:00 CST',
+    'Sat, 01 Mar 2012 02:00:00 CST',
+    'Mar 01 2012 02:00:00 CST',
+    'Saturday, 01-Mar-2012 02:00:00 CST',
+    '01 Mar 2012 02:00 -0600',
+
+    'Sat, 01-Mar-2012 03:00:00 CDT',
+    'Sat, 01 Mar 2012 03:00:00 CDT',
+    'Mar 01 2012 03:00:00 CDT',
+    'Saturday, 01-Mar-2012 03:00:00 CDT',
+    '01 Mar 2012 03:00 -0500',
+
+    'Sat, 01-Mar-2012 01:00:00 MST',
+    'Sat, 01 Mar 2012 01:00:00 MST',
+    'Mar 01 2012 01:00:00 MST',
+    'Saturday, 01-Mar-2012 01:00:00 MST',
+    '01 Mar 2012 01:00 -0700',
+
+    'Sat, 01-Mar-2012 02:00:00 MDT',
+    'Sat, 01 Mar 2012 02:00:00 MDT',
+    'Mar 01 2012 02:00:00 MDT',
+    'Saturday, 01-Mar-2012 02:00:00 MDT',
+    '01 Mar 2012 02:00 -0600',
+
+    'Sat, 01-Mar-2012 00:00:00 PST',
+    'Sat, 01 Mar 2012 00:00:00 PST',
+    'Mar 01 2012 00:00:00 PST',
+    'Saturday, 01-Mar-2012 00:00:00 PST',
+    '01 Mar 2012 00:00 -0800',
+
+    'Sat, 01-Mar-2012 01:00:00 PDT',
+    'Sat, 01 Mar 2012 01:00:00 PDT',
+    'Mar 01 2012 01:00:00 PDT',
+    'Saturday, 01-Mar-2012 01:00:00 PDT',
+    '01 Mar 2012 01:00 -0700'
+].forEach(function(s) {
+    parseDate(s, 1330588800000);
+});
+
+[
+    '2012-01-01T08:00:00.000Z',
+    '2012-01-01T08:00:00Z',
+    '2012-01-01T08:00Z',
+    '2012-01T08:00:00.000Z',
+    '2012T08:00:00.000Z',
+    '2012T08:00Z',
+    '2012-01T00:00:00.000-08:00',
+    '2012-01T00:00:00.000-08:00'
+].forEach(function(s) {
+    parseDate(s, 1325404800000);
+});
+
+[
+    'Mon, 25 Dec 1995 13:30:00 GMT+0430',
+    '1995/12/25 13:30 GMT+0430',
+    '12/25/1995, 01:30 PM +04:30',
+    'Dec 25 1995 13:30:00 +0430'
+].forEach(function(s) {
+    parseDate(s, 819882000000);
+});
+
+// invalid iso dates
+[
+    '2000-01-01TZ',
+    '2000-01-01T60Z',
+    '2000-01-01T60:60Z',
+    '2000-01-0108:00Z',
+    '2000-01-01T08Z'
+].forEach(function(s) {
+        parseDate(s, NaN);
+    });
+
+// milliseconds
+parseDate('2012-01T08:00:00.001Z', 1325404800001);
+parseDate('2012-01T08:00:00.099Z', 1325404800099);
+parseDate('2012-01T08:00:00.999Z', 1325404800999);
+
+function parseDate(s, t) {
+    var d = new Date(s.toString());
+    if (d.getTime() == t || (isNaN(d.getTime() && isNaN(t)))) {
+        print('ok', d);
+    } else {
+        print('expected', t, 'got', d.getTime());
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-627.js.EXPECTED b/nashorn/test/script/basic/NASHORN-627.js.EXPECTED
new file mode 100644
index 0000000..4666d99
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-627.js.EXPECTED
@@ -0,0 +1,1241 @@
+Sun Dec 21 1969 00:00:00 GMT+0100 (CET) -954000000 1969-12-20T23:00:00.000Z
+Mon Dec 22 1969 00:00:00 GMT+0100 (CET) -867600000 1969-12-21T23:00:00.000Z
+Tue Dec 23 1969 00:00:00 GMT+0100 (CET) -781200000 1969-12-22T23:00:00.000Z
+Wed Dec 24 1969 00:00:00 GMT+0100 (CET) -694800000 1969-12-23T23:00:00.000Z
+Thu Dec 25 1969 00:00:00 GMT+0100 (CET) -608400000 1969-12-24T23:00:00.000Z
+Fri Dec 26 1969 00:00:00 GMT+0100 (CET) -522000000 1969-12-25T23:00:00.000Z
+Sat Dec 27 1969 00:00:00 GMT+0100 (CET) -435600000 1969-12-26T23:00:00.000Z
+Sun Dec 28 1969 00:00:00 GMT+0100 (CET) -349200000 1969-12-27T23:00:00.000Z
+Mon Dec 29 1969 00:00:00 GMT+0100 (CET) -262800000 1969-12-28T23:00:00.000Z
+Tue Dec 30 1969 00:00:00 GMT+0100 (CET) -176400000 1969-12-29T23:00:00.000Z
+Wed Dec 31 1969 00:00:00 GMT+0100 (CET) -90000000 1969-12-30T23:00:00.000Z
+Thu Jan 01 1970 00:00:00 GMT+0100 (CET) -3600000 1969-12-31T23:00:00.000Z
+Fri Jan 02 1970 00:00:00 GMT+0100 (CET) 82800000 1970-01-01T23:00:00.000Z
+Sat Jan 03 1970 00:00:00 GMT+0100 (CET) 169200000 1970-01-02T23:00:00.000Z
+Sun Jan 04 1970 00:00:00 GMT+0100 (CET) 255600000 1970-01-03T23:00:00.000Z
+Mon Jan 05 1970 00:00:00 GMT+0100 (CET) 342000000 1970-01-04T23:00:00.000Z
+Tue Jan 06 1970 00:00:00 GMT+0100 (CET) 428400000 1970-01-05T23:00:00.000Z
+Wed Jan 07 1970 00:00:00 GMT+0100 (CET) 514800000 1970-01-06T23:00:00.000Z
+Thu Jan 08 1970 00:00:00 GMT+0100 (CET) 601200000 1970-01-07T23:00:00.000Z
+Fri Jan 09 1970 00:00:00 GMT+0100 (CET) 687600000 1970-01-08T23:00:00.000Z
+Sat Jan 10 1970 00:00:00 GMT+0100 (CET) 774000000 1970-01-09T23:00:00.000Z
+Sun Jan 11 1970 00:00:00 GMT+0100 (CET) 860400000 1970-01-10T23:00:00.000Z
+Mon Jan 12 1970 00:00:00 GMT+0100 (CET) 946800000 1970-01-11T23:00:00.000Z
+Tue Jan 13 1970 00:00:00 GMT+0100 (CET) 1033200000 1970-01-12T23:00:00.000Z
+Wed Jan 14 1970 00:00:00 GMT+0100 (CET) 1119600000 1970-01-13T23:00:00.000Z
+Thu Jan 15 1970 00:00:00 GMT+0100 (CET) 1206000000 1970-01-14T23:00:00.000Z
+Fri Jan 16 1970 00:00:00 GMT+0100 (CET) 1292400000 1970-01-15T23:00:00.000Z
+Sat Jan 17 1970 00:00:00 GMT+0100 (CET) 1378800000 1970-01-16T23:00:00.000Z
+Sun Jan 18 1970 00:00:00 GMT+0100 (CET) 1465200000 1970-01-17T23:00:00.000Z
+Mon Jan 19 1970 00:00:00 GMT+0100 (CET) 1551600000 1970-01-18T23:00:00.000Z
+Tue Jan 20 1970 00:00:00 GMT+0100 (CET) 1638000000 1970-01-19T23:00:00.000Z
+Wed Jan 21 1970 00:00:00 GMT+0100 (CET) 1724400000 1970-01-20T23:00:00.000Z
+Thu Jan 22 1970 00:00:00 GMT+0100 (CET) 1810800000 1970-01-21T23:00:00.000Z
+Fri Jan 23 1970 00:00:00 GMT+0100 (CET) 1897200000 1970-01-22T23:00:00.000Z
+Sat Jan 24 1970 00:00:00 GMT+0100 (CET) 1983600000 1970-01-23T23:00:00.000Z
+Sun Jan 25 1970 00:00:00 GMT+0100 (CET) 2070000000 1970-01-24T23:00:00.000Z
+Mon Jan 26 1970 00:00:00 GMT+0100 (CET) 2156400000 1970-01-25T23:00:00.000Z
+Tue Jan 27 1970 00:00:00 GMT+0100 (CET) 2242800000 1970-01-26T23:00:00.000Z
+Wed Jan 28 1970 00:00:00 GMT+0100 (CET) 2329200000 1970-01-27T23:00:00.000Z
+Thu Jan 29 1970 00:00:00 GMT+0100 (CET) 2415600000 1970-01-28T23:00:00.000Z
+Fri Jan 30 1970 00:00:00 GMT+0100 (CET) 2502000000 1970-01-29T23:00:00.000Z
+Sat Jan 31 1970 00:00:00 GMT+0100 (CET) 2588400000 1970-01-30T23:00:00.000Z
+Sun Feb 01 1970 00:00:00 GMT+0100 (CET) 2674800000 1970-01-31T23:00:00.000Z
+Mon Feb 02 1970 00:00:00 GMT+0100 (CET) 2761200000 1970-02-01T23:00:00.000Z
+Tue Feb 03 1970 00:00:00 GMT+0100 (CET) 2847600000 1970-02-02T23:00:00.000Z
+Wed Feb 04 1970 00:00:00 GMT+0100 (CET) 2934000000 1970-02-03T23:00:00.000Z
+Thu Feb 05 1970 00:00:00 GMT+0100 (CET) 3020400000 1970-02-04T23:00:00.000Z
+Fri Feb 06 1970 00:00:00 GMT+0100 (CET) 3106800000 1970-02-05T23:00:00.000Z
+Sat Feb 07 1970 00:00:00 GMT+0100 (CET) 3193200000 1970-02-06T23:00:00.000Z
+Sun Feb 08 1970 00:00:00 GMT+0100 (CET) 3279600000 1970-02-07T23:00:00.000Z
+Mon Feb 09 1970 00:00:00 GMT+0100 (CET) 3366000000 1970-02-08T23:00:00.000Z
+Tue Feb 10 1970 00:00:00 GMT+0100 (CET) 3452400000 1970-02-09T23:00:00.000Z
+Wed Feb 11 1970 00:00:00 GMT+0100 (CET) 3538800000 1970-02-10T23:00:00.000Z
+Thu Feb 12 1970 00:00:00 GMT+0100 (CET) 3625200000 1970-02-11T23:00:00.000Z
+Fri Feb 13 1970 00:00:00 GMT+0100 (CET) 3711600000 1970-02-12T23:00:00.000Z
+Sat Feb 14 1970 00:00:00 GMT+0100 (CET) 3798000000 1970-02-13T23:00:00.000Z
+Sun Feb 15 1970 00:00:00 GMT+0100 (CET) 3884400000 1970-02-14T23:00:00.000Z
+Mon Feb 16 1970 00:00:00 GMT+0100 (CET) 3970800000 1970-02-15T23:00:00.000Z
+Tue Feb 17 1970 00:00:00 GMT+0100 (CET) 4057200000 1970-02-16T23:00:00.000Z
+Wed Feb 18 1970 00:00:00 GMT+0100 (CET) 4143600000 1970-02-17T23:00:00.000Z
+Thu Feb 19 1970 00:00:00 GMT+0100 (CET) 4230000000 1970-02-18T23:00:00.000Z
+Fri Feb 20 1970 00:00:00 GMT+0100 (CET) 4316400000 1970-02-19T23:00:00.000Z
+Sat Feb 21 1970 00:00:00 GMT+0100 (CET) 4402800000 1970-02-20T23:00:00.000Z
+Sun Feb 22 1970 00:00:00 GMT+0100 (CET) 4489200000 1970-02-21T23:00:00.000Z
+Mon Feb 23 1970 00:00:00 GMT+0100 (CET) 4575600000 1970-02-22T23:00:00.000Z
+Tue Feb 24 1970 00:00:00 GMT+0100 (CET) 4662000000 1970-02-23T23:00:00.000Z
+Wed Feb 25 1970 00:00:00 GMT+0100 (CET) 4748400000 1970-02-24T23:00:00.000Z
+Thu Feb 26 1970 00:00:00 GMT+0100 (CET) 4834800000 1970-02-25T23:00:00.000Z
+Fri Feb 27 1970 00:00:00 GMT+0100 (CET) 4921200000 1970-02-26T23:00:00.000Z
+Sat Feb 28 1970 00:00:00 GMT+0100 (CET) 5007600000 1970-02-27T23:00:00.000Z
+Sun Mar 01 1970 00:00:00 GMT+0100 (CET) 5094000000 1970-02-28T23:00:00.000Z
+Mon Mar 02 1970 00:00:00 GMT+0100 (CET) 5180400000 1970-03-01T23:00:00.000Z
+Tue Mar 03 1970 00:00:00 GMT+0100 (CET) 5266800000 1970-03-02T23:00:00.000Z
+Wed Mar 04 1970 00:00:00 GMT+0100 (CET) 5353200000 1970-03-03T23:00:00.000Z
+Thu Mar 05 1970 00:00:00 GMT+0100 (CET) 5439600000 1970-03-04T23:00:00.000Z
+Fri Mar 06 1970 00:00:00 GMT+0100 (CET) 5526000000 1970-03-05T23:00:00.000Z
+Sat Mar 07 1970 00:00:00 GMT+0100 (CET) 5612400000 1970-03-06T23:00:00.000Z
+Sun Mar 08 1970 00:00:00 GMT+0100 (CET) 5698800000 1970-03-07T23:00:00.000Z
+Mon Mar 09 1970 00:00:00 GMT+0100 (CET) 5785200000 1970-03-08T23:00:00.000Z
+Tue Mar 10 1970 00:00:00 GMT+0100 (CET) 5871600000 1970-03-09T23:00:00.000Z
+Wed Mar 11 1970 00:00:00 GMT+0100 (CET) 5958000000 1970-03-10T23:00:00.000Z
+Thu Mar 12 1970 00:00:00 GMT+0100 (CET) 6044400000 1970-03-11T23:00:00.000Z
+Fri Mar 13 1970 00:00:00 GMT+0100 (CET) 6130800000 1970-03-12T23:00:00.000Z
+Sat Mar 14 1970 00:00:00 GMT+0100 (CET) 6217200000 1970-03-13T23:00:00.000Z
+Sun Mar 15 1970 00:00:00 GMT+0100 (CET) 6303600000 1970-03-14T23:00:00.000Z
+Mon Mar 16 1970 00:00:00 GMT+0100 (CET) 6390000000 1970-03-15T23:00:00.000Z
+Tue Mar 17 1970 00:00:00 GMT+0100 (CET) 6476400000 1970-03-16T23:00:00.000Z
+Wed Mar 18 1970 00:00:00 GMT+0100 (CET) 6562800000 1970-03-17T23:00:00.000Z
+Thu Mar 19 1970 00:00:00 GMT+0100 (CET) 6649200000 1970-03-18T23:00:00.000Z
+Fri Mar 20 1970 00:00:00 GMT+0100 (CET) 6735600000 1970-03-19T23:00:00.000Z
+Sat Mar 21 1970 00:00:00 GMT+0100 (CET) 6822000000 1970-03-20T23:00:00.000Z
+Sun Mar 22 1970 00:00:00 GMT+0100 (CET) 6908400000 1970-03-21T23:00:00.000Z
+Mon Mar 23 1970 00:00:00 GMT+0100 (CET) 6994800000 1970-03-22T23:00:00.000Z
+Tue Mar 24 1970 00:00:00 GMT+0100 (CET) 7081200000 1970-03-23T23:00:00.000Z
+Wed Mar 25 1970 00:00:00 GMT+0100 (CET) 7167600000 1970-03-24T23:00:00.000Z
+Thu Mar 26 1970 00:00:00 GMT+0100 (CET) 7254000000 1970-03-25T23:00:00.000Z
+Fri Mar 27 1970 00:00:00 GMT+0100 (CET) 7340400000 1970-03-26T23:00:00.000Z
+Sat Mar 28 1970 00:00:00 GMT+0100 (CET) 7426800000 1970-03-27T23:00:00.000Z
+Sun Mar 29 1970 00:00:00 GMT+0100 (CET) 7513200000 1970-03-28T23:00:00.000Z
+Mon Mar 30 1970 00:00:00 GMT+0100 (CET) 7599600000 1970-03-29T23:00:00.000Z
+Tue Mar 31 1970 00:00:00 GMT+0100 (CET) 7686000000 1970-03-30T23:00:00.000Z
+Wed Apr 01 1970 00:00:00 GMT+0100 (CET) 7772400000 1970-03-31T23:00:00.000Z
+Thu Apr 02 1970 00:00:00 GMT+0100 (CET) 7858800000 1970-04-01T23:00:00.000Z
+Fri Apr 03 1970 00:00:00 GMT+0100 (CET) 7945200000 1970-04-02T23:00:00.000Z
+Sat Apr 04 1970 00:00:00 GMT+0100 (CET) 8031600000 1970-04-03T23:00:00.000Z
+Sun Apr 05 1970 00:00:00 GMT+0100 (CET) 8118000000 1970-04-04T23:00:00.000Z
+Mon Apr 06 1970 00:00:00 GMT+0100 (CET) 8204400000 1970-04-05T23:00:00.000Z
+Tue Apr 07 1970 00:00:00 GMT+0100 (CET) 8290800000 1970-04-06T23:00:00.000Z
+Wed Apr 08 1970 00:00:00 GMT+0100 (CET) 8377200000 1970-04-07T23:00:00.000Z
+Thu Apr 09 1970 00:00:00 GMT+0100 (CET) 8463600000 1970-04-08T23:00:00.000Z
+Fri Apr 10 1970 00:00:00 GMT+0100 (CET) 8550000000 1970-04-09T23:00:00.000Z
+Sat Apr 11 1970 00:00:00 GMT+0100 (CET) 8636400000 1970-04-10T23:00:00.000Z
+Sun Apr 12 1970 00:00:00 GMT+0100 (CET) 8722800000 1970-04-11T23:00:00.000Z
+Mon Apr 13 1970 00:00:00 GMT+0100 (CET) 8809200000 1970-04-12T23:00:00.000Z
+Tue Apr 14 1970 00:00:00 GMT+0100 (CET) 8895600000 1970-04-13T23:00:00.000Z
+Wed Apr 15 1970 00:00:00 GMT+0100 (CET) 8982000000 1970-04-14T23:00:00.000Z
+Thu Apr 16 1970 00:00:00 GMT+0100 (CET) 9068400000 1970-04-15T23:00:00.000Z
+Fri Apr 17 1970 00:00:00 GMT+0100 (CET) 9154800000 1970-04-16T23:00:00.000Z
+Sat Apr 18 1970 00:00:00 GMT+0100 (CET) 9241200000 1970-04-17T23:00:00.000Z
+Sun Apr 19 1970 00:00:00 GMT+0100 (CET) 9327600000 1970-04-18T23:00:00.000Z
+Mon Apr 20 1970 00:00:00 GMT+0100 (CET) 9414000000 1970-04-19T23:00:00.000Z
+Tue Apr 21 1970 00:00:00 GMT+0100 (CET) 9500400000 1970-04-20T23:00:00.000Z
+Wed Apr 22 1970 00:00:00 GMT+0100 (CET) 9586800000 1970-04-21T23:00:00.000Z
+Thu Apr 23 1970 00:00:00 GMT+0100 (CET) 9673200000 1970-04-22T23:00:00.000Z
+Fri Apr 24 1970 00:00:00 GMT+0100 (CET) 9759600000 1970-04-23T23:00:00.000Z
+Sat Apr 25 1970 00:00:00 GMT+0100 (CET) 9846000000 1970-04-24T23:00:00.000Z
+Sun Apr 26 1970 00:00:00 GMT+0100 (CET) 9932400000 1970-04-25T23:00:00.000Z
+Mon Apr 27 1970 00:00:00 GMT+0100 (CET) 10018800000 1970-04-26T23:00:00.000Z
+Tue Apr 28 1970 00:00:00 GMT+0100 (CET) 10105200000 1970-04-27T23:00:00.000Z
+Wed Apr 29 1970 00:00:00 GMT+0100 (CET) 10191600000 1970-04-28T23:00:00.000Z
+Thu Apr 30 1970 00:00:00 GMT+0100 (CET) 10278000000 1970-04-29T23:00:00.000Z
+Fri May 01 1970 00:00:00 GMT+0100 (CET) 10364400000 1970-04-30T23:00:00.000Z
+Sat May 02 1970 00:00:00 GMT+0100 (CET) 10450800000 1970-05-01T23:00:00.000Z
+Sun May 03 1970 00:00:00 GMT+0100 (CET) 10537200000 1970-05-02T23:00:00.000Z
+Mon May 04 1970 00:00:00 GMT+0100 (CET) 10623600000 1970-05-03T23:00:00.000Z
+Tue May 05 1970 00:00:00 GMT+0100 (CET) 10710000000 1970-05-04T23:00:00.000Z
+Wed May 06 1970 00:00:00 GMT+0100 (CET) 10796400000 1970-05-05T23:00:00.000Z
+Thu May 07 1970 00:00:00 GMT+0100 (CET) 10882800000 1970-05-06T23:00:00.000Z
+Fri May 08 1970 00:00:00 GMT+0100 (CET) 10969200000 1970-05-07T23:00:00.000Z
+Sat May 09 1970 00:00:00 GMT+0100 (CET) 11055600000 1970-05-08T23:00:00.000Z
+Sun May 10 1970 00:00:00 GMT+0100 (CET) 11142000000 1970-05-09T23:00:00.000Z
+Mon May 11 1970 00:00:00 GMT+0100 (CET) 11228400000 1970-05-10T23:00:00.000Z
+Tue May 12 1970 00:00:00 GMT+0100 (CET) 11314800000 1970-05-11T23:00:00.000Z
+Wed May 13 1970 00:00:00 GMT+0100 (CET) 11401200000 1970-05-12T23:00:00.000Z
+Thu May 14 1970 00:00:00 GMT+0100 (CET) 11487600000 1970-05-13T23:00:00.000Z
+Fri May 15 1970 00:00:00 GMT+0100 (CET) 11574000000 1970-05-14T23:00:00.000Z
+Sat May 16 1970 00:00:00 GMT+0100 (CET) 11660400000 1970-05-15T23:00:00.000Z
+Sun May 17 1970 00:00:00 GMT+0100 (CET) 11746800000 1970-05-16T23:00:00.000Z
+Mon May 18 1970 00:00:00 GMT+0100 (CET) 11833200000 1970-05-17T23:00:00.000Z
+Tue May 19 1970 00:00:00 GMT+0100 (CET) 11919600000 1970-05-18T23:00:00.000Z
+Wed May 20 1970 00:00:00 GMT+0100 (CET) 12006000000 1970-05-19T23:00:00.000Z
+Thu May 21 1970 00:00:00 GMT+0100 (CET) 12092400000 1970-05-20T23:00:00.000Z
+Fri May 22 1970 00:00:00 GMT+0100 (CET) 12178800000 1970-05-21T23:00:00.000Z
+Sat May 23 1970 00:00:00 GMT+0100 (CET) 12265200000 1970-05-22T23:00:00.000Z
+Sun May 24 1970 00:00:00 GMT+0100 (CET) 12351600000 1970-05-23T23:00:00.000Z
+Mon May 25 1970 00:00:00 GMT+0100 (CET) 12438000000 1970-05-24T23:00:00.000Z
+Tue May 26 1970 00:00:00 GMT+0100 (CET) 12524400000 1970-05-25T23:00:00.000Z
+Wed May 27 1970 00:00:00 GMT+0100 (CET) 12610800000 1970-05-26T23:00:00.000Z
+Thu May 28 1970 00:00:00 GMT+0100 (CET) 12697200000 1970-05-27T23:00:00.000Z
+Fri May 29 1970 00:00:00 GMT+0100 (CET) 12783600000 1970-05-28T23:00:00.000Z
+Sat May 30 1970 00:00:00 GMT+0100 (CET) 12870000000 1970-05-29T23:00:00.000Z
+Sun May 31 1970 00:00:00 GMT+0100 (CET) 12956400000 1970-05-30T23:00:00.000Z
+Mon Jun 01 1970 00:00:00 GMT+0100 (CET) 13042800000 1970-05-31T23:00:00.000Z
+Tue Jun 02 1970 00:00:00 GMT+0100 (CET) 13129200000 1970-06-01T23:00:00.000Z
+Wed Jun 03 1970 00:00:00 GMT+0100 (CET) 13215600000 1970-06-02T23:00:00.000Z
+Thu Jun 04 1970 00:00:00 GMT+0100 (CET) 13302000000 1970-06-03T23:00:00.000Z
+Fri Jun 05 1970 00:00:00 GMT+0100 (CET) 13388400000 1970-06-04T23:00:00.000Z
+Sat Jun 06 1970 00:00:00 GMT+0100 (CET) 13474800000 1970-06-05T23:00:00.000Z
+Sun Jun 07 1970 00:00:00 GMT+0100 (CET) 13561200000 1970-06-06T23:00:00.000Z
+Mon Jun 08 1970 00:00:00 GMT+0100 (CET) 13647600000 1970-06-07T23:00:00.000Z
+Tue Jun 09 1970 00:00:00 GMT+0100 (CET) 13734000000 1970-06-08T23:00:00.000Z
+Wed Jun 10 1970 00:00:00 GMT+0100 (CET) 13820400000 1970-06-09T23:00:00.000Z
+Thu Jun 11 1970 00:00:00 GMT+0100 (CET) 13906800000 1970-06-10T23:00:00.000Z
+Fri Jun 12 1970 00:00:00 GMT+0100 (CET) 13993200000 1970-06-11T23:00:00.000Z
+Sat Jun 13 1970 00:00:00 GMT+0100 (CET) 14079600000 1970-06-12T23:00:00.000Z
+Sun Jun 14 1970 00:00:00 GMT+0100 (CET) 14166000000 1970-06-13T23:00:00.000Z
+Mon Jun 15 1970 00:00:00 GMT+0100 (CET) 14252400000 1970-06-14T23:00:00.000Z
+Tue Jun 16 1970 00:00:00 GMT+0100 (CET) 14338800000 1970-06-15T23:00:00.000Z
+Wed Jun 17 1970 00:00:00 GMT+0100 (CET) 14425200000 1970-06-16T23:00:00.000Z
+Thu Jun 18 1970 00:00:00 GMT+0100 (CET) 14511600000 1970-06-17T23:00:00.000Z
+Fri Jun 19 1970 00:00:00 GMT+0100 (CET) 14598000000 1970-06-18T23:00:00.000Z
+Sat Jun 20 1970 00:00:00 GMT+0100 (CET) 14684400000 1970-06-19T23:00:00.000Z
+Sun Jun 21 1970 00:00:00 GMT+0100 (CET) 14770800000 1970-06-20T23:00:00.000Z
+Mon Jun 22 1970 00:00:00 GMT+0100 (CET) 14857200000 1970-06-21T23:00:00.000Z
+Tue Jun 23 1970 00:00:00 GMT+0100 (CET) 14943600000 1970-06-22T23:00:00.000Z
+Wed Jun 24 1970 00:00:00 GMT+0100 (CET) 15030000000 1970-06-23T23:00:00.000Z
+Thu Jun 25 1970 00:00:00 GMT+0100 (CET) 15116400000 1970-06-24T23:00:00.000Z
+Fri Jun 26 1970 00:00:00 GMT+0100 (CET) 15202800000 1970-06-25T23:00:00.000Z
+Sat Jun 27 1970 00:00:00 GMT+0100 (CET) 15289200000 1970-06-26T23:00:00.000Z
+Sun Jun 28 1970 00:00:00 GMT+0100 (CET) 15375600000 1970-06-27T23:00:00.000Z
+Mon Jun 29 1970 00:00:00 GMT+0100 (CET) 15462000000 1970-06-28T23:00:00.000Z
+Tue Jun 30 1970 00:00:00 GMT+0100 (CET) 15548400000 1970-06-29T23:00:00.000Z
+Wed Jul 01 1970 00:00:00 GMT+0100 (CET) 15634800000 1970-06-30T23:00:00.000Z
+Thu Jul 02 1970 00:00:00 GMT+0100 (CET) 15721200000 1970-07-01T23:00:00.000Z
+Fri Jul 03 1970 00:00:00 GMT+0100 (CET) 15807600000 1970-07-02T23:00:00.000Z
+Sat Jul 04 1970 00:00:00 GMT+0100 (CET) 15894000000 1970-07-03T23:00:00.000Z
+Sun Jul 05 1970 00:00:00 GMT+0100 (CET) 15980400000 1970-07-04T23:00:00.000Z
+Mon Jul 06 1970 00:00:00 GMT+0100 (CET) 16066800000 1970-07-05T23:00:00.000Z
+Tue Jul 07 1970 00:00:00 GMT+0100 (CET) 16153200000 1970-07-06T23:00:00.000Z
+Wed Jul 08 1970 00:00:00 GMT+0100 (CET) 16239600000 1970-07-07T23:00:00.000Z
+Thu Jul 09 1970 00:00:00 GMT+0100 (CET) 16326000000 1970-07-08T23:00:00.000Z
+Fri Jul 10 1970 00:00:00 GMT+0100 (CET) 16412400000 1970-07-09T23:00:00.000Z
+Sat Jul 11 1970 00:00:00 GMT+0100 (CET) 16498800000 1970-07-10T23:00:00.000Z
+Sun Jul 12 1970 00:00:00 GMT+0100 (CET) 16585200000 1970-07-11T23:00:00.000Z
+Mon Jul 13 1970 00:00:00 GMT+0100 (CET) 16671600000 1970-07-12T23:00:00.000Z
+Tue Jul 14 1970 00:00:00 GMT+0100 (CET) 16758000000 1970-07-13T23:00:00.000Z
+Wed Jul 15 1970 00:00:00 GMT+0100 (CET) 16844400000 1970-07-14T23:00:00.000Z
+Thu Jul 16 1970 00:00:00 GMT+0100 (CET) 16930800000 1970-07-15T23:00:00.000Z
+Fri Jul 17 1970 00:00:00 GMT+0100 (CET) 17017200000 1970-07-16T23:00:00.000Z
+Sat Jul 18 1970 00:00:00 GMT+0100 (CET) 17103600000 1970-07-17T23:00:00.000Z
+Sun Jul 19 1970 00:00:00 GMT+0100 (CET) 17190000000 1970-07-18T23:00:00.000Z
+Mon Jul 20 1970 00:00:00 GMT+0100 (CET) 17276400000 1970-07-19T23:00:00.000Z
+Tue Jul 21 1970 00:00:00 GMT+0100 (CET) 17362800000 1970-07-20T23:00:00.000Z
+Wed Jul 22 1970 00:00:00 GMT+0100 (CET) 17449200000 1970-07-21T23:00:00.000Z
+Thu Jul 23 1970 00:00:00 GMT+0100 (CET) 17535600000 1970-07-22T23:00:00.000Z
+Fri Jul 24 1970 00:00:00 GMT+0100 (CET) 17622000000 1970-07-23T23:00:00.000Z
+Sat Jul 25 1970 00:00:00 GMT+0100 (CET) 17708400000 1970-07-24T23:00:00.000Z
+Sun Jul 26 1970 00:00:00 GMT+0100 (CET) 17794800000 1970-07-25T23:00:00.000Z
+Mon Jul 27 1970 00:00:00 GMT+0100 (CET) 17881200000 1970-07-26T23:00:00.000Z
+Tue Jul 28 1970 00:00:00 GMT+0100 (CET) 17967600000 1970-07-27T23:00:00.000Z
+Wed Jul 29 1970 00:00:00 GMT+0100 (CET) 18054000000 1970-07-28T23:00:00.000Z
+Thu Jul 30 1970 00:00:00 GMT+0100 (CET) 18140400000 1970-07-29T23:00:00.000Z
+Fri Jul 31 1970 00:00:00 GMT+0100 (CET) 18226800000 1970-07-30T23:00:00.000Z
+Sat Aug 01 1970 00:00:00 GMT+0100 (CET) 18313200000 1970-07-31T23:00:00.000Z
+Sun Aug 02 1970 00:00:00 GMT+0100 (CET) 18399600000 1970-08-01T23:00:00.000Z
+Mon Aug 03 1970 00:00:00 GMT+0100 (CET) 18486000000 1970-08-02T23:00:00.000Z
+Tue Aug 04 1970 00:00:00 GMT+0100 (CET) 18572400000 1970-08-03T23:00:00.000Z
+Wed Aug 05 1970 00:00:00 GMT+0100 (CET) 18658800000 1970-08-04T23:00:00.000Z
+Thu Aug 06 1970 00:00:00 GMT+0100 (CET) 18745200000 1970-08-05T23:00:00.000Z
+Fri Aug 07 1970 00:00:00 GMT+0100 (CET) 18831600000 1970-08-06T23:00:00.000Z
+Sat Aug 08 1970 00:00:00 GMT+0100 (CET) 18918000000 1970-08-07T23:00:00.000Z
+Sun Aug 09 1970 00:00:00 GMT+0100 (CET) 19004400000 1970-08-08T23:00:00.000Z
+Mon Aug 10 1970 00:00:00 GMT+0100 (CET) 19090800000 1970-08-09T23:00:00.000Z
+Tue Aug 11 1970 00:00:00 GMT+0100 (CET) 19177200000 1970-08-10T23:00:00.000Z
+Wed Aug 12 1970 00:00:00 GMT+0100 (CET) 19263600000 1970-08-11T23:00:00.000Z
+Thu Aug 13 1970 00:00:00 GMT+0100 (CET) 19350000000 1970-08-12T23:00:00.000Z
+Fri Aug 14 1970 00:00:00 GMT+0100 (CET) 19436400000 1970-08-13T23:00:00.000Z
+Sat Aug 15 1970 00:00:00 GMT+0100 (CET) 19522800000 1970-08-14T23:00:00.000Z
+Sun Aug 16 1970 00:00:00 GMT+0100 (CET) 19609200000 1970-08-15T23:00:00.000Z
+Mon Aug 17 1970 00:00:00 GMT+0100 (CET) 19695600000 1970-08-16T23:00:00.000Z
+Tue Aug 18 1970 00:00:00 GMT+0100 (CET) 19782000000 1970-08-17T23:00:00.000Z
+Wed Aug 19 1970 00:00:00 GMT+0100 (CET) 19868400000 1970-08-18T23:00:00.000Z
+Thu Aug 20 1970 00:00:00 GMT+0100 (CET) 19954800000 1970-08-19T23:00:00.000Z
+Fri Aug 21 1970 00:00:00 GMT+0100 (CET) 20041200000 1970-08-20T23:00:00.000Z
+Sat Aug 22 1970 00:00:00 GMT+0100 (CET) 20127600000 1970-08-21T23:00:00.000Z
+Sun Aug 23 1970 00:00:00 GMT+0100 (CET) 20214000000 1970-08-22T23:00:00.000Z
+Mon Aug 24 1970 00:00:00 GMT+0100 (CET) 20300400000 1970-08-23T23:00:00.000Z
+Tue Aug 25 1970 00:00:00 GMT+0100 (CET) 20386800000 1970-08-24T23:00:00.000Z
+Wed Aug 26 1970 00:00:00 GMT+0100 (CET) 20473200000 1970-08-25T23:00:00.000Z
+Thu Aug 27 1970 00:00:00 GMT+0100 (CET) 20559600000 1970-08-26T23:00:00.000Z
+Fri Aug 28 1970 00:00:00 GMT+0100 (CET) 20646000000 1970-08-27T23:00:00.000Z
+Sat Aug 29 1970 00:00:00 GMT+0100 (CET) 20732400000 1970-08-28T23:00:00.000Z
+Sun Aug 30 1970 00:00:00 GMT+0100 (CET) 20818800000 1970-08-29T23:00:00.000Z
+Mon Aug 31 1970 00:00:00 GMT+0100 (CET) 20905200000 1970-08-30T23:00:00.000Z
+Tue Sep 01 1970 00:00:00 GMT+0100 (CET) 20991600000 1970-08-31T23:00:00.000Z
+Wed Sep 02 1970 00:00:00 GMT+0100 (CET) 21078000000 1970-09-01T23:00:00.000Z
+Thu Sep 03 1970 00:00:00 GMT+0100 (CET) 21164400000 1970-09-02T23:00:00.000Z
+Fri Sep 04 1970 00:00:00 GMT+0100 (CET) 21250800000 1970-09-03T23:00:00.000Z
+Sat Sep 05 1970 00:00:00 GMT+0100 (CET) 21337200000 1970-09-04T23:00:00.000Z
+Sun Sep 06 1970 00:00:00 GMT+0100 (CET) 21423600000 1970-09-05T23:00:00.000Z
+Mon Sep 07 1970 00:00:00 GMT+0100 (CET) 21510000000 1970-09-06T23:00:00.000Z
+Tue Sep 08 1970 00:00:00 GMT+0100 (CET) 21596400000 1970-09-07T23:00:00.000Z
+Wed Sep 09 1970 00:00:00 GMT+0100 (CET) 21682800000 1970-09-08T23:00:00.000Z
+Thu Sep 10 1970 00:00:00 GMT+0100 (CET) 21769200000 1970-09-09T23:00:00.000Z
+Fri Sep 11 1970 00:00:00 GMT+0100 (CET) 21855600000 1970-09-10T23:00:00.000Z
+Sat Sep 12 1970 00:00:00 GMT+0100 (CET) 21942000000 1970-09-11T23:00:00.000Z
+Sun Sep 13 1970 00:00:00 GMT+0100 (CET) 22028400000 1970-09-12T23:00:00.000Z
+Mon Sep 14 1970 00:00:00 GMT+0100 (CET) 22114800000 1970-09-13T23:00:00.000Z
+Tue Sep 15 1970 00:00:00 GMT+0100 (CET) 22201200000 1970-09-14T23:00:00.000Z
+Wed Sep 16 1970 00:00:00 GMT+0100 (CET) 22287600000 1970-09-15T23:00:00.000Z
+Thu Sep 17 1970 00:00:00 GMT+0100 (CET) 22374000000 1970-09-16T23:00:00.000Z
+Fri Sep 18 1970 00:00:00 GMT+0100 (CET) 22460400000 1970-09-17T23:00:00.000Z
+Sat Sep 19 1970 00:00:00 GMT+0100 (CET) 22546800000 1970-09-18T23:00:00.000Z
+Sun Sep 20 1970 00:00:00 GMT+0100 (CET) 22633200000 1970-09-19T23:00:00.000Z
+Mon Sep 21 1970 00:00:00 GMT+0100 (CET) 22719600000 1970-09-20T23:00:00.000Z
+Tue Sep 22 1970 00:00:00 GMT+0100 (CET) 22806000000 1970-09-21T23:00:00.000Z
+Wed Sep 23 1970 00:00:00 GMT+0100 (CET) 22892400000 1970-09-22T23:00:00.000Z
+Thu Sep 24 1970 00:00:00 GMT+0100 (CET) 22978800000 1970-09-23T23:00:00.000Z
+Fri Sep 25 1970 00:00:00 GMT+0100 (CET) 23065200000 1970-09-24T23:00:00.000Z
+Sat Sep 26 1970 00:00:00 GMT+0100 (CET) 23151600000 1970-09-25T23:00:00.000Z
+Sun Sep 27 1970 00:00:00 GMT+0100 (CET) 23238000000 1970-09-26T23:00:00.000Z
+Mon Sep 28 1970 00:00:00 GMT+0100 (CET) 23324400000 1970-09-27T23:00:00.000Z
+Tue Sep 29 1970 00:00:00 GMT+0100 (CET) 23410800000 1970-09-28T23:00:00.000Z
+Wed Sep 30 1970 00:00:00 GMT+0100 (CET) 23497200000 1970-09-29T23:00:00.000Z
+Thu Oct 01 1970 00:00:00 GMT+0100 (CET) 23583600000 1970-09-30T23:00:00.000Z
+Fri Oct 02 1970 00:00:00 GMT+0100 (CET) 23670000000 1970-10-01T23:00:00.000Z
+Sat Oct 03 1970 00:00:00 GMT+0100 (CET) 23756400000 1970-10-02T23:00:00.000Z
+Sun Oct 04 1970 00:00:00 GMT+0100 (CET) 23842800000 1970-10-03T23:00:00.000Z
+Mon Oct 05 1970 00:00:00 GMT+0100 (CET) 23929200000 1970-10-04T23:00:00.000Z
+Tue Oct 06 1970 00:00:00 GMT+0100 (CET) 24015600000 1970-10-05T23:00:00.000Z
+Wed Oct 07 1970 00:00:00 GMT+0100 (CET) 24102000000 1970-10-06T23:00:00.000Z
+Thu Oct 08 1970 00:00:00 GMT+0100 (CET) 24188400000 1970-10-07T23:00:00.000Z
+Fri Oct 09 1970 00:00:00 GMT+0100 (CET) 24274800000 1970-10-08T23:00:00.000Z
+Sat Oct 10 1970 00:00:00 GMT+0100 (CET) 24361200000 1970-10-09T23:00:00.000Z
+Sun Oct 11 1970 00:00:00 GMT+0100 (CET) 24447600000 1970-10-10T23:00:00.000Z
+Mon Oct 12 1970 00:00:00 GMT+0100 (CET) 24534000000 1970-10-11T23:00:00.000Z
+Tue Oct 13 1970 00:00:00 GMT+0100 (CET) 24620400000 1970-10-12T23:00:00.000Z
+Wed Oct 14 1970 00:00:00 GMT+0100 (CET) 24706800000 1970-10-13T23:00:00.000Z
+Thu Oct 15 1970 00:00:00 GMT+0100 (CET) 24793200000 1970-10-14T23:00:00.000Z
+Fri Oct 16 1970 00:00:00 GMT+0100 (CET) 24879600000 1970-10-15T23:00:00.000Z
+Sat Oct 17 1970 00:00:00 GMT+0100 (CET) 24966000000 1970-10-16T23:00:00.000Z
+Sun Oct 18 1970 00:00:00 GMT+0100 (CET) 25052400000 1970-10-17T23:00:00.000Z
+Mon Oct 19 1970 00:00:00 GMT+0100 (CET) 25138800000 1970-10-18T23:00:00.000Z
+Tue Oct 20 1970 00:00:00 GMT+0100 (CET) 25225200000 1970-10-19T23:00:00.000Z
+Wed Oct 21 1970 00:00:00 GMT+0100 (CET) 25311600000 1970-10-20T23:00:00.000Z
+Thu Oct 22 1970 00:00:00 GMT+0100 (CET) 25398000000 1970-10-21T23:00:00.000Z
+Fri Oct 23 1970 00:00:00 GMT+0100 (CET) 25484400000 1970-10-22T23:00:00.000Z
+Sat Oct 24 1970 00:00:00 GMT+0100 (CET) 25570800000 1970-10-23T23:00:00.000Z
+Sun Oct 25 1970 00:00:00 GMT+0100 (CET) 25657200000 1970-10-24T23:00:00.000Z
+Mon Oct 26 1970 00:00:00 GMT+0100 (CET) 25743600000 1970-10-25T23:00:00.000Z
+Tue Oct 27 1970 00:00:00 GMT+0100 (CET) 25830000000 1970-10-26T23:00:00.000Z
+Wed Oct 28 1970 00:00:00 GMT+0100 (CET) 25916400000 1970-10-27T23:00:00.000Z
+Thu Oct 29 1970 00:00:00 GMT+0100 (CET) 26002800000 1970-10-28T23:00:00.000Z
+Fri Oct 30 1970 00:00:00 GMT+0100 (CET) 26089200000 1970-10-29T23:00:00.000Z
+Sat Oct 31 1970 00:00:00 GMT+0100 (CET) 26175600000 1970-10-30T23:00:00.000Z
+Sun Nov 01 1970 00:00:00 GMT+0100 (CET) 26262000000 1970-10-31T23:00:00.000Z
+Mon Nov 02 1970 00:00:00 GMT+0100 (CET) 26348400000 1970-11-01T23:00:00.000Z
+Tue Nov 03 1970 00:00:00 GMT+0100 (CET) 26434800000 1970-11-02T23:00:00.000Z
+Wed Nov 04 1970 00:00:00 GMT+0100 (CET) 26521200000 1970-11-03T23:00:00.000Z
+Thu Nov 05 1970 00:00:00 GMT+0100 (CET) 26607600000 1970-11-04T23:00:00.000Z
+Fri Nov 06 1970 00:00:00 GMT+0100 (CET) 26694000000 1970-11-05T23:00:00.000Z
+Sat Nov 07 1970 00:00:00 GMT+0100 (CET) 26780400000 1970-11-06T23:00:00.000Z
+Sun Nov 08 1970 00:00:00 GMT+0100 (CET) 26866800000 1970-11-07T23:00:00.000Z
+Mon Nov 09 1970 00:00:00 GMT+0100 (CET) 26953200000 1970-11-08T23:00:00.000Z
+Tue Nov 10 1970 00:00:00 GMT+0100 (CET) 27039600000 1970-11-09T23:00:00.000Z
+Wed Nov 11 1970 00:00:00 GMT+0100 (CET) 27126000000 1970-11-10T23:00:00.000Z
+Thu Nov 12 1970 00:00:00 GMT+0100 (CET) 27212400000 1970-11-11T23:00:00.000Z
+Fri Nov 13 1970 00:00:00 GMT+0100 (CET) 27298800000 1970-11-12T23:00:00.000Z
+Sat Nov 14 1970 00:00:00 GMT+0100 (CET) 27385200000 1970-11-13T23:00:00.000Z
+Sun Nov 15 1970 00:00:00 GMT+0100 (CET) 27471600000 1970-11-14T23:00:00.000Z
+Mon Nov 16 1970 00:00:00 GMT+0100 (CET) 27558000000 1970-11-15T23:00:00.000Z
+Tue Nov 17 1970 00:00:00 GMT+0100 (CET) 27644400000 1970-11-16T23:00:00.000Z
+Wed Nov 18 1970 00:00:00 GMT+0100 (CET) 27730800000 1970-11-17T23:00:00.000Z
+Thu Nov 19 1970 00:00:00 GMT+0100 (CET) 27817200000 1970-11-18T23:00:00.000Z
+Fri Nov 20 1970 00:00:00 GMT+0100 (CET) 27903600000 1970-11-19T23:00:00.000Z
+Sat Nov 21 1970 00:00:00 GMT+0100 (CET) 27990000000 1970-11-20T23:00:00.000Z
+Sun Nov 22 1970 00:00:00 GMT+0100 (CET) 28076400000 1970-11-21T23:00:00.000Z
+Mon Nov 23 1970 00:00:00 GMT+0100 (CET) 28162800000 1970-11-22T23:00:00.000Z
+Tue Nov 24 1970 00:00:00 GMT+0100 (CET) 28249200000 1970-11-23T23:00:00.000Z
+Wed Nov 25 1970 00:00:00 GMT+0100 (CET) 28335600000 1970-11-24T23:00:00.000Z
+Thu Nov 26 1970 00:00:00 GMT+0100 (CET) 28422000000 1970-11-25T23:00:00.000Z
+Fri Nov 27 1970 00:00:00 GMT+0100 (CET) 28508400000 1970-11-26T23:00:00.000Z
+Sat Nov 28 1970 00:00:00 GMT+0100 (CET) 28594800000 1970-11-27T23:00:00.000Z
+Sun Nov 29 1970 00:00:00 GMT+0100 (CET) 28681200000 1970-11-28T23:00:00.000Z
+Mon Nov 30 1970 00:00:00 GMT+0100 (CET) 28767600000 1970-11-29T23:00:00.000Z
+Tue Dec 01 1970 00:00:00 GMT+0100 (CET) 28854000000 1970-11-30T23:00:00.000Z
+Wed Dec 02 1970 00:00:00 GMT+0100 (CET) 28940400000 1970-12-01T23:00:00.000Z
+Thu Dec 03 1970 00:00:00 GMT+0100 (CET) 29026800000 1970-12-02T23:00:00.000Z
+Fri Dec 04 1970 00:00:00 GMT+0100 (CET) 29113200000 1970-12-03T23:00:00.000Z
+Sat Dec 05 1970 00:00:00 GMT+0100 (CET) 29199600000 1970-12-04T23:00:00.000Z
+Sun Dec 06 1970 00:00:00 GMT+0100 (CET) 29286000000 1970-12-05T23:00:00.000Z
+Mon Dec 07 1970 00:00:00 GMT+0100 (CET) 29372400000 1970-12-06T23:00:00.000Z
+Tue Dec 08 1970 00:00:00 GMT+0100 (CET) 29458800000 1970-12-07T23:00:00.000Z
+Wed Dec 09 1970 00:00:00 GMT+0100 (CET) 29545200000 1970-12-08T23:00:00.000Z
+Thu Dec 10 1970 00:00:00 GMT+0100 (CET) 29631600000 1970-12-09T23:00:00.000Z
+Fri Dec 11 1970 00:00:00 GMT+0100 (CET) 29718000000 1970-12-10T23:00:00.000Z
+Sat Dec 12 1970 00:00:00 GMT+0100 (CET) 29804400000 1970-12-11T23:00:00.000Z
+Sun Dec 13 1970 00:00:00 GMT+0100 (CET) 29890800000 1970-12-12T23:00:00.000Z
+Mon Dec 14 1970 00:00:00 GMT+0100 (CET) 29977200000 1970-12-13T23:00:00.000Z
+Tue Dec 15 1970 00:00:00 GMT+0100 (CET) 30063600000 1970-12-14T23:00:00.000Z
+Wed Dec 16 1970 00:00:00 GMT+0100 (CET) 30150000000 1970-12-15T23:00:00.000Z
+Thu Dec 17 1970 00:00:00 GMT+0100 (CET) 30236400000 1970-12-16T23:00:00.000Z
+Fri Dec 18 1970 00:00:00 GMT+0100 (CET) 30322800000 1970-12-17T23:00:00.000Z
+Sat Dec 19 1970 00:00:00 GMT+0100 (CET) 30409200000 1970-12-18T23:00:00.000Z
+Sun Dec 20 1970 00:00:00 GMT+0100 (CET) 30495600000 1970-12-19T23:00:00.000Z
+Mon Dec 21 1970 00:00:00 GMT+0100 (CET) 30582000000 1970-12-20T23:00:00.000Z
+Tue Dec 22 1970 00:00:00 GMT+0100 (CET) 30668400000 1970-12-21T23:00:00.000Z
+Wed Dec 23 1970 00:00:00 GMT+0100 (CET) 30754800000 1970-12-22T23:00:00.000Z
+Thu Dec 24 1970 00:00:00 GMT+0100 (CET) 30841200000 1970-12-23T23:00:00.000Z
+Fri Dec 25 1970 00:00:00 GMT+0100 (CET) 30927600000 1970-12-24T23:00:00.000Z
+Sat Dec 26 1970 00:00:00 GMT+0100 (CET) 31014000000 1970-12-25T23:00:00.000Z
+Sun Dec 27 1970 00:00:00 GMT+0100 (CET) 31100400000 1970-12-26T23:00:00.000Z
+Mon Dec 28 1970 00:00:00 GMT+0100 (CET) 31186800000 1970-12-27T23:00:00.000Z
+Tue Dec 29 1970 00:00:00 GMT+0100 (CET) 31273200000 1970-12-28T23:00:00.000Z
+Wed Dec 30 1970 00:00:00 GMT+0100 (CET) 31359600000 1970-12-29T23:00:00.000Z
+Thu Dec 31 1970 00:00:00 GMT+0100 (CET) 31446000000 1970-12-30T23:00:00.000Z
+Fri Jan 01 1971 00:00:00 GMT+0100 (CET) 31532400000 1970-12-31T23:00:00.000Z
+Sat Jan 02 1971 00:00:00 GMT+0100 (CET) 31618800000 1971-01-01T23:00:00.000Z
+Sun Jan 03 1971 00:00:00 GMT+0100 (CET) 31705200000 1971-01-02T23:00:00.000Z
+Mon Jan 04 1971 00:00:00 GMT+0100 (CET) 31791600000 1971-01-03T23:00:00.000Z
+Tue Jan 05 1971 00:00:00 GMT+0100 (CET) 31878000000 1971-01-04T23:00:00.000Z
+Wed Jan 06 1971 00:00:00 GMT+0100 (CET) 31964400000 1971-01-05T23:00:00.000Z
+Thu Jan 07 1971 00:00:00 GMT+0100 (CET) 32050800000 1971-01-06T23:00:00.000Z
+Fri Jan 08 1971 00:00:00 GMT+0100 (CET) 32137200000 1971-01-07T23:00:00.000Z
+Sat Jan 09 1971 00:00:00 GMT+0100 (CET) 32223600000 1971-01-08T23:00:00.000Z
+Sun Jan 10 1971 00:00:00 GMT+0100 (CET) 32310000000 1971-01-09T23:00:00.000Z
+Mon Jan 11 1971 00:00:00 GMT+0100 (CET) 32396400000 1971-01-10T23:00:00.000Z
+Tue Jan 12 1971 00:00:00 GMT+0100 (CET) 32482800000 1971-01-11T23:00:00.000Z
+Wed Jan 13 1971 00:00:00 GMT+0100 (CET) 32569200000 1971-01-12T23:00:00.000Z
+Thu Jan 14 1971 00:00:00 GMT+0100 (CET) 32655600000 1971-01-13T23:00:00.000Z
+Tue Dec 21 2010 17:00:59 GMT+0100 (CET) 1292947259000 2010-12-21T16:00:59.000Z
+Wed Dec 22 2010 17:00:59 GMT+0100 (CET) 1293033659000 2010-12-22T16:00:59.000Z
+Thu Dec 23 2010 17:00:59 GMT+0100 (CET) 1293120059000 2010-12-23T16:00:59.000Z
+Fri Dec 24 2010 17:00:59 GMT+0100 (CET) 1293206459000 2010-12-24T16:00:59.000Z
+Sat Dec 25 2010 17:00:59 GMT+0100 (CET) 1293292859000 2010-12-25T16:00:59.000Z
+Sun Dec 26 2010 17:00:59 GMT+0100 (CET) 1293379259000 2010-12-26T16:00:59.000Z
+Mon Dec 27 2010 17:00:59 GMT+0100 (CET) 1293465659000 2010-12-27T16:00:59.000Z
+Tue Dec 28 2010 17:00:59 GMT+0100 (CET) 1293552059000 2010-12-28T16:00:59.000Z
+Wed Dec 29 2010 17:00:59 GMT+0100 (CET) 1293638459000 2010-12-29T16:00:59.000Z
+Thu Dec 30 2010 17:00:59 GMT+0100 (CET) 1293724859000 2010-12-30T16:00:59.000Z
+Fri Dec 31 2010 17:00:59 GMT+0100 (CET) 1293811259000 2010-12-31T16:00:59.000Z
+Sat Jan 01 2011 17:00:59 GMT+0100 (CET) 1293897659000 2011-01-01T16:00:59.000Z
+Sun Jan 02 2011 17:00:59 GMT+0100 (CET) 1293984059000 2011-01-02T16:00:59.000Z
+Mon Jan 03 2011 17:00:59 GMT+0100 (CET) 1294070459000 2011-01-03T16:00:59.000Z
+Tue Jan 04 2011 17:00:59 GMT+0100 (CET) 1294156859000 2011-01-04T16:00:59.000Z
+Wed Jan 05 2011 17:00:59 GMT+0100 (CET) 1294243259000 2011-01-05T16:00:59.000Z
+Thu Jan 06 2011 17:00:59 GMT+0100 (CET) 1294329659000 2011-01-06T16:00:59.000Z
+Fri Jan 07 2011 17:00:59 GMT+0100 (CET) 1294416059000 2011-01-07T16:00:59.000Z
+Sat Jan 08 2011 17:00:59 GMT+0100 (CET) 1294502459000 2011-01-08T16:00:59.000Z
+Sun Jan 09 2011 17:00:59 GMT+0100 (CET) 1294588859000 2011-01-09T16:00:59.000Z
+Mon Jan 10 2011 17:00:59 GMT+0100 (CET) 1294675259000 2011-01-10T16:00:59.000Z
+Tue Jan 11 2011 17:00:59 GMT+0100 (CET) 1294761659000 2011-01-11T16:00:59.000Z
+Wed Jan 12 2011 17:00:59 GMT+0100 (CET) 1294848059000 2011-01-12T16:00:59.000Z
+Thu Jan 13 2011 17:00:59 GMT+0100 (CET) 1294934459000 2011-01-13T16:00:59.000Z
+Fri Jan 14 2011 17:00:59 GMT+0100 (CET) 1295020859000 2011-01-14T16:00:59.000Z
+Sat Jan 15 2011 17:00:59 GMT+0100 (CET) 1295107259000 2011-01-15T16:00:59.000Z
+Sun Jan 16 2011 17:00:59 GMT+0100 (CET) 1295193659000 2011-01-16T16:00:59.000Z
+Mon Jan 17 2011 17:00:59 GMT+0100 (CET) 1295280059000 2011-01-17T16:00:59.000Z
+Tue Jan 18 2011 17:00:59 GMT+0100 (CET) 1295366459000 2011-01-18T16:00:59.000Z
+Wed Jan 19 2011 17:00:59 GMT+0100 (CET) 1295452859000 2011-01-19T16:00:59.000Z
+Thu Jan 20 2011 17:00:59 GMT+0100 (CET) 1295539259000 2011-01-20T16:00:59.000Z
+Fri Jan 21 2011 17:00:59 GMT+0100 (CET) 1295625659000 2011-01-21T16:00:59.000Z
+Sat Jan 22 2011 17:00:59 GMT+0100 (CET) 1295712059000 2011-01-22T16:00:59.000Z
+Sun Jan 23 2011 17:00:59 GMT+0100 (CET) 1295798459000 2011-01-23T16:00:59.000Z
+Mon Jan 24 2011 17:00:59 GMT+0100 (CET) 1295884859000 2011-01-24T16:00:59.000Z
+Tue Jan 25 2011 17:00:59 GMT+0100 (CET) 1295971259000 2011-01-25T16:00:59.000Z
+Wed Jan 26 2011 17:00:59 GMT+0100 (CET) 1296057659000 2011-01-26T16:00:59.000Z
+Thu Jan 27 2011 17:00:59 GMT+0100 (CET) 1296144059000 2011-01-27T16:00:59.000Z
+Fri Jan 28 2011 17:00:59 GMT+0100 (CET) 1296230459000 2011-01-28T16:00:59.000Z
+Sat Jan 29 2011 17:00:59 GMT+0100 (CET) 1296316859000 2011-01-29T16:00:59.000Z
+Sun Jan 30 2011 17:00:59 GMT+0100 (CET) 1296403259000 2011-01-30T16:00:59.000Z
+Mon Jan 31 2011 17:00:59 GMT+0100 (CET) 1296489659000 2011-01-31T16:00:59.000Z
+Tue Feb 01 2011 17:00:59 GMT+0100 (CET) 1296576059000 2011-02-01T16:00:59.000Z
+Wed Feb 02 2011 17:00:59 GMT+0100 (CET) 1296662459000 2011-02-02T16:00:59.000Z
+Thu Feb 03 2011 17:00:59 GMT+0100 (CET) 1296748859000 2011-02-03T16:00:59.000Z
+Fri Feb 04 2011 17:00:59 GMT+0100 (CET) 1296835259000 2011-02-04T16:00:59.000Z
+Sat Feb 05 2011 17:00:59 GMT+0100 (CET) 1296921659000 2011-02-05T16:00:59.000Z
+Sun Feb 06 2011 17:00:59 GMT+0100 (CET) 1297008059000 2011-02-06T16:00:59.000Z
+Mon Feb 07 2011 17:00:59 GMT+0100 (CET) 1297094459000 2011-02-07T16:00:59.000Z
+Tue Feb 08 2011 17:00:59 GMT+0100 (CET) 1297180859000 2011-02-08T16:00:59.000Z
+Wed Feb 09 2011 17:00:59 GMT+0100 (CET) 1297267259000 2011-02-09T16:00:59.000Z
+Thu Feb 10 2011 17:00:59 GMT+0100 (CET) 1297353659000 2011-02-10T16:00:59.000Z
+Fri Feb 11 2011 17:00:59 GMT+0100 (CET) 1297440059000 2011-02-11T16:00:59.000Z
+Sat Feb 12 2011 17:00:59 GMT+0100 (CET) 1297526459000 2011-02-12T16:00:59.000Z
+Sun Feb 13 2011 17:00:59 GMT+0100 (CET) 1297612859000 2011-02-13T16:00:59.000Z
+Mon Feb 14 2011 17:00:59 GMT+0100 (CET) 1297699259000 2011-02-14T16:00:59.000Z
+Tue Feb 15 2011 17:00:59 GMT+0100 (CET) 1297785659000 2011-02-15T16:00:59.000Z
+Wed Feb 16 2011 17:00:59 GMT+0100 (CET) 1297872059000 2011-02-16T16:00:59.000Z
+Thu Feb 17 2011 17:00:59 GMT+0100 (CET) 1297958459000 2011-02-17T16:00:59.000Z
+Fri Feb 18 2011 17:00:59 GMT+0100 (CET) 1298044859000 2011-02-18T16:00:59.000Z
+Sat Feb 19 2011 17:00:59 GMT+0100 (CET) 1298131259000 2011-02-19T16:00:59.000Z
+Sun Feb 20 2011 17:00:59 GMT+0100 (CET) 1298217659000 2011-02-20T16:00:59.000Z
+Mon Feb 21 2011 17:00:59 GMT+0100 (CET) 1298304059000 2011-02-21T16:00:59.000Z
+Tue Feb 22 2011 17:00:59 GMT+0100 (CET) 1298390459000 2011-02-22T16:00:59.000Z
+Wed Feb 23 2011 17:00:59 GMT+0100 (CET) 1298476859000 2011-02-23T16:00:59.000Z
+Thu Feb 24 2011 17:00:59 GMT+0100 (CET) 1298563259000 2011-02-24T16:00:59.000Z
+Fri Feb 25 2011 17:00:59 GMT+0100 (CET) 1298649659000 2011-02-25T16:00:59.000Z
+Sat Feb 26 2011 17:00:59 GMT+0100 (CET) 1298736059000 2011-02-26T16:00:59.000Z
+Sun Feb 27 2011 17:00:59 GMT+0100 (CET) 1298822459000 2011-02-27T16:00:59.000Z
+Mon Feb 28 2011 17:00:59 GMT+0100 (CET) 1298908859000 2011-02-28T16:00:59.000Z
+Tue Mar 01 2011 17:00:59 GMT+0100 (CET) 1298995259000 2011-03-01T16:00:59.000Z
+Wed Mar 02 2011 17:00:59 GMT+0100 (CET) 1299081659000 2011-03-02T16:00:59.000Z
+Thu Mar 03 2011 17:00:59 GMT+0100 (CET) 1299168059000 2011-03-03T16:00:59.000Z
+Fri Mar 04 2011 17:00:59 GMT+0100 (CET) 1299254459000 2011-03-04T16:00:59.000Z
+Sat Mar 05 2011 17:00:59 GMT+0100 (CET) 1299340859000 2011-03-05T16:00:59.000Z
+Sun Mar 06 2011 17:00:59 GMT+0100 (CET) 1299427259000 2011-03-06T16:00:59.000Z
+Mon Mar 07 2011 17:00:59 GMT+0100 (CET) 1299513659000 2011-03-07T16:00:59.000Z
+Tue Mar 08 2011 17:00:59 GMT+0100 (CET) 1299600059000 2011-03-08T16:00:59.000Z
+Wed Mar 09 2011 17:00:59 GMT+0100 (CET) 1299686459000 2011-03-09T16:00:59.000Z
+Thu Mar 10 2011 17:00:59 GMT+0100 (CET) 1299772859000 2011-03-10T16:00:59.000Z
+Fri Mar 11 2011 17:00:59 GMT+0100 (CET) 1299859259000 2011-03-11T16:00:59.000Z
+Sat Mar 12 2011 17:00:59 GMT+0100 (CET) 1299945659000 2011-03-12T16:00:59.000Z
+Sun Mar 13 2011 17:00:59 GMT+0100 (CET) 1300032059000 2011-03-13T16:00:59.000Z
+Mon Mar 14 2011 17:00:59 GMT+0100 (CET) 1300118459000 2011-03-14T16:00:59.000Z
+Tue Mar 15 2011 17:00:59 GMT+0100 (CET) 1300204859000 2011-03-15T16:00:59.000Z
+Wed Mar 16 2011 17:00:59 GMT+0100 (CET) 1300291259000 2011-03-16T16:00:59.000Z
+Thu Mar 17 2011 17:00:59 GMT+0100 (CET) 1300377659000 2011-03-17T16:00:59.000Z
+Fri Mar 18 2011 17:00:59 GMT+0100 (CET) 1300464059000 2011-03-18T16:00:59.000Z
+Sat Mar 19 2011 17:00:59 GMT+0100 (CET) 1300550459000 2011-03-19T16:00:59.000Z
+Sun Mar 20 2011 17:00:59 GMT+0100 (CET) 1300636859000 2011-03-20T16:00:59.000Z
+Mon Mar 21 2011 17:00:59 GMT+0100 (CET) 1300723259000 2011-03-21T16:00:59.000Z
+Tue Mar 22 2011 17:00:59 GMT+0100 (CET) 1300809659000 2011-03-22T16:00:59.000Z
+Wed Mar 23 2011 17:00:59 GMT+0100 (CET) 1300896059000 2011-03-23T16:00:59.000Z
+Thu Mar 24 2011 17:00:59 GMT+0100 (CET) 1300982459000 2011-03-24T16:00:59.000Z
+Fri Mar 25 2011 17:00:59 GMT+0100 (CET) 1301068859000 2011-03-25T16:00:59.000Z
+Sat Mar 26 2011 17:00:59 GMT+0100 (CET) 1301155259000 2011-03-26T16:00:59.000Z
+Sun Mar 27 2011 17:00:59 GMT+0200 (CEST) 1301238059000 2011-03-27T15:00:59.000Z
+Mon Mar 28 2011 17:00:59 GMT+0200 (CEST) 1301324459000 2011-03-28T15:00:59.000Z
+Tue Mar 29 2011 17:00:59 GMT+0200 (CEST) 1301410859000 2011-03-29T15:00:59.000Z
+Wed Mar 30 2011 17:00:59 GMT+0200 (CEST) 1301497259000 2011-03-30T15:00:59.000Z
+Thu Mar 31 2011 17:00:59 GMT+0200 (CEST) 1301583659000 2011-03-31T15:00:59.000Z
+Fri Apr 01 2011 17:00:59 GMT+0200 (CEST) 1301670059000 2011-04-01T15:00:59.000Z
+Sat Apr 02 2011 17:00:59 GMT+0200 (CEST) 1301756459000 2011-04-02T15:00:59.000Z
+Sun Apr 03 2011 17:00:59 GMT+0200 (CEST) 1301842859000 2011-04-03T15:00:59.000Z
+Mon Apr 04 2011 17:00:59 GMT+0200 (CEST) 1301929259000 2011-04-04T15:00:59.000Z
+Tue Apr 05 2011 17:00:59 GMT+0200 (CEST) 1302015659000 2011-04-05T15:00:59.000Z
+Wed Apr 06 2011 17:00:59 GMT+0200 (CEST) 1302102059000 2011-04-06T15:00:59.000Z
+Thu Apr 07 2011 17:00:59 GMT+0200 (CEST) 1302188459000 2011-04-07T15:00:59.000Z
+Fri Apr 08 2011 17:00:59 GMT+0200 (CEST) 1302274859000 2011-04-08T15:00:59.000Z
+Sat Apr 09 2011 17:00:59 GMT+0200 (CEST) 1302361259000 2011-04-09T15:00:59.000Z
+Sun Apr 10 2011 17:00:59 GMT+0200 (CEST) 1302447659000 2011-04-10T15:00:59.000Z
+Mon Apr 11 2011 17:00:59 GMT+0200 (CEST) 1302534059000 2011-04-11T15:00:59.000Z
+Tue Apr 12 2011 17:00:59 GMT+0200 (CEST) 1302620459000 2011-04-12T15:00:59.000Z
+Wed Apr 13 2011 17:00:59 GMT+0200 (CEST) 1302706859000 2011-04-13T15:00:59.000Z
+Thu Apr 14 2011 17:00:59 GMT+0200 (CEST) 1302793259000 2011-04-14T15:00:59.000Z
+Fri Apr 15 2011 17:00:59 GMT+0200 (CEST) 1302879659000 2011-04-15T15:00:59.000Z
+Sat Apr 16 2011 17:00:59 GMT+0200 (CEST) 1302966059000 2011-04-16T15:00:59.000Z
+Sun Apr 17 2011 17:00:59 GMT+0200 (CEST) 1303052459000 2011-04-17T15:00:59.000Z
+Mon Apr 18 2011 17:00:59 GMT+0200 (CEST) 1303138859000 2011-04-18T15:00:59.000Z
+Tue Apr 19 2011 17:00:59 GMT+0200 (CEST) 1303225259000 2011-04-19T15:00:59.000Z
+Wed Apr 20 2011 17:00:59 GMT+0200 (CEST) 1303311659000 2011-04-20T15:00:59.000Z
+Thu Apr 21 2011 17:00:59 GMT+0200 (CEST) 1303398059000 2011-04-21T15:00:59.000Z
+Fri Apr 22 2011 17:00:59 GMT+0200 (CEST) 1303484459000 2011-04-22T15:00:59.000Z
+Sat Apr 23 2011 17:00:59 GMT+0200 (CEST) 1303570859000 2011-04-23T15:00:59.000Z
+Sun Apr 24 2011 17:00:59 GMT+0200 (CEST) 1303657259000 2011-04-24T15:00:59.000Z
+Mon Apr 25 2011 17:00:59 GMT+0200 (CEST) 1303743659000 2011-04-25T15:00:59.000Z
+Tue Apr 26 2011 17:00:59 GMT+0200 (CEST) 1303830059000 2011-04-26T15:00:59.000Z
+Wed Apr 27 2011 17:00:59 GMT+0200 (CEST) 1303916459000 2011-04-27T15:00:59.000Z
+Thu Apr 28 2011 17:00:59 GMT+0200 (CEST) 1304002859000 2011-04-28T15:00:59.000Z
+Fri Apr 29 2011 17:00:59 GMT+0200 (CEST) 1304089259000 2011-04-29T15:00:59.000Z
+Sat Apr 30 2011 17:00:59 GMT+0200 (CEST) 1304175659000 2011-04-30T15:00:59.000Z
+Sun May 01 2011 17:00:59 GMT+0200 (CEST) 1304262059000 2011-05-01T15:00:59.000Z
+Mon May 02 2011 17:00:59 GMT+0200 (CEST) 1304348459000 2011-05-02T15:00:59.000Z
+Tue May 03 2011 17:00:59 GMT+0200 (CEST) 1304434859000 2011-05-03T15:00:59.000Z
+Wed May 04 2011 17:00:59 GMT+0200 (CEST) 1304521259000 2011-05-04T15:00:59.000Z
+Thu May 05 2011 17:00:59 GMT+0200 (CEST) 1304607659000 2011-05-05T15:00:59.000Z
+Fri May 06 2011 17:00:59 GMT+0200 (CEST) 1304694059000 2011-05-06T15:00:59.000Z
+Sat May 07 2011 17:00:59 GMT+0200 (CEST) 1304780459000 2011-05-07T15:00:59.000Z
+Sun May 08 2011 17:00:59 GMT+0200 (CEST) 1304866859000 2011-05-08T15:00:59.000Z
+Mon May 09 2011 17:00:59 GMT+0200 (CEST) 1304953259000 2011-05-09T15:00:59.000Z
+Tue May 10 2011 17:00:59 GMT+0200 (CEST) 1305039659000 2011-05-10T15:00:59.000Z
+Wed May 11 2011 17:00:59 GMT+0200 (CEST) 1305126059000 2011-05-11T15:00:59.000Z
+Thu May 12 2011 17:00:59 GMT+0200 (CEST) 1305212459000 2011-05-12T15:00:59.000Z
+Fri May 13 2011 17:00:59 GMT+0200 (CEST) 1305298859000 2011-05-13T15:00:59.000Z
+Sat May 14 2011 17:00:59 GMT+0200 (CEST) 1305385259000 2011-05-14T15:00:59.000Z
+Sun May 15 2011 17:00:59 GMT+0200 (CEST) 1305471659000 2011-05-15T15:00:59.000Z
+Mon May 16 2011 17:00:59 GMT+0200 (CEST) 1305558059000 2011-05-16T15:00:59.000Z
+Tue May 17 2011 17:00:59 GMT+0200 (CEST) 1305644459000 2011-05-17T15:00:59.000Z
+Wed May 18 2011 17:00:59 GMT+0200 (CEST) 1305730859000 2011-05-18T15:00:59.000Z
+Thu May 19 2011 17:00:59 GMT+0200 (CEST) 1305817259000 2011-05-19T15:00:59.000Z
+Fri May 20 2011 17:00:59 GMT+0200 (CEST) 1305903659000 2011-05-20T15:00:59.000Z
+Sat May 21 2011 17:00:59 GMT+0200 (CEST) 1305990059000 2011-05-21T15:00:59.000Z
+Sun May 22 2011 17:00:59 GMT+0200 (CEST) 1306076459000 2011-05-22T15:00:59.000Z
+Mon May 23 2011 17:00:59 GMT+0200 (CEST) 1306162859000 2011-05-23T15:00:59.000Z
+Tue May 24 2011 17:00:59 GMT+0200 (CEST) 1306249259000 2011-05-24T15:00:59.000Z
+Wed May 25 2011 17:00:59 GMT+0200 (CEST) 1306335659000 2011-05-25T15:00:59.000Z
+Thu May 26 2011 17:00:59 GMT+0200 (CEST) 1306422059000 2011-05-26T15:00:59.000Z
+Fri May 27 2011 17:00:59 GMT+0200 (CEST) 1306508459000 2011-05-27T15:00:59.000Z
+Sat May 28 2011 17:00:59 GMT+0200 (CEST) 1306594859000 2011-05-28T15:00:59.000Z
+Sun May 29 2011 17:00:59 GMT+0200 (CEST) 1306681259000 2011-05-29T15:00:59.000Z
+Mon May 30 2011 17:00:59 GMT+0200 (CEST) 1306767659000 2011-05-30T15:00:59.000Z
+Tue May 31 2011 17:00:59 GMT+0200 (CEST) 1306854059000 2011-05-31T15:00:59.000Z
+Wed Jun 01 2011 17:00:59 GMT+0200 (CEST) 1306940459000 2011-06-01T15:00:59.000Z
+Thu Jun 02 2011 17:00:59 GMT+0200 (CEST) 1307026859000 2011-06-02T15:00:59.000Z
+Fri Jun 03 2011 17:00:59 GMT+0200 (CEST) 1307113259000 2011-06-03T15:00:59.000Z
+Sat Jun 04 2011 17:00:59 GMT+0200 (CEST) 1307199659000 2011-06-04T15:00:59.000Z
+Sun Jun 05 2011 17:00:59 GMT+0200 (CEST) 1307286059000 2011-06-05T15:00:59.000Z
+Mon Jun 06 2011 17:00:59 GMT+0200 (CEST) 1307372459000 2011-06-06T15:00:59.000Z
+Tue Jun 07 2011 17:00:59 GMT+0200 (CEST) 1307458859000 2011-06-07T15:00:59.000Z
+Wed Jun 08 2011 17:00:59 GMT+0200 (CEST) 1307545259000 2011-06-08T15:00:59.000Z
+Thu Jun 09 2011 17:00:59 GMT+0200 (CEST) 1307631659000 2011-06-09T15:00:59.000Z
+Fri Jun 10 2011 17:00:59 GMT+0200 (CEST) 1307718059000 2011-06-10T15:00:59.000Z
+Sat Jun 11 2011 17:00:59 GMT+0200 (CEST) 1307804459000 2011-06-11T15:00:59.000Z
+Sun Jun 12 2011 17:00:59 GMT+0200 (CEST) 1307890859000 2011-06-12T15:00:59.000Z
+Mon Jun 13 2011 17:00:59 GMT+0200 (CEST) 1307977259000 2011-06-13T15:00:59.000Z
+Tue Jun 14 2011 17:00:59 GMT+0200 (CEST) 1308063659000 2011-06-14T15:00:59.000Z
+Wed Jun 15 2011 17:00:59 GMT+0200 (CEST) 1308150059000 2011-06-15T15:00:59.000Z
+Thu Jun 16 2011 17:00:59 GMT+0200 (CEST) 1308236459000 2011-06-16T15:00:59.000Z
+Fri Jun 17 2011 17:00:59 GMT+0200 (CEST) 1308322859000 2011-06-17T15:00:59.000Z
+Sat Jun 18 2011 17:00:59 GMT+0200 (CEST) 1308409259000 2011-06-18T15:00:59.000Z
+Sun Jun 19 2011 17:00:59 GMT+0200 (CEST) 1308495659000 2011-06-19T15:00:59.000Z
+Mon Jun 20 2011 17:00:59 GMT+0200 (CEST) 1308582059000 2011-06-20T15:00:59.000Z
+Tue Jun 21 2011 17:00:59 GMT+0200 (CEST) 1308668459000 2011-06-21T15:00:59.000Z
+Wed Jun 22 2011 17:00:59 GMT+0200 (CEST) 1308754859000 2011-06-22T15:00:59.000Z
+Thu Jun 23 2011 17:00:59 GMT+0200 (CEST) 1308841259000 2011-06-23T15:00:59.000Z
+Fri Jun 24 2011 17:00:59 GMT+0200 (CEST) 1308927659000 2011-06-24T15:00:59.000Z
+Sat Jun 25 2011 17:00:59 GMT+0200 (CEST) 1309014059000 2011-06-25T15:00:59.000Z
+Sun Jun 26 2011 17:00:59 GMT+0200 (CEST) 1309100459000 2011-06-26T15:00:59.000Z
+Mon Jun 27 2011 17:00:59 GMT+0200 (CEST) 1309186859000 2011-06-27T15:00:59.000Z
+Tue Jun 28 2011 17:00:59 GMT+0200 (CEST) 1309273259000 2011-06-28T15:00:59.000Z
+Wed Jun 29 2011 17:00:59 GMT+0200 (CEST) 1309359659000 2011-06-29T15:00:59.000Z
+Thu Jun 30 2011 17:00:59 GMT+0200 (CEST) 1309446059000 2011-06-30T15:00:59.000Z
+Fri Jul 01 2011 17:00:59 GMT+0200 (CEST) 1309532459000 2011-07-01T15:00:59.000Z
+Sat Jul 02 2011 17:00:59 GMT+0200 (CEST) 1309618859000 2011-07-02T15:00:59.000Z
+Sun Jul 03 2011 17:00:59 GMT+0200 (CEST) 1309705259000 2011-07-03T15:00:59.000Z
+Mon Jul 04 2011 17:00:59 GMT+0200 (CEST) 1309791659000 2011-07-04T15:00:59.000Z
+Tue Jul 05 2011 17:00:59 GMT+0200 (CEST) 1309878059000 2011-07-05T15:00:59.000Z
+Wed Jul 06 2011 17:00:59 GMT+0200 (CEST) 1309964459000 2011-07-06T15:00:59.000Z
+Thu Jul 07 2011 17:00:59 GMT+0200 (CEST) 1310050859000 2011-07-07T15:00:59.000Z
+Fri Jul 08 2011 17:00:59 GMT+0200 (CEST) 1310137259000 2011-07-08T15:00:59.000Z
+Sat Jul 09 2011 17:00:59 GMT+0200 (CEST) 1310223659000 2011-07-09T15:00:59.000Z
+Sun Jul 10 2011 17:00:59 GMT+0200 (CEST) 1310310059000 2011-07-10T15:00:59.000Z
+Mon Jul 11 2011 17:00:59 GMT+0200 (CEST) 1310396459000 2011-07-11T15:00:59.000Z
+Tue Jul 12 2011 17:00:59 GMT+0200 (CEST) 1310482859000 2011-07-12T15:00:59.000Z
+Wed Jul 13 2011 17:00:59 GMT+0200 (CEST) 1310569259000 2011-07-13T15:00:59.000Z
+Thu Jul 14 2011 17:00:59 GMT+0200 (CEST) 1310655659000 2011-07-14T15:00:59.000Z
+Fri Jul 15 2011 17:00:59 GMT+0200 (CEST) 1310742059000 2011-07-15T15:00:59.000Z
+Sat Jul 16 2011 17:00:59 GMT+0200 (CEST) 1310828459000 2011-07-16T15:00:59.000Z
+Sun Jul 17 2011 17:00:59 GMT+0200 (CEST) 1310914859000 2011-07-17T15:00:59.000Z
+Mon Jul 18 2011 17:00:59 GMT+0200 (CEST) 1311001259000 2011-07-18T15:00:59.000Z
+Tue Jul 19 2011 17:00:59 GMT+0200 (CEST) 1311087659000 2011-07-19T15:00:59.000Z
+Wed Jul 20 2011 17:00:59 GMT+0200 (CEST) 1311174059000 2011-07-20T15:00:59.000Z
+Thu Jul 21 2011 17:00:59 GMT+0200 (CEST) 1311260459000 2011-07-21T15:00:59.000Z
+Fri Jul 22 2011 17:00:59 GMT+0200 (CEST) 1311346859000 2011-07-22T15:00:59.000Z
+Sat Jul 23 2011 17:00:59 GMT+0200 (CEST) 1311433259000 2011-07-23T15:00:59.000Z
+Sun Jul 24 2011 17:00:59 GMT+0200 (CEST) 1311519659000 2011-07-24T15:00:59.000Z
+Mon Jul 25 2011 17:00:59 GMT+0200 (CEST) 1311606059000 2011-07-25T15:00:59.000Z
+Tue Jul 26 2011 17:00:59 GMT+0200 (CEST) 1311692459000 2011-07-26T15:00:59.000Z
+Wed Jul 27 2011 17:00:59 GMT+0200 (CEST) 1311778859000 2011-07-27T15:00:59.000Z
+Thu Jul 28 2011 17:00:59 GMT+0200 (CEST) 1311865259000 2011-07-28T15:00:59.000Z
+Fri Jul 29 2011 17:00:59 GMT+0200 (CEST) 1311951659000 2011-07-29T15:00:59.000Z
+Sat Jul 30 2011 17:00:59 GMT+0200 (CEST) 1312038059000 2011-07-30T15:00:59.000Z
+Sun Jul 31 2011 17:00:59 GMT+0200 (CEST) 1312124459000 2011-07-31T15:00:59.000Z
+Mon Aug 01 2011 17:00:59 GMT+0200 (CEST) 1312210859000 2011-08-01T15:00:59.000Z
+Tue Aug 02 2011 17:00:59 GMT+0200 (CEST) 1312297259000 2011-08-02T15:00:59.000Z
+Wed Aug 03 2011 17:00:59 GMT+0200 (CEST) 1312383659000 2011-08-03T15:00:59.000Z
+Thu Aug 04 2011 17:00:59 GMT+0200 (CEST) 1312470059000 2011-08-04T15:00:59.000Z
+Fri Aug 05 2011 17:00:59 GMT+0200 (CEST) 1312556459000 2011-08-05T15:00:59.000Z
+Sat Aug 06 2011 17:00:59 GMT+0200 (CEST) 1312642859000 2011-08-06T15:00:59.000Z
+Sun Aug 07 2011 17:00:59 GMT+0200 (CEST) 1312729259000 2011-08-07T15:00:59.000Z
+Mon Aug 08 2011 17:00:59 GMT+0200 (CEST) 1312815659000 2011-08-08T15:00:59.000Z
+Tue Aug 09 2011 17:00:59 GMT+0200 (CEST) 1312902059000 2011-08-09T15:00:59.000Z
+Wed Aug 10 2011 17:00:59 GMT+0200 (CEST) 1312988459000 2011-08-10T15:00:59.000Z
+Thu Aug 11 2011 17:00:59 GMT+0200 (CEST) 1313074859000 2011-08-11T15:00:59.000Z
+Fri Aug 12 2011 17:00:59 GMT+0200 (CEST) 1313161259000 2011-08-12T15:00:59.000Z
+Sat Aug 13 2011 17:00:59 GMT+0200 (CEST) 1313247659000 2011-08-13T15:00:59.000Z
+Sun Aug 14 2011 17:00:59 GMT+0200 (CEST) 1313334059000 2011-08-14T15:00:59.000Z
+Mon Aug 15 2011 17:00:59 GMT+0200 (CEST) 1313420459000 2011-08-15T15:00:59.000Z
+Tue Aug 16 2011 17:00:59 GMT+0200 (CEST) 1313506859000 2011-08-16T15:00:59.000Z
+Wed Aug 17 2011 17:00:59 GMT+0200 (CEST) 1313593259000 2011-08-17T15:00:59.000Z
+Thu Aug 18 2011 17:00:59 GMT+0200 (CEST) 1313679659000 2011-08-18T15:00:59.000Z
+Fri Aug 19 2011 17:00:59 GMT+0200 (CEST) 1313766059000 2011-08-19T15:00:59.000Z
+Sat Aug 20 2011 17:00:59 GMT+0200 (CEST) 1313852459000 2011-08-20T15:00:59.000Z
+Sun Aug 21 2011 17:00:59 GMT+0200 (CEST) 1313938859000 2011-08-21T15:00:59.000Z
+Mon Aug 22 2011 17:00:59 GMT+0200 (CEST) 1314025259000 2011-08-22T15:00:59.000Z
+Tue Aug 23 2011 17:00:59 GMT+0200 (CEST) 1314111659000 2011-08-23T15:00:59.000Z
+Wed Aug 24 2011 17:00:59 GMT+0200 (CEST) 1314198059000 2011-08-24T15:00:59.000Z
+Thu Aug 25 2011 17:00:59 GMT+0200 (CEST) 1314284459000 2011-08-25T15:00:59.000Z
+Fri Aug 26 2011 17:00:59 GMT+0200 (CEST) 1314370859000 2011-08-26T15:00:59.000Z
+Sat Aug 27 2011 17:00:59 GMT+0200 (CEST) 1314457259000 2011-08-27T15:00:59.000Z
+Sun Aug 28 2011 17:00:59 GMT+0200 (CEST) 1314543659000 2011-08-28T15:00:59.000Z
+Mon Aug 29 2011 17:00:59 GMT+0200 (CEST) 1314630059000 2011-08-29T15:00:59.000Z
+Tue Aug 30 2011 17:00:59 GMT+0200 (CEST) 1314716459000 2011-08-30T15:00:59.000Z
+Wed Aug 31 2011 17:00:59 GMT+0200 (CEST) 1314802859000 2011-08-31T15:00:59.000Z
+Thu Sep 01 2011 17:00:59 GMT+0200 (CEST) 1314889259000 2011-09-01T15:00:59.000Z
+Fri Sep 02 2011 17:00:59 GMT+0200 (CEST) 1314975659000 2011-09-02T15:00:59.000Z
+Sat Sep 03 2011 17:00:59 GMT+0200 (CEST) 1315062059000 2011-09-03T15:00:59.000Z
+Sun Sep 04 2011 17:00:59 GMT+0200 (CEST) 1315148459000 2011-09-04T15:00:59.000Z
+Mon Sep 05 2011 17:00:59 GMT+0200 (CEST) 1315234859000 2011-09-05T15:00:59.000Z
+Tue Sep 06 2011 17:00:59 GMT+0200 (CEST) 1315321259000 2011-09-06T15:00:59.000Z
+Wed Sep 07 2011 17:00:59 GMT+0200 (CEST) 1315407659000 2011-09-07T15:00:59.000Z
+Thu Sep 08 2011 17:00:59 GMT+0200 (CEST) 1315494059000 2011-09-08T15:00:59.000Z
+Fri Sep 09 2011 17:00:59 GMT+0200 (CEST) 1315580459000 2011-09-09T15:00:59.000Z
+Sat Sep 10 2011 17:00:59 GMT+0200 (CEST) 1315666859000 2011-09-10T15:00:59.000Z
+Sun Sep 11 2011 17:00:59 GMT+0200 (CEST) 1315753259000 2011-09-11T15:00:59.000Z
+Mon Sep 12 2011 17:00:59 GMT+0200 (CEST) 1315839659000 2011-09-12T15:00:59.000Z
+Tue Sep 13 2011 17:00:59 GMT+0200 (CEST) 1315926059000 2011-09-13T15:00:59.000Z
+Wed Sep 14 2011 17:00:59 GMT+0200 (CEST) 1316012459000 2011-09-14T15:00:59.000Z
+Thu Sep 15 2011 17:00:59 GMT+0200 (CEST) 1316098859000 2011-09-15T15:00:59.000Z
+Fri Sep 16 2011 17:00:59 GMT+0200 (CEST) 1316185259000 2011-09-16T15:00:59.000Z
+Sat Sep 17 2011 17:00:59 GMT+0200 (CEST) 1316271659000 2011-09-17T15:00:59.000Z
+Sun Sep 18 2011 17:00:59 GMT+0200 (CEST) 1316358059000 2011-09-18T15:00:59.000Z
+Mon Sep 19 2011 17:00:59 GMT+0200 (CEST) 1316444459000 2011-09-19T15:00:59.000Z
+Tue Sep 20 2011 17:00:59 GMT+0200 (CEST) 1316530859000 2011-09-20T15:00:59.000Z
+Wed Sep 21 2011 17:00:59 GMT+0200 (CEST) 1316617259000 2011-09-21T15:00:59.000Z
+Thu Sep 22 2011 17:00:59 GMT+0200 (CEST) 1316703659000 2011-09-22T15:00:59.000Z
+Fri Sep 23 2011 17:00:59 GMT+0200 (CEST) 1316790059000 2011-09-23T15:00:59.000Z
+Sat Sep 24 2011 17:00:59 GMT+0200 (CEST) 1316876459000 2011-09-24T15:00:59.000Z
+Sun Sep 25 2011 17:00:59 GMT+0200 (CEST) 1316962859000 2011-09-25T15:00:59.000Z
+Mon Sep 26 2011 17:00:59 GMT+0200 (CEST) 1317049259000 2011-09-26T15:00:59.000Z
+Tue Sep 27 2011 17:00:59 GMT+0200 (CEST) 1317135659000 2011-09-27T15:00:59.000Z
+Wed Sep 28 2011 17:00:59 GMT+0200 (CEST) 1317222059000 2011-09-28T15:00:59.000Z
+Thu Sep 29 2011 17:00:59 GMT+0200 (CEST) 1317308459000 2011-09-29T15:00:59.000Z
+Fri Sep 30 2011 17:00:59 GMT+0200 (CEST) 1317394859000 2011-09-30T15:00:59.000Z
+Sat Oct 01 2011 17:00:59 GMT+0200 (CEST) 1317481259000 2011-10-01T15:00:59.000Z
+Sun Oct 02 2011 17:00:59 GMT+0200 (CEST) 1317567659000 2011-10-02T15:00:59.000Z
+Mon Oct 03 2011 17:00:59 GMT+0200 (CEST) 1317654059000 2011-10-03T15:00:59.000Z
+Tue Oct 04 2011 17:00:59 GMT+0200 (CEST) 1317740459000 2011-10-04T15:00:59.000Z
+Wed Oct 05 2011 17:00:59 GMT+0200 (CEST) 1317826859000 2011-10-05T15:00:59.000Z
+Thu Oct 06 2011 17:00:59 GMT+0200 (CEST) 1317913259000 2011-10-06T15:00:59.000Z
+Fri Oct 07 2011 17:00:59 GMT+0200 (CEST) 1317999659000 2011-10-07T15:00:59.000Z
+Sat Oct 08 2011 17:00:59 GMT+0200 (CEST) 1318086059000 2011-10-08T15:00:59.000Z
+Sun Oct 09 2011 17:00:59 GMT+0200 (CEST) 1318172459000 2011-10-09T15:00:59.000Z
+Mon Oct 10 2011 17:00:59 GMT+0200 (CEST) 1318258859000 2011-10-10T15:00:59.000Z
+Tue Oct 11 2011 17:00:59 GMT+0200 (CEST) 1318345259000 2011-10-11T15:00:59.000Z
+Wed Oct 12 2011 17:00:59 GMT+0200 (CEST) 1318431659000 2011-10-12T15:00:59.000Z
+Thu Oct 13 2011 17:00:59 GMT+0200 (CEST) 1318518059000 2011-10-13T15:00:59.000Z
+Fri Oct 14 2011 17:00:59 GMT+0200 (CEST) 1318604459000 2011-10-14T15:00:59.000Z
+Sat Oct 15 2011 17:00:59 GMT+0200 (CEST) 1318690859000 2011-10-15T15:00:59.000Z
+Sun Oct 16 2011 17:00:59 GMT+0200 (CEST) 1318777259000 2011-10-16T15:00:59.000Z
+Mon Oct 17 2011 17:00:59 GMT+0200 (CEST) 1318863659000 2011-10-17T15:00:59.000Z
+Tue Oct 18 2011 17:00:59 GMT+0200 (CEST) 1318950059000 2011-10-18T15:00:59.000Z
+Wed Oct 19 2011 17:00:59 GMT+0200 (CEST) 1319036459000 2011-10-19T15:00:59.000Z
+Thu Oct 20 2011 17:00:59 GMT+0200 (CEST) 1319122859000 2011-10-20T15:00:59.000Z
+Fri Oct 21 2011 17:00:59 GMT+0200 (CEST) 1319209259000 2011-10-21T15:00:59.000Z
+Sat Oct 22 2011 17:00:59 GMT+0200 (CEST) 1319295659000 2011-10-22T15:00:59.000Z
+Sun Oct 23 2011 17:00:59 GMT+0200 (CEST) 1319382059000 2011-10-23T15:00:59.000Z
+Mon Oct 24 2011 17:00:59 GMT+0200 (CEST) 1319468459000 2011-10-24T15:00:59.000Z
+Tue Oct 25 2011 17:00:59 GMT+0200 (CEST) 1319554859000 2011-10-25T15:00:59.000Z
+Wed Oct 26 2011 17:00:59 GMT+0200 (CEST) 1319641259000 2011-10-26T15:00:59.000Z
+Thu Oct 27 2011 17:00:59 GMT+0200 (CEST) 1319727659000 2011-10-27T15:00:59.000Z
+Fri Oct 28 2011 17:00:59 GMT+0200 (CEST) 1319814059000 2011-10-28T15:00:59.000Z
+Sat Oct 29 2011 17:00:59 GMT+0200 (CEST) 1319900459000 2011-10-29T15:00:59.000Z
+Sun Oct 30 2011 17:00:59 GMT+0100 (CET) 1319990459000 2011-10-30T16:00:59.000Z
+Mon Oct 31 2011 17:00:59 GMT+0100 (CET) 1320076859000 2011-10-31T16:00:59.000Z
+Tue Nov 01 2011 17:00:59 GMT+0100 (CET) 1320163259000 2011-11-01T16:00:59.000Z
+Wed Nov 02 2011 17:00:59 GMT+0100 (CET) 1320249659000 2011-11-02T16:00:59.000Z
+Thu Nov 03 2011 17:00:59 GMT+0100 (CET) 1320336059000 2011-11-03T16:00:59.000Z
+Fri Nov 04 2011 17:00:59 GMT+0100 (CET) 1320422459000 2011-11-04T16:00:59.000Z
+Sat Nov 05 2011 17:00:59 GMT+0100 (CET) 1320508859000 2011-11-05T16:00:59.000Z
+Sun Nov 06 2011 17:00:59 GMT+0100 (CET) 1320595259000 2011-11-06T16:00:59.000Z
+Mon Nov 07 2011 17:00:59 GMT+0100 (CET) 1320681659000 2011-11-07T16:00:59.000Z
+Tue Nov 08 2011 17:00:59 GMT+0100 (CET) 1320768059000 2011-11-08T16:00:59.000Z
+Wed Nov 09 2011 17:00:59 GMT+0100 (CET) 1320854459000 2011-11-09T16:00:59.000Z
+Thu Nov 10 2011 17:00:59 GMT+0100 (CET) 1320940859000 2011-11-10T16:00:59.000Z
+Fri Nov 11 2011 17:00:59 GMT+0100 (CET) 1321027259000 2011-11-11T16:00:59.000Z
+Sat Nov 12 2011 17:00:59 GMT+0100 (CET) 1321113659000 2011-11-12T16:00:59.000Z
+Sun Nov 13 2011 17:00:59 GMT+0100 (CET) 1321200059000 2011-11-13T16:00:59.000Z
+Mon Nov 14 2011 17:00:59 GMT+0100 (CET) 1321286459000 2011-11-14T16:00:59.000Z
+Tue Nov 15 2011 17:00:59 GMT+0100 (CET) 1321372859000 2011-11-15T16:00:59.000Z
+Wed Nov 16 2011 17:00:59 GMT+0100 (CET) 1321459259000 2011-11-16T16:00:59.000Z
+Thu Nov 17 2011 17:00:59 GMT+0100 (CET) 1321545659000 2011-11-17T16:00:59.000Z
+Fri Nov 18 2011 17:00:59 GMT+0100 (CET) 1321632059000 2011-11-18T16:00:59.000Z
+Sat Nov 19 2011 17:00:59 GMT+0100 (CET) 1321718459000 2011-11-19T16:00:59.000Z
+Sun Nov 20 2011 17:00:59 GMT+0100 (CET) 1321804859000 2011-11-20T16:00:59.000Z
+Mon Nov 21 2011 17:00:59 GMT+0100 (CET) 1321891259000 2011-11-21T16:00:59.000Z
+Tue Nov 22 2011 17:00:59 GMT+0100 (CET) 1321977659000 2011-11-22T16:00:59.000Z
+Wed Nov 23 2011 17:00:59 GMT+0100 (CET) 1322064059000 2011-11-23T16:00:59.000Z
+Thu Nov 24 2011 17:00:59 GMT+0100 (CET) 1322150459000 2011-11-24T16:00:59.000Z
+Fri Nov 25 2011 17:00:59 GMT+0100 (CET) 1322236859000 2011-11-25T16:00:59.000Z
+Sat Nov 26 2011 17:00:59 GMT+0100 (CET) 1322323259000 2011-11-26T16:00:59.000Z
+Sun Nov 27 2011 17:00:59 GMT+0100 (CET) 1322409659000 2011-11-27T16:00:59.000Z
+Mon Nov 28 2011 17:00:59 GMT+0100 (CET) 1322496059000 2011-11-28T16:00:59.000Z
+Tue Nov 29 2011 17:00:59 GMT+0100 (CET) 1322582459000 2011-11-29T16:00:59.000Z
+Wed Nov 30 2011 17:00:59 GMT+0100 (CET) 1322668859000 2011-11-30T16:00:59.000Z
+Thu Dec 01 2011 17:00:59 GMT+0100 (CET) 1322755259000 2011-12-01T16:00:59.000Z
+Fri Dec 02 2011 17:00:59 GMT+0100 (CET) 1322841659000 2011-12-02T16:00:59.000Z
+Sat Dec 03 2011 17:00:59 GMT+0100 (CET) 1322928059000 2011-12-03T16:00:59.000Z
+Sun Dec 04 2011 17:00:59 GMT+0100 (CET) 1323014459000 2011-12-04T16:00:59.000Z
+Mon Dec 05 2011 17:00:59 GMT+0100 (CET) 1323100859000 2011-12-05T16:00:59.000Z
+Tue Dec 06 2011 17:00:59 GMT+0100 (CET) 1323187259000 2011-12-06T16:00:59.000Z
+Wed Dec 07 2011 17:00:59 GMT+0100 (CET) 1323273659000 2011-12-07T16:00:59.000Z
+Thu Dec 08 2011 17:00:59 GMT+0100 (CET) 1323360059000 2011-12-08T16:00:59.000Z
+Fri Dec 09 2011 17:00:59 GMT+0100 (CET) 1323446459000 2011-12-09T16:00:59.000Z
+Sat Dec 10 2011 17:00:59 GMT+0100 (CET) 1323532859000 2011-12-10T16:00:59.000Z
+Sun Dec 11 2011 17:00:59 GMT+0100 (CET) 1323619259000 2011-12-11T16:00:59.000Z
+Mon Dec 12 2011 17:00:59 GMT+0100 (CET) 1323705659000 2011-12-12T16:00:59.000Z
+Tue Dec 13 2011 17:00:59 GMT+0100 (CET) 1323792059000 2011-12-13T16:00:59.000Z
+Wed Dec 14 2011 17:00:59 GMT+0100 (CET) 1323878459000 2011-12-14T16:00:59.000Z
+Thu Dec 15 2011 17:00:59 GMT+0100 (CET) 1323964859000 2011-12-15T16:00:59.000Z
+Fri Dec 16 2011 17:00:59 GMT+0100 (CET) 1324051259000 2011-12-16T16:00:59.000Z
+Sat Dec 17 2011 17:00:59 GMT+0100 (CET) 1324137659000 2011-12-17T16:00:59.000Z
+Sun Dec 18 2011 17:00:59 GMT+0100 (CET) 1324224059000 2011-12-18T16:00:59.000Z
+Mon Dec 19 2011 17:00:59 GMT+0100 (CET) 1324310459000 2011-12-19T16:00:59.000Z
+Tue Dec 20 2011 17:00:59 GMT+0100 (CET) 1324396859000 2011-12-20T16:00:59.000Z
+Wed Dec 21 2011 17:00:59 GMT+0100 (CET) 1324483259000 2011-12-21T16:00:59.000Z
+Thu Dec 22 2011 17:00:59 GMT+0100 (CET) 1324569659000 2011-12-22T16:00:59.000Z
+Fri Dec 23 2011 17:00:59 GMT+0100 (CET) 1324656059000 2011-12-23T16:00:59.000Z
+Sat Dec 24 2011 17:00:59 GMT+0100 (CET) 1324742459000 2011-12-24T16:00:59.000Z
+Sun Dec 25 2011 17:00:59 GMT+0100 (CET) 1324828859000 2011-12-25T16:00:59.000Z
+Mon Dec 26 2011 17:00:59 GMT+0100 (CET) 1324915259000 2011-12-26T16:00:59.000Z
+Tue Dec 27 2011 17:00:59 GMT+0100 (CET) 1325001659000 2011-12-27T16:00:59.000Z
+Wed Dec 28 2011 17:00:59 GMT+0100 (CET) 1325088059000 2011-12-28T16:00:59.000Z
+Thu Dec 29 2011 17:00:59 GMT+0100 (CET) 1325174459000 2011-12-29T16:00:59.000Z
+Fri Dec 30 2011 17:00:59 GMT+0100 (CET) 1325260859000 2011-12-30T16:00:59.000Z
+Sat Dec 31 2011 17:00:59 GMT+0100 (CET) 1325347259000 2011-12-31T16:00:59.000Z
+Sun Jan 01 2012 17:00:59 GMT+0100 (CET) 1325433659000 2012-01-01T16:00:59.000Z
+Mon Jan 02 2012 17:00:59 GMT+0100 (CET) 1325520059000 2012-01-02T16:00:59.000Z
+Tue Jan 03 2012 17:00:59 GMT+0100 (CET) 1325606459000 2012-01-03T16:00:59.000Z
+Wed Jan 04 2012 17:00:59 GMT+0100 (CET) 1325692859000 2012-01-04T16:00:59.000Z
+Thu Jan 05 2012 17:00:59 GMT+0100 (CET) 1325779259000 2012-01-05T16:00:59.000Z
+Fri Jan 06 2012 17:00:59 GMT+0100 (CET) 1325865659000 2012-01-06T16:00:59.000Z
+Sat Jan 07 2012 17:00:59 GMT+0100 (CET) 1325952059000 2012-01-07T16:00:59.000Z
+Sun Jan 08 2012 17:00:59 GMT+0100 (CET) 1326038459000 2012-01-08T16:00:59.000Z
+Mon Jan 09 2012 17:00:59 GMT+0100 (CET) 1326124859000 2012-01-09T16:00:59.000Z
+Tue Jan 10 2012 17:00:59 GMT+0100 (CET) 1326211259000 2012-01-10T16:00:59.000Z
+Wed Jan 11 2012 17:00:59 GMT+0100 (CET) 1326297659000 2012-01-11T16:00:59.000Z
+Thu Jan 12 2012 17:00:59 GMT+0100 (CET) 1326384059000 2012-01-12T16:00:59.000Z
+Fri Jan 13 2012 17:00:59 GMT+0100 (CET) 1326470459000 2012-01-13T16:00:59.000Z
+Sat Jan 14 2012 17:00:59 GMT+0100 (CET) 1326556859000 2012-01-14T16:00:59.000Z
+Wed Dec 21 2011 12:30:10 GMT+0100 (CET) 1324467010500 2011-12-21T11:30:10.500Z
+Thu Dec 22 2011 12:30:10 GMT+0100 (CET) 1324553410500 2011-12-22T11:30:10.500Z
+Fri Dec 23 2011 12:30:10 GMT+0100 (CET) 1324639810500 2011-12-23T11:30:10.500Z
+Sat Dec 24 2011 12:30:10 GMT+0100 (CET) 1324726210500 2011-12-24T11:30:10.500Z
+Sun Dec 25 2011 12:30:10 GMT+0100 (CET) 1324812610500 2011-12-25T11:30:10.500Z
+Mon Dec 26 2011 12:30:10 GMT+0100 (CET) 1324899010500 2011-12-26T11:30:10.500Z
+Tue Dec 27 2011 12:30:10 GMT+0100 (CET) 1324985410500 2011-12-27T11:30:10.500Z
+Wed Dec 28 2011 12:30:10 GMT+0100 (CET) 1325071810500 2011-12-28T11:30:10.500Z
+Thu Dec 29 2011 12:30:10 GMT+0100 (CET) 1325158210500 2011-12-29T11:30:10.500Z
+Fri Dec 30 2011 12:30:10 GMT+0100 (CET) 1325244610500 2011-12-30T11:30:10.500Z
+Sat Dec 31 2011 12:30:10 GMT+0100 (CET) 1325331010500 2011-12-31T11:30:10.500Z
+Sun Jan 01 2012 12:30:10 GMT+0100 (CET) 1325417410500 2012-01-01T11:30:10.500Z
+Mon Jan 02 2012 12:30:10 GMT+0100 (CET) 1325503810500 2012-01-02T11:30:10.500Z
+Tue Jan 03 2012 12:30:10 GMT+0100 (CET) 1325590210500 2012-01-03T11:30:10.500Z
+Wed Jan 04 2012 12:30:10 GMT+0100 (CET) 1325676610500 2012-01-04T11:30:10.500Z
+Thu Jan 05 2012 12:30:10 GMT+0100 (CET) 1325763010500 2012-01-05T11:30:10.500Z
+Fri Jan 06 2012 12:30:10 GMT+0100 (CET) 1325849410500 2012-01-06T11:30:10.500Z
+Sat Jan 07 2012 12:30:10 GMT+0100 (CET) 1325935810500 2012-01-07T11:30:10.500Z
+Sun Jan 08 2012 12:30:10 GMT+0100 (CET) 1326022210500 2012-01-08T11:30:10.500Z
+Mon Jan 09 2012 12:30:10 GMT+0100 (CET) 1326108610500 2012-01-09T11:30:10.500Z
+Tue Jan 10 2012 12:30:10 GMT+0100 (CET) 1326195010500 2012-01-10T11:30:10.500Z
+Wed Jan 11 2012 12:30:10 GMT+0100 (CET) 1326281410500 2012-01-11T11:30:10.500Z
+Thu Jan 12 2012 12:30:10 GMT+0100 (CET) 1326367810500 2012-01-12T11:30:10.500Z
+Fri Jan 13 2012 12:30:10 GMT+0100 (CET) 1326454210500 2012-01-13T11:30:10.500Z
+Sat Jan 14 2012 12:30:10 GMT+0100 (CET) 1326540610500 2012-01-14T11:30:10.500Z
+Sun Jan 15 2012 12:30:10 GMT+0100 (CET) 1326627010500 2012-01-15T11:30:10.500Z
+Mon Jan 16 2012 12:30:10 GMT+0100 (CET) 1326713410500 2012-01-16T11:30:10.500Z
+Tue Jan 17 2012 12:30:10 GMT+0100 (CET) 1326799810500 2012-01-17T11:30:10.500Z
+Wed Jan 18 2012 12:30:10 GMT+0100 (CET) 1326886210500 2012-01-18T11:30:10.500Z
+Thu Jan 19 2012 12:30:10 GMT+0100 (CET) 1326972610500 2012-01-19T11:30:10.500Z
+Fri Jan 20 2012 12:30:10 GMT+0100 (CET) 1327059010500 2012-01-20T11:30:10.500Z
+Sat Jan 21 2012 12:30:10 GMT+0100 (CET) 1327145410500 2012-01-21T11:30:10.500Z
+Sun Jan 22 2012 12:30:10 GMT+0100 (CET) 1327231810500 2012-01-22T11:30:10.500Z
+Mon Jan 23 2012 12:30:10 GMT+0100 (CET) 1327318210500 2012-01-23T11:30:10.500Z
+Tue Jan 24 2012 12:30:10 GMT+0100 (CET) 1327404610500 2012-01-24T11:30:10.500Z
+Wed Jan 25 2012 12:30:10 GMT+0100 (CET) 1327491010500 2012-01-25T11:30:10.500Z
+Thu Jan 26 2012 12:30:10 GMT+0100 (CET) 1327577410500 2012-01-26T11:30:10.500Z
+Fri Jan 27 2012 12:30:10 GMT+0100 (CET) 1327663810500 2012-01-27T11:30:10.500Z
+Sat Jan 28 2012 12:30:10 GMT+0100 (CET) 1327750210500 2012-01-28T11:30:10.500Z
+Sun Jan 29 2012 12:30:10 GMT+0100 (CET) 1327836610500 2012-01-29T11:30:10.500Z
+Mon Jan 30 2012 12:30:10 GMT+0100 (CET) 1327923010500 2012-01-30T11:30:10.500Z
+Tue Jan 31 2012 12:30:10 GMT+0100 (CET) 1328009410500 2012-01-31T11:30:10.500Z
+Wed Feb 01 2012 12:30:10 GMT+0100 (CET) 1328095810500 2012-02-01T11:30:10.500Z
+Thu Feb 02 2012 12:30:10 GMT+0100 (CET) 1328182210500 2012-02-02T11:30:10.500Z
+Fri Feb 03 2012 12:30:10 GMT+0100 (CET) 1328268610500 2012-02-03T11:30:10.500Z
+Sat Feb 04 2012 12:30:10 GMT+0100 (CET) 1328355010500 2012-02-04T11:30:10.500Z
+Sun Feb 05 2012 12:30:10 GMT+0100 (CET) 1328441410500 2012-02-05T11:30:10.500Z
+Mon Feb 06 2012 12:30:10 GMT+0100 (CET) 1328527810500 2012-02-06T11:30:10.500Z
+Tue Feb 07 2012 12:30:10 GMT+0100 (CET) 1328614210500 2012-02-07T11:30:10.500Z
+Wed Feb 08 2012 12:30:10 GMT+0100 (CET) 1328700610500 2012-02-08T11:30:10.500Z
+Thu Feb 09 2012 12:30:10 GMT+0100 (CET) 1328787010500 2012-02-09T11:30:10.500Z
+Fri Feb 10 2012 12:30:10 GMT+0100 (CET) 1328873410500 2012-02-10T11:30:10.500Z
+Sat Feb 11 2012 12:30:10 GMT+0100 (CET) 1328959810500 2012-02-11T11:30:10.500Z
+Sun Feb 12 2012 12:30:10 GMT+0100 (CET) 1329046210500 2012-02-12T11:30:10.500Z
+Mon Feb 13 2012 12:30:10 GMT+0100 (CET) 1329132610500 2012-02-13T11:30:10.500Z
+Tue Feb 14 2012 12:30:10 GMT+0100 (CET) 1329219010500 2012-02-14T11:30:10.500Z
+Wed Feb 15 2012 12:30:10 GMT+0100 (CET) 1329305410500 2012-02-15T11:30:10.500Z
+Thu Feb 16 2012 12:30:10 GMT+0100 (CET) 1329391810500 2012-02-16T11:30:10.500Z
+Fri Feb 17 2012 12:30:10 GMT+0100 (CET) 1329478210500 2012-02-17T11:30:10.500Z
+Sat Feb 18 2012 12:30:10 GMT+0100 (CET) 1329564610500 2012-02-18T11:30:10.500Z
+Sun Feb 19 2012 12:30:10 GMT+0100 (CET) 1329651010500 2012-02-19T11:30:10.500Z
+Mon Feb 20 2012 12:30:10 GMT+0100 (CET) 1329737410500 2012-02-20T11:30:10.500Z
+Tue Feb 21 2012 12:30:10 GMT+0100 (CET) 1329823810500 2012-02-21T11:30:10.500Z
+Wed Feb 22 2012 12:30:10 GMT+0100 (CET) 1329910210500 2012-02-22T11:30:10.500Z
+Thu Feb 23 2012 12:30:10 GMT+0100 (CET) 1329996610500 2012-02-23T11:30:10.500Z
+Fri Feb 24 2012 12:30:10 GMT+0100 (CET) 1330083010500 2012-02-24T11:30:10.500Z
+Sat Feb 25 2012 12:30:10 GMT+0100 (CET) 1330169410500 2012-02-25T11:30:10.500Z
+Sun Feb 26 2012 12:30:10 GMT+0100 (CET) 1330255810500 2012-02-26T11:30:10.500Z
+Mon Feb 27 2012 12:30:10 GMT+0100 (CET) 1330342210500 2012-02-27T11:30:10.500Z
+Tue Feb 28 2012 12:30:10 GMT+0100 (CET) 1330428610500 2012-02-28T11:30:10.500Z
+Wed Feb 29 2012 12:30:10 GMT+0100 (CET) 1330515010500 2012-02-29T11:30:10.500Z
+Thu Mar 01 2012 12:30:10 GMT+0100 (CET) 1330601410500 2012-03-01T11:30:10.500Z
+Fri Mar 02 2012 12:30:10 GMT+0100 (CET) 1330687810500 2012-03-02T11:30:10.500Z
+Sat Mar 03 2012 12:30:10 GMT+0100 (CET) 1330774210500 2012-03-03T11:30:10.500Z
+Sun Mar 04 2012 12:30:10 GMT+0100 (CET) 1330860610500 2012-03-04T11:30:10.500Z
+Mon Mar 05 2012 12:30:10 GMT+0100 (CET) 1330947010500 2012-03-05T11:30:10.500Z
+Tue Mar 06 2012 12:30:10 GMT+0100 (CET) 1331033410500 2012-03-06T11:30:10.500Z
+Wed Mar 07 2012 12:30:10 GMT+0100 (CET) 1331119810500 2012-03-07T11:30:10.500Z
+Thu Mar 08 2012 12:30:10 GMT+0100 (CET) 1331206210500 2012-03-08T11:30:10.500Z
+Fri Mar 09 2012 12:30:10 GMT+0100 (CET) 1331292610500 2012-03-09T11:30:10.500Z
+Sat Mar 10 2012 12:30:10 GMT+0100 (CET) 1331379010500 2012-03-10T11:30:10.500Z
+Sun Mar 11 2012 12:30:10 GMT+0100 (CET) 1331465410500 2012-03-11T11:30:10.500Z
+Mon Mar 12 2012 12:30:10 GMT+0100 (CET) 1331551810500 2012-03-12T11:30:10.500Z
+Tue Mar 13 2012 12:30:10 GMT+0100 (CET) 1331638210500 2012-03-13T11:30:10.500Z
+Wed Mar 14 2012 12:30:10 GMT+0100 (CET) 1331724610500 2012-03-14T11:30:10.500Z
+Thu Mar 15 2012 12:30:10 GMT+0100 (CET) 1331811010500 2012-03-15T11:30:10.500Z
+Fri Mar 16 2012 12:30:10 GMT+0100 (CET) 1331897410500 2012-03-16T11:30:10.500Z
+Sat Mar 17 2012 12:30:10 GMT+0100 (CET) 1331983810500 2012-03-17T11:30:10.500Z
+Sun Mar 18 2012 12:30:10 GMT+0100 (CET) 1332070210500 2012-03-18T11:30:10.500Z
+Mon Mar 19 2012 12:30:10 GMT+0100 (CET) 1332156610500 2012-03-19T11:30:10.500Z
+Tue Mar 20 2012 12:30:10 GMT+0100 (CET) 1332243010500 2012-03-20T11:30:10.500Z
+Wed Mar 21 2012 12:30:10 GMT+0100 (CET) 1332329410500 2012-03-21T11:30:10.500Z
+Thu Mar 22 2012 12:30:10 GMT+0100 (CET) 1332415810500 2012-03-22T11:30:10.500Z
+Fri Mar 23 2012 12:30:10 GMT+0100 (CET) 1332502210500 2012-03-23T11:30:10.500Z
+Sat Mar 24 2012 12:30:10 GMT+0100 (CET) 1332588610500 2012-03-24T11:30:10.500Z
+Sun Mar 25 2012 12:30:10 GMT+0200 (CEST) 1332671410500 2012-03-25T10:30:10.500Z
+Mon Mar 26 2012 12:30:10 GMT+0200 (CEST) 1332757810500 2012-03-26T10:30:10.500Z
+Tue Mar 27 2012 12:30:10 GMT+0200 (CEST) 1332844210500 2012-03-27T10:30:10.500Z
+Wed Mar 28 2012 12:30:10 GMT+0200 (CEST) 1332930610500 2012-03-28T10:30:10.500Z
+Thu Mar 29 2012 12:30:10 GMT+0200 (CEST) 1333017010500 2012-03-29T10:30:10.500Z
+Fri Mar 30 2012 12:30:10 GMT+0200 (CEST) 1333103410500 2012-03-30T10:30:10.500Z
+Sat Mar 31 2012 12:30:10 GMT+0200 (CEST) 1333189810500 2012-03-31T10:30:10.500Z
+Sun Apr 01 2012 12:30:10 GMT+0200 (CEST) 1333276210500 2012-04-01T10:30:10.500Z
+Mon Apr 02 2012 12:30:10 GMT+0200 (CEST) 1333362610500 2012-04-02T10:30:10.500Z
+Tue Apr 03 2012 12:30:10 GMT+0200 (CEST) 1333449010500 2012-04-03T10:30:10.500Z
+Wed Apr 04 2012 12:30:10 GMT+0200 (CEST) 1333535410500 2012-04-04T10:30:10.500Z
+Thu Apr 05 2012 12:30:10 GMT+0200 (CEST) 1333621810500 2012-04-05T10:30:10.500Z
+Fri Apr 06 2012 12:30:10 GMT+0200 (CEST) 1333708210500 2012-04-06T10:30:10.500Z
+Sat Apr 07 2012 12:30:10 GMT+0200 (CEST) 1333794610500 2012-04-07T10:30:10.500Z
+Sun Apr 08 2012 12:30:10 GMT+0200 (CEST) 1333881010500 2012-04-08T10:30:10.500Z
+Mon Apr 09 2012 12:30:10 GMT+0200 (CEST) 1333967410500 2012-04-09T10:30:10.500Z
+Tue Apr 10 2012 12:30:10 GMT+0200 (CEST) 1334053810500 2012-04-10T10:30:10.500Z
+Wed Apr 11 2012 12:30:10 GMT+0200 (CEST) 1334140210500 2012-04-11T10:30:10.500Z
+Thu Apr 12 2012 12:30:10 GMT+0200 (CEST) 1334226610500 2012-04-12T10:30:10.500Z
+Fri Apr 13 2012 12:30:10 GMT+0200 (CEST) 1334313010500 2012-04-13T10:30:10.500Z
+Sat Apr 14 2012 12:30:10 GMT+0200 (CEST) 1334399410500 2012-04-14T10:30:10.500Z
+Sun Apr 15 2012 12:30:10 GMT+0200 (CEST) 1334485810500 2012-04-15T10:30:10.500Z
+Mon Apr 16 2012 12:30:10 GMT+0200 (CEST) 1334572210500 2012-04-16T10:30:10.500Z
+Tue Apr 17 2012 12:30:10 GMT+0200 (CEST) 1334658610500 2012-04-17T10:30:10.500Z
+Wed Apr 18 2012 12:30:10 GMT+0200 (CEST) 1334745010500 2012-04-18T10:30:10.500Z
+Thu Apr 19 2012 12:30:10 GMT+0200 (CEST) 1334831410500 2012-04-19T10:30:10.500Z
+Fri Apr 20 2012 12:30:10 GMT+0200 (CEST) 1334917810500 2012-04-20T10:30:10.500Z
+Sat Apr 21 2012 12:30:10 GMT+0200 (CEST) 1335004210500 2012-04-21T10:30:10.500Z
+Sun Apr 22 2012 12:30:10 GMT+0200 (CEST) 1335090610500 2012-04-22T10:30:10.500Z
+Mon Apr 23 2012 12:30:10 GMT+0200 (CEST) 1335177010500 2012-04-23T10:30:10.500Z
+Tue Apr 24 2012 12:30:10 GMT+0200 (CEST) 1335263410500 2012-04-24T10:30:10.500Z
+Wed Apr 25 2012 12:30:10 GMT+0200 (CEST) 1335349810500 2012-04-25T10:30:10.500Z
+Thu Apr 26 2012 12:30:10 GMT+0200 (CEST) 1335436210500 2012-04-26T10:30:10.500Z
+Fri Apr 27 2012 12:30:10 GMT+0200 (CEST) 1335522610500 2012-04-27T10:30:10.500Z
+Sat Apr 28 2012 12:30:10 GMT+0200 (CEST) 1335609010500 2012-04-28T10:30:10.500Z
+Sun Apr 29 2012 12:30:10 GMT+0200 (CEST) 1335695410500 2012-04-29T10:30:10.500Z
+Mon Apr 30 2012 12:30:10 GMT+0200 (CEST) 1335781810500 2012-04-30T10:30:10.500Z
+Tue May 01 2012 12:30:10 GMT+0200 (CEST) 1335868210500 2012-05-01T10:30:10.500Z
+Wed May 02 2012 12:30:10 GMT+0200 (CEST) 1335954610500 2012-05-02T10:30:10.500Z
+Thu May 03 2012 12:30:10 GMT+0200 (CEST) 1336041010500 2012-05-03T10:30:10.500Z
+Fri May 04 2012 12:30:10 GMT+0200 (CEST) 1336127410500 2012-05-04T10:30:10.500Z
+Sat May 05 2012 12:30:10 GMT+0200 (CEST) 1336213810500 2012-05-05T10:30:10.500Z
+Sun May 06 2012 12:30:10 GMT+0200 (CEST) 1336300210500 2012-05-06T10:30:10.500Z
+Mon May 07 2012 12:30:10 GMT+0200 (CEST) 1336386610500 2012-05-07T10:30:10.500Z
+Tue May 08 2012 12:30:10 GMT+0200 (CEST) 1336473010500 2012-05-08T10:30:10.500Z
+Wed May 09 2012 12:30:10 GMT+0200 (CEST) 1336559410500 2012-05-09T10:30:10.500Z
+Thu May 10 2012 12:30:10 GMT+0200 (CEST) 1336645810500 2012-05-10T10:30:10.500Z
+Fri May 11 2012 12:30:10 GMT+0200 (CEST) 1336732210500 2012-05-11T10:30:10.500Z
+Sat May 12 2012 12:30:10 GMT+0200 (CEST) 1336818610500 2012-05-12T10:30:10.500Z
+Sun May 13 2012 12:30:10 GMT+0200 (CEST) 1336905010500 2012-05-13T10:30:10.500Z
+Mon May 14 2012 12:30:10 GMT+0200 (CEST) 1336991410500 2012-05-14T10:30:10.500Z
+Tue May 15 2012 12:30:10 GMT+0200 (CEST) 1337077810500 2012-05-15T10:30:10.500Z
+Wed May 16 2012 12:30:10 GMT+0200 (CEST) 1337164210500 2012-05-16T10:30:10.500Z
+Thu May 17 2012 12:30:10 GMT+0200 (CEST) 1337250610500 2012-05-17T10:30:10.500Z
+Fri May 18 2012 12:30:10 GMT+0200 (CEST) 1337337010500 2012-05-18T10:30:10.500Z
+Sat May 19 2012 12:30:10 GMT+0200 (CEST) 1337423410500 2012-05-19T10:30:10.500Z
+Sun May 20 2012 12:30:10 GMT+0200 (CEST) 1337509810500 2012-05-20T10:30:10.500Z
+Mon May 21 2012 12:30:10 GMT+0200 (CEST) 1337596210500 2012-05-21T10:30:10.500Z
+Tue May 22 2012 12:30:10 GMT+0200 (CEST) 1337682610500 2012-05-22T10:30:10.500Z
+Wed May 23 2012 12:30:10 GMT+0200 (CEST) 1337769010500 2012-05-23T10:30:10.500Z
+Thu May 24 2012 12:30:10 GMT+0200 (CEST) 1337855410500 2012-05-24T10:30:10.500Z
+Fri May 25 2012 12:30:10 GMT+0200 (CEST) 1337941810500 2012-05-25T10:30:10.500Z
+Sat May 26 2012 12:30:10 GMT+0200 (CEST) 1338028210500 2012-05-26T10:30:10.500Z
+Sun May 27 2012 12:30:10 GMT+0200 (CEST) 1338114610500 2012-05-27T10:30:10.500Z
+Mon May 28 2012 12:30:10 GMT+0200 (CEST) 1338201010500 2012-05-28T10:30:10.500Z
+Tue May 29 2012 12:30:10 GMT+0200 (CEST) 1338287410500 2012-05-29T10:30:10.500Z
+Wed May 30 2012 12:30:10 GMT+0200 (CEST) 1338373810500 2012-05-30T10:30:10.500Z
+Thu May 31 2012 12:30:10 GMT+0200 (CEST) 1338460210500 2012-05-31T10:30:10.500Z
+Fri Jun 01 2012 12:30:10 GMT+0200 (CEST) 1338546610500 2012-06-01T10:30:10.500Z
+Sat Jun 02 2012 12:30:10 GMT+0200 (CEST) 1338633010500 2012-06-02T10:30:10.500Z
+Sun Jun 03 2012 12:30:10 GMT+0200 (CEST) 1338719410500 2012-06-03T10:30:10.500Z
+Mon Jun 04 2012 12:30:10 GMT+0200 (CEST) 1338805810500 2012-06-04T10:30:10.500Z
+Tue Jun 05 2012 12:30:10 GMT+0200 (CEST) 1338892210500 2012-06-05T10:30:10.500Z
+Wed Jun 06 2012 12:30:10 GMT+0200 (CEST) 1338978610500 2012-06-06T10:30:10.500Z
+Thu Jun 07 2012 12:30:10 GMT+0200 (CEST) 1339065010500 2012-06-07T10:30:10.500Z
+Fri Jun 08 2012 12:30:10 GMT+0200 (CEST) 1339151410500 2012-06-08T10:30:10.500Z
+Sat Jun 09 2012 12:30:10 GMT+0200 (CEST) 1339237810500 2012-06-09T10:30:10.500Z
+Sun Jun 10 2012 12:30:10 GMT+0200 (CEST) 1339324210500 2012-06-10T10:30:10.500Z
+Mon Jun 11 2012 12:30:10 GMT+0200 (CEST) 1339410610500 2012-06-11T10:30:10.500Z
+Tue Jun 12 2012 12:30:10 GMT+0200 (CEST) 1339497010500 2012-06-12T10:30:10.500Z
+Wed Jun 13 2012 12:30:10 GMT+0200 (CEST) 1339583410500 2012-06-13T10:30:10.500Z
+Thu Jun 14 2012 12:30:10 GMT+0200 (CEST) 1339669810500 2012-06-14T10:30:10.500Z
+Fri Jun 15 2012 12:30:10 GMT+0200 (CEST) 1339756210500 2012-06-15T10:30:10.500Z
+Sat Jun 16 2012 12:30:10 GMT+0200 (CEST) 1339842610500 2012-06-16T10:30:10.500Z
+Sun Jun 17 2012 12:30:10 GMT+0200 (CEST) 1339929010500 2012-06-17T10:30:10.500Z
+Mon Jun 18 2012 12:30:10 GMT+0200 (CEST) 1340015410500 2012-06-18T10:30:10.500Z
+Tue Jun 19 2012 12:30:10 GMT+0200 (CEST) 1340101810500 2012-06-19T10:30:10.500Z
+Wed Jun 20 2012 12:30:10 GMT+0200 (CEST) 1340188210500 2012-06-20T10:30:10.500Z
+Thu Jun 21 2012 12:30:10 GMT+0200 (CEST) 1340274610500 2012-06-21T10:30:10.500Z
+Fri Jun 22 2012 12:30:10 GMT+0200 (CEST) 1340361010500 2012-06-22T10:30:10.500Z
+Sat Jun 23 2012 12:30:10 GMT+0200 (CEST) 1340447410500 2012-06-23T10:30:10.500Z
+Sun Jun 24 2012 12:30:10 GMT+0200 (CEST) 1340533810500 2012-06-24T10:30:10.500Z
+Mon Jun 25 2012 12:30:10 GMT+0200 (CEST) 1340620210500 2012-06-25T10:30:10.500Z
+Tue Jun 26 2012 12:30:10 GMT+0200 (CEST) 1340706610500 2012-06-26T10:30:10.500Z
+Wed Jun 27 2012 12:30:10 GMT+0200 (CEST) 1340793010500 2012-06-27T10:30:10.500Z
+Thu Jun 28 2012 12:30:10 GMT+0200 (CEST) 1340879410500 2012-06-28T10:30:10.500Z
+Fri Jun 29 2012 12:30:10 GMT+0200 (CEST) 1340965810500 2012-06-29T10:30:10.500Z
+Sat Jun 30 2012 12:30:10 GMT+0200 (CEST) 1341052210500 2012-06-30T10:30:10.500Z
+Sun Jul 01 2012 12:30:10 GMT+0200 (CEST) 1341138610500 2012-07-01T10:30:10.500Z
+Mon Jul 02 2012 12:30:10 GMT+0200 (CEST) 1341225010500 2012-07-02T10:30:10.500Z
+Tue Jul 03 2012 12:30:10 GMT+0200 (CEST) 1341311410500 2012-07-03T10:30:10.500Z
+Wed Jul 04 2012 12:30:10 GMT+0200 (CEST) 1341397810500 2012-07-04T10:30:10.500Z
+Thu Jul 05 2012 12:30:10 GMT+0200 (CEST) 1341484210500 2012-07-05T10:30:10.500Z
+Fri Jul 06 2012 12:30:10 GMT+0200 (CEST) 1341570610500 2012-07-06T10:30:10.500Z
+Sat Jul 07 2012 12:30:10 GMT+0200 (CEST) 1341657010500 2012-07-07T10:30:10.500Z
+Sun Jul 08 2012 12:30:10 GMT+0200 (CEST) 1341743410500 2012-07-08T10:30:10.500Z
+Mon Jul 09 2012 12:30:10 GMT+0200 (CEST) 1341829810500 2012-07-09T10:30:10.500Z
+Tue Jul 10 2012 12:30:10 GMT+0200 (CEST) 1341916210500 2012-07-10T10:30:10.500Z
+Wed Jul 11 2012 12:30:10 GMT+0200 (CEST) 1342002610500 2012-07-11T10:30:10.500Z
+Thu Jul 12 2012 12:30:10 GMT+0200 (CEST) 1342089010500 2012-07-12T10:30:10.500Z
+Fri Jul 13 2012 12:30:10 GMT+0200 (CEST) 1342175410500 2012-07-13T10:30:10.500Z
+Sat Jul 14 2012 12:30:10 GMT+0200 (CEST) 1342261810500 2012-07-14T10:30:10.500Z
+Sun Jul 15 2012 12:30:10 GMT+0200 (CEST) 1342348210500 2012-07-15T10:30:10.500Z
+Mon Jul 16 2012 12:30:10 GMT+0200 (CEST) 1342434610500 2012-07-16T10:30:10.500Z
+Tue Jul 17 2012 12:30:10 GMT+0200 (CEST) 1342521010500 2012-07-17T10:30:10.500Z
+Wed Jul 18 2012 12:30:10 GMT+0200 (CEST) 1342607410500 2012-07-18T10:30:10.500Z
+Thu Jul 19 2012 12:30:10 GMT+0200 (CEST) 1342693810500 2012-07-19T10:30:10.500Z
+Fri Jul 20 2012 12:30:10 GMT+0200 (CEST) 1342780210500 2012-07-20T10:30:10.500Z
+Sat Jul 21 2012 12:30:10 GMT+0200 (CEST) 1342866610500 2012-07-21T10:30:10.500Z
+Sun Jul 22 2012 12:30:10 GMT+0200 (CEST) 1342953010500 2012-07-22T10:30:10.500Z
+Mon Jul 23 2012 12:30:10 GMT+0200 (CEST) 1343039410500 2012-07-23T10:30:10.500Z
+Tue Jul 24 2012 12:30:10 GMT+0200 (CEST) 1343125810500 2012-07-24T10:30:10.500Z
+Wed Jul 25 2012 12:30:10 GMT+0200 (CEST) 1343212210500 2012-07-25T10:30:10.500Z
+Thu Jul 26 2012 12:30:10 GMT+0200 (CEST) 1343298610500 2012-07-26T10:30:10.500Z
+Fri Jul 27 2012 12:30:10 GMT+0200 (CEST) 1343385010500 2012-07-27T10:30:10.500Z
+Sat Jul 28 2012 12:30:10 GMT+0200 (CEST) 1343471410500 2012-07-28T10:30:10.500Z
+Sun Jul 29 2012 12:30:10 GMT+0200 (CEST) 1343557810500 2012-07-29T10:30:10.500Z
+Mon Jul 30 2012 12:30:10 GMT+0200 (CEST) 1343644210500 2012-07-30T10:30:10.500Z
+Tue Jul 31 2012 12:30:10 GMT+0200 (CEST) 1343730610500 2012-07-31T10:30:10.500Z
+Wed Aug 01 2012 12:30:10 GMT+0200 (CEST) 1343817010500 2012-08-01T10:30:10.500Z
+Thu Aug 02 2012 12:30:10 GMT+0200 (CEST) 1343903410500 2012-08-02T10:30:10.500Z
+Fri Aug 03 2012 12:30:10 GMT+0200 (CEST) 1343989810500 2012-08-03T10:30:10.500Z
+Sat Aug 04 2012 12:30:10 GMT+0200 (CEST) 1344076210500 2012-08-04T10:30:10.500Z
+Sun Aug 05 2012 12:30:10 GMT+0200 (CEST) 1344162610500 2012-08-05T10:30:10.500Z
+Mon Aug 06 2012 12:30:10 GMT+0200 (CEST) 1344249010500 2012-08-06T10:30:10.500Z
+Tue Aug 07 2012 12:30:10 GMT+0200 (CEST) 1344335410500 2012-08-07T10:30:10.500Z
+Wed Aug 08 2012 12:30:10 GMT+0200 (CEST) 1344421810500 2012-08-08T10:30:10.500Z
+Thu Aug 09 2012 12:30:10 GMT+0200 (CEST) 1344508210500 2012-08-09T10:30:10.500Z
+Fri Aug 10 2012 12:30:10 GMT+0200 (CEST) 1344594610500 2012-08-10T10:30:10.500Z
+Sat Aug 11 2012 12:30:10 GMT+0200 (CEST) 1344681010500 2012-08-11T10:30:10.500Z
+Sun Aug 12 2012 12:30:10 GMT+0200 (CEST) 1344767410500 2012-08-12T10:30:10.500Z
+Mon Aug 13 2012 12:30:10 GMT+0200 (CEST) 1344853810500 2012-08-13T10:30:10.500Z
+Tue Aug 14 2012 12:30:10 GMT+0200 (CEST) 1344940210500 2012-08-14T10:30:10.500Z
+Wed Aug 15 2012 12:30:10 GMT+0200 (CEST) 1345026610500 2012-08-15T10:30:10.500Z
+Thu Aug 16 2012 12:30:10 GMT+0200 (CEST) 1345113010500 2012-08-16T10:30:10.500Z
+Fri Aug 17 2012 12:30:10 GMT+0200 (CEST) 1345199410500 2012-08-17T10:30:10.500Z
+Sat Aug 18 2012 12:30:10 GMT+0200 (CEST) 1345285810500 2012-08-18T10:30:10.500Z
+Sun Aug 19 2012 12:30:10 GMT+0200 (CEST) 1345372210500 2012-08-19T10:30:10.500Z
+Mon Aug 20 2012 12:30:10 GMT+0200 (CEST) 1345458610500 2012-08-20T10:30:10.500Z
+Tue Aug 21 2012 12:30:10 GMT+0200 (CEST) 1345545010500 2012-08-21T10:30:10.500Z
+Wed Aug 22 2012 12:30:10 GMT+0200 (CEST) 1345631410500 2012-08-22T10:30:10.500Z
+Thu Aug 23 2012 12:30:10 GMT+0200 (CEST) 1345717810500 2012-08-23T10:30:10.500Z
+Fri Aug 24 2012 12:30:10 GMT+0200 (CEST) 1345804210500 2012-08-24T10:30:10.500Z
+Sat Aug 25 2012 12:30:10 GMT+0200 (CEST) 1345890610500 2012-08-25T10:30:10.500Z
+Sun Aug 26 2012 12:30:10 GMT+0200 (CEST) 1345977010500 2012-08-26T10:30:10.500Z
+Mon Aug 27 2012 12:30:10 GMT+0200 (CEST) 1346063410500 2012-08-27T10:30:10.500Z
+Tue Aug 28 2012 12:30:10 GMT+0200 (CEST) 1346149810500 2012-08-28T10:30:10.500Z
+Wed Aug 29 2012 12:30:10 GMT+0200 (CEST) 1346236210500 2012-08-29T10:30:10.500Z
+Thu Aug 30 2012 12:30:10 GMT+0200 (CEST) 1346322610500 2012-08-30T10:30:10.500Z
+Fri Aug 31 2012 12:30:10 GMT+0200 (CEST) 1346409010500 2012-08-31T10:30:10.500Z
+Sat Sep 01 2012 12:30:10 GMT+0200 (CEST) 1346495410500 2012-09-01T10:30:10.500Z
+Sun Sep 02 2012 12:30:10 GMT+0200 (CEST) 1346581810500 2012-09-02T10:30:10.500Z
+Mon Sep 03 2012 12:30:10 GMT+0200 (CEST) 1346668210500 2012-09-03T10:30:10.500Z
+Tue Sep 04 2012 12:30:10 GMT+0200 (CEST) 1346754610500 2012-09-04T10:30:10.500Z
+Wed Sep 05 2012 12:30:10 GMT+0200 (CEST) 1346841010500 2012-09-05T10:30:10.500Z
+Thu Sep 06 2012 12:30:10 GMT+0200 (CEST) 1346927410500 2012-09-06T10:30:10.500Z
+Fri Sep 07 2012 12:30:10 GMT+0200 (CEST) 1347013810500 2012-09-07T10:30:10.500Z
+Sat Sep 08 2012 12:30:10 GMT+0200 (CEST) 1347100210500 2012-09-08T10:30:10.500Z
+Sun Sep 09 2012 12:30:10 GMT+0200 (CEST) 1347186610500 2012-09-09T10:30:10.500Z
+Mon Sep 10 2012 12:30:10 GMT+0200 (CEST) 1347273010500 2012-09-10T10:30:10.500Z
+Tue Sep 11 2012 12:30:10 GMT+0200 (CEST) 1347359410500 2012-09-11T10:30:10.500Z
+Wed Sep 12 2012 12:30:10 GMT+0200 (CEST) 1347445810500 2012-09-12T10:30:10.500Z
+Thu Sep 13 2012 12:30:10 GMT+0200 (CEST) 1347532210500 2012-09-13T10:30:10.500Z
+Fri Sep 14 2012 12:30:10 GMT+0200 (CEST) 1347618610500 2012-09-14T10:30:10.500Z
+Sat Sep 15 2012 12:30:10 GMT+0200 (CEST) 1347705010500 2012-09-15T10:30:10.500Z
+Sun Sep 16 2012 12:30:10 GMT+0200 (CEST) 1347791410500 2012-09-16T10:30:10.500Z
+Mon Sep 17 2012 12:30:10 GMT+0200 (CEST) 1347877810500 2012-09-17T10:30:10.500Z
+Tue Sep 18 2012 12:30:10 GMT+0200 (CEST) 1347964210500 2012-09-18T10:30:10.500Z
+Wed Sep 19 2012 12:30:10 GMT+0200 (CEST) 1348050610500 2012-09-19T10:30:10.500Z
+Thu Sep 20 2012 12:30:10 GMT+0200 (CEST) 1348137010500 2012-09-20T10:30:10.500Z
+Fri Sep 21 2012 12:30:10 GMT+0200 (CEST) 1348223410500 2012-09-21T10:30:10.500Z
+Sat Sep 22 2012 12:30:10 GMT+0200 (CEST) 1348309810500 2012-09-22T10:30:10.500Z
+Sun Sep 23 2012 12:30:10 GMT+0200 (CEST) 1348396210500 2012-09-23T10:30:10.500Z
+Mon Sep 24 2012 12:30:10 GMT+0200 (CEST) 1348482610500 2012-09-24T10:30:10.500Z
+Tue Sep 25 2012 12:30:10 GMT+0200 (CEST) 1348569010500 2012-09-25T10:30:10.500Z
+Wed Sep 26 2012 12:30:10 GMT+0200 (CEST) 1348655410500 2012-09-26T10:30:10.500Z
+Thu Sep 27 2012 12:30:10 GMT+0200 (CEST) 1348741810500 2012-09-27T10:30:10.500Z
+Fri Sep 28 2012 12:30:10 GMT+0200 (CEST) 1348828210500 2012-09-28T10:30:10.500Z
+Sat Sep 29 2012 12:30:10 GMT+0200 (CEST) 1348914610500 2012-09-29T10:30:10.500Z
+Sun Sep 30 2012 12:30:10 GMT+0200 (CEST) 1349001010500 2012-09-30T10:30:10.500Z
+Mon Oct 01 2012 12:30:10 GMT+0200 (CEST) 1349087410500 2012-10-01T10:30:10.500Z
+Tue Oct 02 2012 12:30:10 GMT+0200 (CEST) 1349173810500 2012-10-02T10:30:10.500Z
+Wed Oct 03 2012 12:30:10 GMT+0200 (CEST) 1349260210500 2012-10-03T10:30:10.500Z
+Thu Oct 04 2012 12:30:10 GMT+0200 (CEST) 1349346610500 2012-10-04T10:30:10.500Z
+Fri Oct 05 2012 12:30:10 GMT+0200 (CEST) 1349433010500 2012-10-05T10:30:10.500Z
+Sat Oct 06 2012 12:30:10 GMT+0200 (CEST) 1349519410500 2012-10-06T10:30:10.500Z
+Sun Oct 07 2012 12:30:10 GMT+0200 (CEST) 1349605810500 2012-10-07T10:30:10.500Z
+Mon Oct 08 2012 12:30:10 GMT+0200 (CEST) 1349692210500 2012-10-08T10:30:10.500Z
+Tue Oct 09 2012 12:30:10 GMT+0200 (CEST) 1349778610500 2012-10-09T10:30:10.500Z
+Wed Oct 10 2012 12:30:10 GMT+0200 (CEST) 1349865010500 2012-10-10T10:30:10.500Z
+Thu Oct 11 2012 12:30:10 GMT+0200 (CEST) 1349951410500 2012-10-11T10:30:10.500Z
+Fri Oct 12 2012 12:30:10 GMT+0200 (CEST) 1350037810500 2012-10-12T10:30:10.500Z
+Sat Oct 13 2012 12:30:10 GMT+0200 (CEST) 1350124210500 2012-10-13T10:30:10.500Z
+Sun Oct 14 2012 12:30:10 GMT+0200 (CEST) 1350210610500 2012-10-14T10:30:10.500Z
+Mon Oct 15 2012 12:30:10 GMT+0200 (CEST) 1350297010500 2012-10-15T10:30:10.500Z
+Tue Oct 16 2012 12:30:10 GMT+0200 (CEST) 1350383410500 2012-10-16T10:30:10.500Z
+Wed Oct 17 2012 12:30:10 GMT+0200 (CEST) 1350469810500 2012-10-17T10:30:10.500Z
+Thu Oct 18 2012 12:30:10 GMT+0200 (CEST) 1350556210500 2012-10-18T10:30:10.500Z
+Fri Oct 19 2012 12:30:10 GMT+0200 (CEST) 1350642610500 2012-10-19T10:30:10.500Z
+Sat Oct 20 2012 12:30:10 GMT+0200 (CEST) 1350729010500 2012-10-20T10:30:10.500Z
+Sun Oct 21 2012 12:30:10 GMT+0200 (CEST) 1350815410500 2012-10-21T10:30:10.500Z
+Mon Oct 22 2012 12:30:10 GMT+0200 (CEST) 1350901810500 2012-10-22T10:30:10.500Z
+Tue Oct 23 2012 12:30:10 GMT+0200 (CEST) 1350988210500 2012-10-23T10:30:10.500Z
+Wed Oct 24 2012 12:30:10 GMT+0200 (CEST) 1351074610500 2012-10-24T10:30:10.500Z
+Thu Oct 25 2012 12:30:10 GMT+0200 (CEST) 1351161010500 2012-10-25T10:30:10.500Z
+Fri Oct 26 2012 12:30:10 GMT+0200 (CEST) 1351247410500 2012-10-26T10:30:10.500Z
+Sat Oct 27 2012 12:30:10 GMT+0200 (CEST) 1351333810500 2012-10-27T10:30:10.500Z
+Sun Oct 28 2012 12:30:10 GMT+0100 (CET) 1351423810500 2012-10-28T11:30:10.500Z
+Mon Oct 29 2012 12:30:10 GMT+0100 (CET) 1351510210500 2012-10-29T11:30:10.500Z
+Tue Oct 30 2012 12:30:10 GMT+0100 (CET) 1351596610500 2012-10-30T11:30:10.500Z
+Wed Oct 31 2012 12:30:10 GMT+0100 (CET) 1351683010500 2012-10-31T11:30:10.500Z
+Thu Nov 01 2012 12:30:10 GMT+0100 (CET) 1351769410500 2012-11-01T11:30:10.500Z
+Fri Nov 02 2012 12:30:10 GMT+0100 (CET) 1351855810500 2012-11-02T11:30:10.500Z
+Sat Nov 03 2012 12:30:10 GMT+0100 (CET) 1351942210500 2012-11-03T11:30:10.500Z
+Sun Nov 04 2012 12:30:10 GMT+0100 (CET) 1352028610500 2012-11-04T11:30:10.500Z
+Mon Nov 05 2012 12:30:10 GMT+0100 (CET) 1352115010500 2012-11-05T11:30:10.500Z
+Tue Nov 06 2012 12:30:10 GMT+0100 (CET) 1352201410500 2012-11-06T11:30:10.500Z
+Wed Nov 07 2012 12:30:10 GMT+0100 (CET) 1352287810500 2012-11-07T11:30:10.500Z
+Thu Nov 08 2012 12:30:10 GMT+0100 (CET) 1352374210500 2012-11-08T11:30:10.500Z
+Fri Nov 09 2012 12:30:10 GMT+0100 (CET) 1352460610500 2012-11-09T11:30:10.500Z
+Sat Nov 10 2012 12:30:10 GMT+0100 (CET) 1352547010500 2012-11-10T11:30:10.500Z
+Sun Nov 11 2012 12:30:10 GMT+0100 (CET) 1352633410500 2012-11-11T11:30:10.500Z
+Mon Nov 12 2012 12:30:10 GMT+0100 (CET) 1352719810500 2012-11-12T11:30:10.500Z
+Tue Nov 13 2012 12:30:10 GMT+0100 (CET) 1352806210500 2012-11-13T11:30:10.500Z
+Wed Nov 14 2012 12:30:10 GMT+0100 (CET) 1352892610500 2012-11-14T11:30:10.500Z
+Thu Nov 15 2012 12:30:10 GMT+0100 (CET) 1352979010500 2012-11-15T11:30:10.500Z
+Fri Nov 16 2012 12:30:10 GMT+0100 (CET) 1353065410500 2012-11-16T11:30:10.500Z
+Sat Nov 17 2012 12:30:10 GMT+0100 (CET) 1353151810500 2012-11-17T11:30:10.500Z
+Sun Nov 18 2012 12:30:10 GMT+0100 (CET) 1353238210500 2012-11-18T11:30:10.500Z
+Mon Nov 19 2012 12:30:10 GMT+0100 (CET) 1353324610500 2012-11-19T11:30:10.500Z
+Tue Nov 20 2012 12:30:10 GMT+0100 (CET) 1353411010500 2012-11-20T11:30:10.500Z
+Wed Nov 21 2012 12:30:10 GMT+0100 (CET) 1353497410500 2012-11-21T11:30:10.500Z
+Thu Nov 22 2012 12:30:10 GMT+0100 (CET) 1353583810500 2012-11-22T11:30:10.500Z
+Fri Nov 23 2012 12:30:10 GMT+0100 (CET) 1353670210500 2012-11-23T11:30:10.500Z
+Sat Nov 24 2012 12:30:10 GMT+0100 (CET) 1353756610500 2012-11-24T11:30:10.500Z
+Sun Nov 25 2012 12:30:10 GMT+0100 (CET) 1353843010500 2012-11-25T11:30:10.500Z
+Mon Nov 26 2012 12:30:10 GMT+0100 (CET) 1353929410500 2012-11-26T11:30:10.500Z
+Tue Nov 27 2012 12:30:10 GMT+0100 (CET) 1354015810500 2012-11-27T11:30:10.500Z
+Wed Nov 28 2012 12:30:10 GMT+0100 (CET) 1354102210500 2012-11-28T11:30:10.500Z
+Thu Nov 29 2012 12:30:10 GMT+0100 (CET) 1354188610500 2012-11-29T11:30:10.500Z
+Fri Nov 30 2012 12:30:10 GMT+0100 (CET) 1354275010500 2012-11-30T11:30:10.500Z
+Sat Dec 01 2012 12:30:10 GMT+0100 (CET) 1354361410500 2012-12-01T11:30:10.500Z
+Sun Dec 02 2012 12:30:10 GMT+0100 (CET) 1354447810500 2012-12-02T11:30:10.500Z
+Mon Dec 03 2012 12:30:10 GMT+0100 (CET) 1354534210500 2012-12-03T11:30:10.500Z
+Tue Dec 04 2012 12:30:10 GMT+0100 (CET) 1354620610500 2012-12-04T11:30:10.500Z
+Wed Dec 05 2012 12:30:10 GMT+0100 (CET) 1354707010500 2012-12-05T11:30:10.500Z
+Thu Dec 06 2012 12:30:10 GMT+0100 (CET) 1354793410500 2012-12-06T11:30:10.500Z
+Fri Dec 07 2012 12:30:10 GMT+0100 (CET) 1354879810500 2012-12-07T11:30:10.500Z
+Sat Dec 08 2012 12:30:10 GMT+0100 (CET) 1354966210500 2012-12-08T11:30:10.500Z
+Sun Dec 09 2012 12:30:10 GMT+0100 (CET) 1355052610500 2012-12-09T11:30:10.500Z
+Mon Dec 10 2012 12:30:10 GMT+0100 (CET) 1355139010500 2012-12-10T11:30:10.500Z
+Tue Dec 11 2012 12:30:10 GMT+0100 (CET) 1355225410500 2012-12-11T11:30:10.500Z
+Wed Dec 12 2012 12:30:10 GMT+0100 (CET) 1355311810500 2012-12-12T11:30:10.500Z
+Thu Dec 13 2012 12:30:10 GMT+0100 (CET) 1355398210500 2012-12-13T11:30:10.500Z
+Fri Dec 14 2012 12:30:10 GMT+0100 (CET) 1355484610500 2012-12-14T11:30:10.500Z
+Sat Dec 15 2012 12:30:10 GMT+0100 (CET) 1355571010500 2012-12-15T11:30:10.500Z
+Sun Dec 16 2012 12:30:10 GMT+0100 (CET) 1355657410500 2012-12-16T11:30:10.500Z
+Mon Dec 17 2012 12:30:10 GMT+0100 (CET) 1355743810500 2012-12-17T11:30:10.500Z
+Tue Dec 18 2012 12:30:10 GMT+0100 (CET) 1355830210500 2012-12-18T11:30:10.500Z
+Wed Dec 19 2012 12:30:10 GMT+0100 (CET) 1355916610500 2012-12-19T11:30:10.500Z
+Thu Dec 20 2012 12:30:10 GMT+0100 (CET) 1356003010500 2012-12-20T11:30:10.500Z
+Fri Dec 21 2012 12:30:10 GMT+0100 (CET) 1356089410500 2012-12-21T11:30:10.500Z
+Sat Dec 22 2012 12:30:10 GMT+0100 (CET) 1356175810500 2012-12-22T11:30:10.500Z
+Sun Dec 23 2012 12:30:10 GMT+0100 (CET) 1356262210500 2012-12-23T11:30:10.500Z
+Mon Dec 24 2012 12:30:10 GMT+0100 (CET) 1356348610500 2012-12-24T11:30:10.500Z
+Tue Dec 25 2012 12:30:10 GMT+0100 (CET) 1356435010500 2012-12-25T11:30:10.500Z
+Wed Dec 26 2012 12:30:10 GMT+0100 (CET) 1356521410500 2012-12-26T11:30:10.500Z
+Thu Dec 27 2012 12:30:10 GMT+0100 (CET) 1356607810500 2012-12-27T11:30:10.500Z
+Fri Dec 28 2012 12:30:10 GMT+0100 (CET) 1356694210500 2012-12-28T11:30:10.500Z
+Sat Dec 29 2012 12:30:10 GMT+0100 (CET) 1356780610500 2012-12-29T11:30:10.500Z
+Sun Dec 30 2012 12:30:10 GMT+0100 (CET) 1356867010500 2012-12-30T11:30:10.500Z
+Mon Dec 31 2012 12:30:10 GMT+0100 (CET) 1356953410500 2012-12-31T11:30:10.500Z
+Tue Jan 01 2013 12:30:10 GMT+0100 (CET) 1357039810500 2013-01-01T11:30:10.500Z
+Wed Jan 02 2013 12:30:10 GMT+0100 (CET) 1357126210500 2013-01-02T11:30:10.500Z
+Thu Jan 03 2013 12:30:10 GMT+0100 (CET) 1357212610500 2013-01-03T11:30:10.500Z
+Fri Jan 04 2013 12:30:10 GMT+0100 (CET) 1357299010500 2013-01-04T11:30:10.500Z
+Sat Jan 05 2013 12:30:10 GMT+0100 (CET) 1357385410500 2013-01-05T11:30:10.500Z
+Sun Jan 06 2013 12:30:10 GMT+0100 (CET) 1357471810500 2013-01-06T11:30:10.500Z
+Mon Jan 07 2013 12:30:10 GMT+0100 (CET) 1357558210500 2013-01-07T11:30:10.500Z
+Tue Jan 08 2013 12:30:10 GMT+0100 (CET) 1357644610500 2013-01-08T11:30:10.500Z
+Wed Jan 09 2013 12:30:10 GMT+0100 (CET) 1357731010500 2013-01-09T11:30:10.500Z
+Thu Jan 10 2013 12:30:10 GMT+0100 (CET) 1357817410500 2013-01-10T11:30:10.500Z
+Fri Jan 11 2013 12:30:10 GMT+0100 (CET) 1357903810500 2013-01-11T11:30:10.500Z
+Sat Jan 12 2013 12:30:10 GMT+0100 (CET) 1357990210500 2013-01-12T11:30:10.500Z
+Sun Jan 13 2013 12:30:10 GMT+0100 (CET) 1358076610500 2013-01-13T11:30:10.500Z
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Thu Mar 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Mon Dec 25 1995 10:00:00 GMT+0100 (CET)
+ok Mon Dec 25 1995 10:00:00 GMT+0100 (CET)
+ok Mon Dec 25 1995 10:00:00 GMT+0100 (CET)
+ok Mon Dec 25 1995 10:00:00 GMT+0100 (CET)
+ok Invalid Date
+ok Invalid Date
+ok Invalid Date
+ok Invalid Date
+ok Invalid Date
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
+ok Sun Jan 01 2012 09:00:00 GMT+0100 (CET)
diff --git a/nashorn/test/script/basic/NASHORN-63.js b/nashorn/test/script/basic/NASHORN-63.js
new file mode 100644
index 0000000..f1178de
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-63.js
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-63 :  equality and strict equality implementations are broken.
+ *
+ * @test
+ * @run
+ */
+
+function error(msg) {
+    print("Error: " + msg);
+}
+
+if ((new Boolean(true) != new Boolean(true)) !== true) {
+    error('Different Boolean objects are equal');
+}
+
+if ((new Boolean(false) != new Boolean(false)) !== true) {
+    error('Different Boolean objects are equal');
+}
+
+if ((new Boolean(true) != new Boolean(false)) !== true) {
+    error('Different Boolean objects are equal');
+}
+
+if ((new Number(3.14) != new Number(3.14)) !== true) {
+    error('Different Number objects are equal');
+}
+
+if ((new Number(2.718) != new Number(3.14)) !== true) {
+    error('Different Number objects are equal');
+}
+
+if ((new String("nashorn") != new String("nashorn")) !== true) {
+    error('Different String objects are equal');
+}
+
+if ((new String("ecmascript") != new String("nashorn")) !== true) {
+    error('Different String objects are equal');
+}
+
+if ((new Object() != new Object()) !== true) {
+    error('Different Objects are equal');
+}
+
+var obj1 = {}; 
+var obj2 = obj1;
+if (obj1 != obj2) {
+    error(' Same object literals are not equal');
+}
+
+if ((new Boolean(0) != new Number(0)) !== true) {
+    error('a Boolean and a Number object are equal');
+}
+
+if ((new Number(42) != new String("42")) !== true) {
+    error('a Number and a String object are equal');
+}
+
+if ((new String("1") != new Boolean(true)) !== true) {
+    error('a String and a Boolean object are equal');
+}
+
+// strict equality checks
+if ((new String("abc")) === "abc") {
+    error('a String and a primitive string are strict equal');
+}
+
+if ((new Number(42)) === 42) {
+    error('a Number and a primitive number are strict equal');
+}
+
+if ((new Boolean(true)) === true) {
+    error('a Boolean and a primitive boolean are strict equal');
+}
+
+if ((new Boolean(false)) === false) {
+    error('a Boolean and a primitive boolean are strict equal');
+}
+
+if ((new Object()) === (new Object())) {
+    error('two different Objects are strict strict equal');
+}
+
+if ({} === {}) {
+    error('two different Objects are strict strict equal');
+}
diff --git a/nashorn/test/script/basic/NASHORN-631.js.EXPECTED b/nashorn/test/script/basic/NASHORN-631.js.EXPECTED
new file mode 100644
index 0000000..da24fe6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-631.js.EXPECTED
@@ -0,0 +1,3917 @@
+9.53674316 e-7
+-9.5367431 e-7
+4.76837158 e-7
+-4.7683715 e-7
+2.38418579 e-7
+-2.3841857 e-7
+1.19209289 e-7
+-1.1920928 e-7
+5.96046447 e-8
+-5.9604644 e-8
+2.98023223 e-8
+-2.9802322 e-8
+1.49011611 e-8
+-1.4901161 e-8
+7.45058059 e-9
+-7.4505805 e-9
+3.72529029 e-9
+-3.7252902 e-9
+1.86264514 e-9
+-1.8626451 e-9
+9.31322574 e-10
+-9.3132257 e-10
+4.65661287 e-10
+-4.6566128 e-10
+2.32830643 e-10
+-2.3283064 e-10
+1.16415321 e-10
+-1.1641532 e-10
+5.82076609 e-11
+-5.8207660 e-11
+2.91038304 e-11
+-2.9103830 e-11
+1.45519152 e-11
+-1.4551915 e-11
+7.27595761 e-12
+-7.2759576 e-12
+3.63797880 e-12
+-3.6379788 e-12
+1.81898940 e-12
+-1.8189894 e-12
+9.09494701 e-13
+-9.0949470 e-13
+4.54747350 e-13
+-4.5474735 e-13
+2.27373675 e-13
+-2.2737367 e-13
+1.13686837 e-13
+-1.1368683 e-13
+5.68434188 e-14
+-5.6843418 e-14
+2.84217094 e-14
+-2.8421709 e-14
+1.42108547 e-14
+-1.4210854 e-14
+7.10542735 e-15
+-7.1054273 e-15
+3.55271367 e-15
+-3.5527136 e-15
+1.77635683 e-15
+-1.7763568 e-15
+8.88178419 e-16
+-8.8817841 e-16
+4.44089209 e-16
+-4.4408920 e-16
+2.22044604 e-16
+-2.2204460 e-16
+1.11022302 e-16
+-1.1102230 e-16
+5.55111512 e-17
+-5.5511151 e-17
+2.77555756 e-17
+-2.7755575 e-17
+1.38777878 e-17
+-1.3877787 e-17
+6.93889390 e-18
+-6.9388939 e-18
+3.46944695 e-18
+-3.4694469 e-18
+1.73472347 e-18
+-1.7347234 e-18
+8.67361737 e-19
+-8.6736173 e-19
+4.33680868 e-19
+-4.3368086 e-19
+2.16840434 e-19
+-2.1684043 e-19
+1.08420217 e-19
+-1.0842021 e-19
+5.42101086 e-20
+-5.4210108 e-20
+2.71050543 e-20
+-2.7105054 e-20
+1.35525271 e-20
+-1.3552527 e-20
+6.77626357 e-21
+-6.7762635 e-21
+3.38813178 e-21
+-3.3881317 e-21
+1.69406589 e-21
+-1.6940658 e-21
+1.18059162 e+21
+-1.1805916 e+21
+8.47032947 e-22
+-8.4703294 e-22
+2.36118324 e+21
+-2.3611832 e+21
+4.23516473 e-22
+-4.2351647 e-22
+4.72236648 e+21
+-4.7223664 e+21
+2.11758236 e-22
+-2.1175823 e-22
+9.44473296 e+21
+-9.4447329 e+21
+1.05879118 e-22
+-1.0587911 e-22
+1.88894659 e+22
+-1.8889465 e+22
+5.29395592 e-23
+-5.2939559 e-23
+3.77789318 e+22
+-3.7778931 e+22
+2.64697796 e-23
+-2.6469779 e-23
+7.55578637 e+22
+-7.5557863 e+22
+1.32348898 e-23
+-1.3234889 e-23
+1.51115727 e+23
+-1.5111572 e+23
+6.61744490 e-24
+-6.6174449 e-24
+3.02231454 e+23
+-3.0223145 e+23
+3.30872245 e-24
+-3.3087224 e-24
+6.04462909 e+23
+-6.0446290 e+23
+1.65436122 e-24
+-1.6543612 e-24
+1.20892581 e+24
+-1.2089258 e+24
+8.27180612 e-25
+-8.2718061 e-25
+2.41785163 e+24
+-2.4178516 e+24
+4.13590306 e-25
+-4.1359030 e-25
+4.83570327 e+24
+-4.8357032 e+24
+2.06795153 e-25
+-2.0679515 e-25
+9.67140655 e+24
+-9.6714065 e+24
+1.03397576 e-25
+-1.0339757 e-25
+1.93428131 e+25
+-1.9342813 e+25
+5.16987882 e-26
+-5.1698788 e-26
+3.86856262 e+25
+-3.8685626 e+25
+2.58493941 e-26
+-2.5849394 e-26
+7.73712524 e+25
+-7.7371252 e+25
+1.29246970 e-26
+-1.2924697 e-26
+1.54742504 e+26
+-1.5474250 e+26
+6.46234853 e-27
+-6.4623485 e-27
+3.09485009 e+26
+-3.0948500 e+26
+3.23117426 e-27
+-3.2311742 e-27
+6.18970019 e+26
+-6.1897001 e+26
+1.61558713 e-27
+-1.6155871 e-27
+1.23794003 e+27
+-1.2379400 e+27
+8.07793566 e-28
+-8.0779356 e-28
+2.47588007 e+27
+-2.4758800 e+27
+4.03896783 e-28
+-4.0389678 e-28
+4.95176015 e+27
+-4.9517601 e+27
+2.01948391 e-28
+-2.0194839 e-28
+9.90352031 e+27
+-9.9035203 e+27
+1.00974195 e-28
+-1.0097419 e-28
+1.98070406 e+28
+-1.9807040 e+28
+5.04870979 e-29
+-5.0487097 e-29
+3.96140812 e+28
+-3.9614081 e+28
+2.52435489 e-29
+-2.5243548 e-29
+7.92281625 e+28
+-7.9228162 e+28
+1.26217744 e-29
+-1.2621774 e-29
+1.58456325 e+29
+-1.5845632 e+29
+6.31088724 e-30
+-6.3108872 e-30
+3.16912650 e+29
+-3.1691265 e+29
+3.15544362 e-30
+-3.1554436 e-30
+6.33825300 e+29
+-6.3382530 e+29
+1.57772181 e-30
+-1.5777218 e-30
+1.26765060 e+30
+-1.2676506 e+30
+7.88860905 e-31
+-7.8886090 e-31
+2.53530120 e+30
+-2.5353012 e+30
+3.94430452 e-31
+-3.9443045 e-31
+5.07060240 e+30
+-5.0706024 e+30
+1.97215226 e-31
+-1.9721522 e-31
+1.01412048 e+31
+-1.0141204 e+31
+9.86076131 e-32
+-9.8607613 e-32
+2.02824096 e+31
+-2.0282409 e+31
+4.93038065 e-32
+-4.9303806 e-32
+4.05648192 e+31
+-4.0564819 e+31
+2.46519032 e-32
+-2.4651903 e-32
+8.11296384 e+31
+-8.1129638 e+31
+1.23259516 e-32
+-1.2325951 e-32
+1.62259276 e+32
+-1.6225927 e+32
+6.16297582 e-33
+-6.1629758 e-33
+3.24518553 e+32
+-3.2451855 e+32
+3.08148791 e-33
+-3.0814879 e-33
+6.49037107 e+32
+-6.4903710 e+32
+1.54074395 e-33
+-1.5407439 e-33
+1.29807421 e+33
+-1.2980742 e+33
+7.70371977 e-34
+-7.7037197 e-34
+2.59614842 e+33
+-2.5961484 e+33
+3.85185988 e-34
+-3.8518598 e-34
+5.19229685 e+33
+-5.1922968 e+33
+1.92592994 e-34
+-1.9259299 e-34
+1.03845937 e+34
+-1.0384593 e+34
+9.62964972 e-35
+-9.6296497 e-35
+2.07691874 e+34
+-2.0769187 e+34
+4.81482486 e-35
+-4.8148248 e-35
+4.15383748 e+34
+-4.1538374 e+34
+2.40741243 e-35
+-2.4074124 e-35
+8.30767497 e+34
+-8.3076749 e+34
+1.20370621 e-35
+-1.2037062 e-35
+1.66153499 e+35
+-1.6615349 e+35
+6.01853107 e-36
+-6.0185310 e-36
+3.32306998 e+35
+-3.3230699 e+35
+3.00926553 e-36
+-3.0092655 e-36
+6.64613997 e+35
+-6.6461399 e+35
+1.50463276 e-36
+-1.5046327 e-36
+1.32922799 e+36
+-1.3292279 e+36
+7.52316384 e-37
+-7.5231638 e-37
+2.65845599 e+36
+-2.6584559 e+36
+3.76158192 e-37
+-3.7615819 e-37
+5.31691198 e+36
+-5.3169119 e+36
+1.88079096 e-37
+-1.8807909 e-37
+1.06338239 e+37
+-1.0633823 e+37
+9.40395480 e-38
+-9.4039548 e-38
+2.12676479 e+37
+-2.1267647 e+37
+4.70197740 e-38
+-4.7019774 e-38
+4.25352958 e+37
+-4.2535295 e+37
+2.35098870 e-38
+-2.3509887 e-38
+8.50705917 e+37
+-8.5070591 e+37
+1.17549435 e-38
+-1.1754943 e-38
+1.70141183 e+38
+-1.7014118 e+38
+5.87747175 e-39
+-5.8774717 e-39
+3.40282366 e+38
+-3.4028236 e+38
+2.93873587 e-39
+-2.9387358 e-39
+6.80564733 e+38
+-6.8056473 e+38
+1.46936793 e-39
+-1.4693679 e-39
+1.36112946 e+39
+-1.3611294 e+39
+7.34683969 e-40
+-7.3468396 e-40
+2.72225893 e+39
+-2.7222589 e+39
+3.67341984 e-40
+-3.6734198 e-40
+5.44451787 e+39
+-5.4445178 e+39
+1.83670992 e-40
+-1.8367099 e-40
+1.08890357 e+40
+-1.0889035 e+40
+9.18354961 e-41
+-9.1835496 e-41
+2.17780714 e+40
+-2.1778071 e+40
+4.59177480 e-41
+-4.5917748 e-41
+4.35561429 e+40
+-4.3556142 e+40
+2.29588740 e-41
+-2.2958874 e-41
+8.71122859 e+40
+-8.7112285 e+40
+1.14794370 e-41
+-1.1479437 e-41
+1.74224571 e+41
+-1.7422457 e+41
+5.73971850 e-42
+-5.7397185 e-42
+3.48449143 e+41
+-3.4844914 e+41
+2.86985925 e-42
+-2.8698592 e-42
+6.96898287 e+41
+-6.9689828 e+41
+1.43492962 e-42
+-1.4349296 e-42
+1.39379657 e+42
+-1.3937965 e+42
+7.17464813 e-43
+-7.1746481 e-43
+2.78759314 e+42
+-2.7875931 e+42
+3.58732406 e-43
+-3.5873240 e-43
+5.57518629 e+42
+-5.5751862 e+42
+1.79366203 e-43
+-1.7936620 e-43
+1.11503725 e+43
+-1.1150372 e+43
+8.96831017 e-44
+-8.9683101 e-44
+2.23007451 e+43
+-2.2300745 e+43
+4.48415508 e-44
+-4.4841550 e-44
+4.46014903 e+43
+-4.4601490 e+43
+2.24207754 e-44
+-2.2420775 e-44
+8.92029807 e+43
+-8.9202980 e+43
+1.12103877 e-44
+-1.1210387 e-44
+1.78405961 e+44
+-1.7840596 e+44
+5.60519385 e-45
+-5.6051938 e-45
+3.56811923 e+44
+-3.5681192 e+44
+2.80259692 e-45
+-2.8025969 e-45
+7.13623846 e+44
+-7.1362384 e+44
+1.40129846 e-45
+-1.4012984 e-45
+1.42724769 e+45
+-1.4272476 e+45
+7.00649232 e-46
+-7.0064923 e-46
+2.85449538 e+45
+-2.8544953 e+45
+3.50324616 e-46
+-3.5032461 e-46
+5.70899077 e+45
+-5.7089907 e+45
+1.75162308 e-46
+-1.7516230 e-46
+1.14179815 e+46
+-1.1417981 e+46
+8.75811540 e-47
+-8.7581154 e-47
+2.28359630 e+46
+-2.2835963 e+46
+4.37905770 e-47
+-4.3790577 e-47
+4.56719261 e+46
+-4.5671926 e+46
+2.18952885 e-47
+-2.1895288 e-47
+9.13438523 e+46
+-9.1343852 e+46
+1.09476442 e-47
+-1.0947644 e-47
+1.82687704 e+47
+-1.8268770 e+47
+5.47382212 e-48
+-5.4738221 e-48
+3.65375409 e+47
+-3.6537540 e+47
+2.73691106 e-48
+-2.7369110 e-48
+7.30750818 e+47
+-7.3075081 e+47
+1.36845553 e-48
+-1.3684555 e-48
+1.46150163 e+48
+-1.4615016 e+48
+6.84227765 e-49
+-6.8422776 e-49
+2.92300327 e+48
+-2.9230032 e+48
+3.42113882 e-49
+-3.4211388 e-49
+5.84600654 e+48
+-5.8460065 e+48
+1.71056941 e-49
+-1.7105694 e-49
+1.16920130 e+49
+-1.1692013 e+49
+8.55284707 e-50
+-8.5528470 e-50
+2.33840261 e+49
+-2.3384026 e+49
+4.27642353 e-50
+-4.2764235 e-50
+4.67680523 e+49
+-4.6768052 e+49
+2.13821176 e-50
+-2.1382117 e-50
+9.35361047 e+49
+-9.3536104 e+49
+1.06910588 e-50
+-1.0691058 e-50
+1.87072209 e+50
+-1.8707220 e+50
+5.34552942 e-51
+-5.3455294 e-51
+3.74144419 e+50
+-3.7414441 e+50
+2.67276471 e-51
+-2.6727647 e-51
+7.48288838 e+50
+-7.4828883 e+50
+1.33638235 e-51
+-1.3363823 e-51
+1.49657767 e+51
+-1.4965776 e+51
+6.68191177 e-52
+-6.6819117 e-52
+2.99315535 e+51
+-2.9931553 e+51
+3.34095588 e-52
+-3.3409558 e-52
+5.98631070 e+51
+-5.9863107 e+51
+1.67047794 e-52
+-1.6704779 e-52
+1.19726214 e+52
+-1.1972621 e+52
+8.35238971 e-53
+-8.3523897 e-53
+2.39452428 e+52
+-2.3945242 e+52
+4.17619485 e-53
+-4.1761948 e-53
+4.78904856 e+52
+-4.7890485 e+52
+2.08809742 e-53
+-2.0880974 e-53
+9.57809713 e+52
+-9.5780971 e+52
+1.04404871 e-53
+-1.0440487 e-53
+1.91561942 e+53
+-1.9156194 e+53
+5.22024357 e-54
+-5.2202435 e-54
+3.83123885 e+53
+-3.8312388 e+53
+2.61012178 e-54
+-2.6101217 e-54
+7.66247770 e+53
+-7.6624777 e+53
+1.30506089 e-54
+-1.3050608 e-54
+1.53249554 e+54
+-1.5324955 e+54
+6.52530446 e-55
+-6.5253044 e-55
+3.06499108 e+54
+-3.0649910 e+54
+3.26265223 e-55
+-3.2626522 e-55
+6.12998216 e+54
+-6.1299821 e+54
+1.63132611 e-55
+-1.6313261 e-55
+1.22599643 e+55
+-1.2259964 e+55
+8.15663058 e-56
+-8.1566305 e-56
+2.45199286 e+55
+-2.4519928 e+55
+4.07831529 e-56
+-4.0783152 e-56
+4.90398573 e+55
+-4.9039857 e+55
+2.03915764 e-56
+-2.0391576 e-56
+9.80797146 e+55
+-9.8079714 e+55
+1.01957882 e-56
+-1.0195788 e-56
+1.96159429 e+56
+-1.9615942 e+56
+5.09789411 e-57
+-5.0978941 e-57
+3.92318858 e+56
+-3.9231885 e+56
+2.54894705 e-57
+-2.5489470 e-57
+7.84637716 e+56
+-7.8463771 e+56
+1.27447352 e-57
+-1.2744735 e-57
+1.56927543 e+57
+-1.5692754 e+57
+6.37236764 e-58
+-6.3723676 e-58
+3.13855086 e+57
+-3.1385508 e+57
+3.18618382 e-58
+-3.1861838 e-58
+6.27710173 e+57
+-6.2771017 e+57
+1.59309191 e-58
+-1.5930919 e-58
+1.25542034 e+58
+-1.2554203 e+58
+7.96545955 e-59
+-7.9654595 e-59
+2.51084069 e+58
+-2.5108406 e+58
+3.98272977 e-59
+-3.9827297 e-59
+5.02168138 e+58
+-5.0216813 e+58
+1.99136488 e-59
+-1.9913648 e-59
+1.00433627 e+59
+-1.0043362 e+59
+9.95682444 e-60
+-9.9568244 e-60
+2.00867255 e+59
+-2.0086725 e+59
+4.97841222 e-60
+-4.9784122 e-60
+4.01734511 e+59
+-4.0173451 e+59
+2.48920611 e-60
+-2.4892061 e-60
+8.03469022 e+59
+-8.0346902 e+59
+1.24460305 e-60
+-1.2446030 e-60
+1.60693804 e+60
+-1.6069380 e+60
+6.22301527 e-61
+-6.2230152 e-61
+3.21387608 e+60
+-3.2138760 e+60
+3.11150763 e-61
+-3.1115076 e-61
+6.42775217 e+60
+-6.4277521 e+60
+1.55575381 e-61
+-1.5557538 e-61
+1.28555043 e+61
+-1.2855504 e+61
+7.77876909 e-62
+-7.7787690 e-62
+2.57110087 e+61
+-2.5711008 e+61
+3.88938454 e-62
+-3.8893845 e-62
+5.14220174 e+61
+-5.1422017 e+61
+1.94469227 e-62
+-1.9446922 e-62
+1.02844034 e+62
+-1.0284403 e+62
+9.72346137 e-63
+-9.7234613 e-63
+2.05688069 e+62
+-2.0568806 e+62
+4.86173068 e-63
+-4.8617306 e-63
+4.11376139 e+62
+-4.1137613 e+62
+2.43086534 e-63
+-2.4308653 e-63
+8.22752278 e+62
+-8.2275227 e+62
+1.21543267 e-63
+-1.2154326 e-63
+1.64550455 e+63
+-1.6455045 e+63
+6.07716335 e-64
+-6.0771633 e-64
+3.29100911 e+63
+-3.2910091 e+63
+3.03858167 e-64
+-3.0385816 e-64
+6.58201822 e+63
+-6.5820182 e+63
+1.51929083 e-64
+-1.5192908 e-64
+1.31640364 e+64
+-1.3164036 e+64
+7.59645419 e-65
+-7.5964541 e-65
+2.63280729 e+64
+-2.6328072 e+64
+3.79822709 e-65
+-3.7982270 e-65
+5.26561458 e+64
+-5.2656145 e+64
+1.89911354 e-65
+-1.8991135 e-65
+1.05312291 e+65
+-1.0531229 e+65
+9.49556774 e-66
+-9.4955677 e-66
+2.10624583 e+65
+-2.1062458 e+65
+4.74778387 e-66
+-4.7477838 e-66
+4.21249166 e+65
+-4.2124916 e+65
+2.37389193 e-66
+-2.3738919 e-66
+8.42498333 e+65
+-8.4249833 e+65
+1.18694596 e-66
+-1.1869459 e-66
+1.68499666 e+66
+-1.6849966 e+66
+5.93472984 e-67
+-5.9347298 e-67
+3.36999333 e+66
+-3.3699933 e+66
+2.96736492 e-67
+-2.9673649 e-67
+6.73998666 e+66
+-6.7399866 e+66
+1.48368246 e-67
+-1.4836824 e-67
+1.34799733 e+67
+-1.3479973 e+67
+7.41841230 e-68
+-7.4184123 e-68
+2.69599466 e+67
+-2.6959946 e+67
+3.70920615 e-68
+-3.7092061 e-68
+5.39198933 e+67
+-5.3919893 e+67
+1.85460307 e-68
+-1.8546030 e-68
+1.07839786 e+68
+-1.0783978 e+68
+9.27301537 e-69
+-9.2730153 e-69
+2.15679573 e+68
+-2.1567957 e+68
+4.63650768 e-69
+-4.6365076 e-69
+4.31359146 e+68
+-4.3135914 e+68
+2.31825384 e-69
+-2.3182538 e-69
+8.62718293 e+68
+-8.6271829 e+68
+1.15912692 e-69
+-1.1591269 e-69
+1.72543658 e+69
+-1.7254365 e+69
+5.79563461 e-70
+-5.7956346 e-70
+3.45087317 e+69
+-3.4508731 e+69
+2.89781730 e-70
+-2.8978173 e-70
+6.90174634 e+69
+-6.9017463 e+69
+1.44890865 e-70
+-1.4489086 e-70
+1.38034926 e+70
+-1.3803492 e+70
+7.24454326 e-71
+-7.2445432 e-71
+2.76069853 e+70
+-2.7606985 e+70
+3.62227163 e-71
+-3.6222716 e-71
+5.52139707 e+70
+-5.5213970 e+70
+1.81113581 e-71
+-1.8111358 e-71
+1.10427941 e+71
+-1.1042794 e+71
+9.05567907 e-72
+-9.0556790 e-72
+2.20855883 e+71
+-2.2085588 e+71
+4.52783953 e-72
+-4.5278395 e-72
+4.41711766 e+71
+-4.4171176 e+71
+2.26391976 e-72
+-2.2639197 e-72
+8.83423532 e+71
+-8.8342353 e+71
+1.13195988 e-72
+-1.1319598 e-72
+1.76684706 e+72
+-1.7668470 e+72
+5.65979942 e-73
+-5.6597994 e-73
+3.53369412 e+72
+-3.5336941 e+72
+2.82989971 e-73
+-2.8298997 e-73
+7.06738825 e+72
+-7.0673882 e+72
+1.41494985 e-73
+-1.4149498 e-73
+1.41347765 e+73
+-1.4134776 e+73
+7.07474928 e-74
+-7.0747492 e-74
+2.82695530 e+73
+-2.8269553 e+73
+3.53737464 e-74
+-3.5373746 e-74
+5.65391060 e+73
+-5.6539106 e+73
+1.76868732 e-74
+-1.7686873 e-74
+1.13078212 e+74
+-1.1307821 e+74
+8.84343660 e-75
+-8.8434366 e-75
+2.26156424 e+74
+-2.2615642 e+74
+4.42171830 e-75
+-4.4217183 e-75
+4.52312848 e+74
+-4.5231284 e+74
+2.21085915 e-75
+-2.2108591 e-75
+9.04625697 e+74
+-9.0462569 e+74
+1.10542957 e-75
+-1.1054295 e-75
+1.80925139 e+75
+-1.8092513 e+75
+5.52714787 e-76
+-5.5271478 e-76
+3.61850278 e+75
+-3.6185027 e+75
+2.76357393 e-76
+-2.7635739 e-76
+7.23700557 e+75
+-7.2370055 e+75
+1.38178696 e-76
+-1.3817869 e-76
+1.44740111 e+76
+-1.4474011 e+76
+6.90893484 e-77
+-6.9089348 e-77
+2.89480223 e+76
+-2.8948022 e+76
+3.45446742 e-77
+-3.4544674 e-77
+5.78960446 e+76
+-5.7896044 e+76
+1.72723371 e-77
+-1.7272337 e-77
+1.15792089 e+77
+-1.1579208 e+77
+8.63616855 e-78
+-8.6361685 e-78
+2.31584178 e+77
+-2.3158417 e+77
+4.31808427 e-78
+-4.3180842 e-78
+4.63168356 e+77
+-4.6316835 e+77
+2.15904213 e-78
+-2.1590421 e-78
+9.26336713 e+77
+-9.2633671 e+77
+1.07952106 e-78
+-1.0795210 e-78
+1.85267342 e+78
+-1.8526734 e+78
+5.39760534 e-79
+-5.3976053 e-79
+3.70534685 e+78
+-3.7053468 e+78
+2.69880267 e-79
+-2.6988026 e-79
+7.41069371 e+78
+-7.4106937 e+78
+1.34940133 e-79
+-1.3494013 e-79
+1.48213874 e+79
+-1.4821387 e+79
+6.74700668 e-80
+-6.7470066 e-80
+2.96427748 e+79
+-2.9642774 e+79
+3.37350334 e-80
+-3.3735033 e-80
+5.92855496 e+79
+-5.9285549 e+79
+1.68675167 e-80
+-1.6867516 e-80
+1.18571099 e+80
+-1.1857109 e+80
+8.43375835 e-81
+-8.4337583 e-81
+2.37142198 e+80
+-2.3714219 e+80
+4.21687917 e-81
+-4.2168791 e-81
+4.74284397 e+80
+-4.7428439 e+80
+2.10843958 e-81
+-2.1084395 e-81
+9.48568795 e+80
+-9.4856879 e+80
+1.05421979 e-81
+-1.0542197 e-81
+1.89713759 e+81
+-1.8971375 e+81
+5.27109897 e-82
+-5.2710989 e-82
+3.79427518 e+81
+-3.7942751 e+81
+2.63554948 e-82
+-2.6355494 e-82
+7.58855036 e+81
+-7.5885503 e+81
+1.31777474 e-82
+-1.3177747 e-82
+1.51771007 e+82
+-1.5177100 e+82
+6.58887371 e-83
+-6.5888737 e-83
+3.03542014 e+82
+-3.0354201 e+82
+3.29443685 e-83
+-3.2944368 e-83
+6.07084028 e+82
+-6.0708402 e+82
+1.64721842 e-83
+-1.6472184 e-83
+1.21416805 e+83
+-1.2141680 e+83
+8.23609214 e-84
+-8.2360921 e-84
+2.42833611 e+83
+-2.4283361 e+83
+4.11804607 e-84
+-4.1180460 e-84
+4.85667223 e+83
+-4.8566722 e+83
+2.05902303 e-84
+-2.0590230 e-84
+9.71334446 e+83
+-9.7133444 e+83
+1.02951151 e-84
+-1.0295115 e-84
+1.94266889 e+84
+-1.9426688 e+84
+5.14755758 e-85
+-5.1475575 e-85
+3.88533778 e+84
+-3.8853377 e+84
+2.57377879 e-85
+-2.5737787 e-85
+7.77067556 e+84
+-7.7706755 e+84
+1.28688939 e-85
+-1.2868893 e-85
+1.55413511 e+85
+-1.5541351 e+85
+6.43444698 e-86
+-6.4344469 e-86
+3.10827022 e+85
+-3.1082702 e+85
+3.21722349 e-86
+-3.2172234 e-86
+6.21654045 e+85
+-6.2165404 e+85
+1.60861174 e-86
+-1.6086117 e-86
+1.24330809 e+86
+-1.2433080 e+86
+8.04305873 e-87
+-8.0430587 e-87
+2.48661618 e+86
+-2.4866161 e+86
+4.02152936 e-87
+-4.0215293 e-87
+4.97323236 e+86
+-4.9732323 e+86
+2.01076468 e-87
+-2.0107646 e-87
+9.94646472 e+86
+-9.9464647 e+86
+1.00538234 e-87
+-1.0053823 e-87
+1.98929294 e+87
+-1.9892929 e+87
+5.02691170 e-88
+-5.0269117 e-88
+3.97858589 e+87
+-3.9785858 e+87
+2.51345585 e-88
+-2.5134558 e-88
+7.95717178 e+87
+-7.9571717 e+87
+1.25672792 e-88
+-1.2567279 e-88
+1.59143435 e+88
+-1.5914343 e+88
+6.28363963 e-89
+-6.2836396 e-89
+3.18286871 e+88
+-3.1828687 e+88
+3.14181981 e-89
+-3.1418198 e-89
+6.36573742 e+88
+-6.3657374 e+88
+1.57090990 e-89
+-1.5709099 e-89
+1.27314748 e+89
+-1.2731474 e+89
+7.85454954 e-90
+-7.8545495 e-90
+2.54629497 e+89
+-2.5462949 e+89
+3.92727477 e-90
+-3.9272747 e-90
+5.09258994 e+89
+-5.0925899 e+89
+1.96363738 e-90
+-1.9636373 e-90
+1.01851798 e+90
+-1.0185179 e+90
+9.81818693 e-91
+-9.8181869 e-91
+2.03703597 e+90
+-2.0370359 e+90
+4.90909346 e-91
+-4.9090934 e-91
+4.07407195 e+90
+-4.0740719 e+90
+2.45454673 e-91
+-2.4545467 e-91
+8.14814390 e+90
+-8.1481439 e+90
+1.22727336 e-91
+-1.2272733 e-91
+1.62962878 e+91
+-1.6296287 e+91
+6.13636683 e-92
+-6.1363668 e-92
+3.25925756 e+91
+-3.2592575 e+91
+3.06818341 e-92
+-3.0681834 e-92
+6.51851512 e+91
+-6.5185151 e+91
+1.53409170 e-92
+-1.5340917 e-92
+1.30370302 e+92
+-1.3037030 e+92
+7.67045853 e-93
+-7.6704585 e-93
+2.60740604 e+92
+-2.6074060 e+92
+3.83522926 e-93
+-3.8352292 e-93
+5.21481209 e+92
+-5.2148120 e+92
+1.91761463 e-93
+-1.9176146 e-93
+1.04296241 e+93
+-1.0429624 e+93
+9.58807317 e-94
+-9.5880731 e-94
+2.08592483 e+93
+-2.0859248 e+93
+4.79403658 e-94
+-4.7940365 e-94
+4.17184967 e+93
+-4.1718496 e+93
+2.39701829 e-94
+-2.3970182 e-94
+8.34369935 e+93
+-8.3436993 e+93
+1.19850914 e-94
+-1.1985091 e-94
+1.66873987 e+94
+-1.6687398 e+94
+5.99254573 e-95
+-5.9925457 e-95
+3.33747974 e+94
+-3.3374797 e+94
+2.99627286 e-95
+-2.9962728 e-95
+6.67495948 e+94
+-6.6749594 e+94
+1.49813643 e-95
+-1.4981364 e-95
+1.33499189 e+95
+-1.3349918 e+95
+7.49068216 e-96
+-7.4906821 e-96
+2.66998379 e+95
+-2.6699837 e+95
+3.74534108 e-96
+-3.7453410 e-96
+5.33996758 e+95
+-5.3399675 e+95
+1.87267054 e-96
+-1.8726705 e-96
+1.06799351 e+96
+-1.0679935 e+96
+9.36335270 e-97
+-9.3633527 e-97
+2.13598703 e+96
+-2.1359870 e+96
+4.68167635 e-97
+-4.6816763 e-97
+4.27197407 e+96
+-4.2719740 e+96
+2.34083817 e-97
+-2.3408381 e-97
+8.54394814 e+96
+-8.5439481 e+96
+1.17041908 e-97
+-1.1704190 e-97
+1.70878962 e+97
+-1.7087896 e+97
+5.85209544 e-98
+-5.8520954 e-98
+3.41757925 e+97
+-3.4175792 e+97
+2.92604772 e-98
+-2.9260477 e-98
+6.83515851 e+97
+-6.8351585 e+97
+1.46302386 e-98
+-1.4630238 e-98
+1.36703170 e+98
+-1.3670317 e+98
+7.31511930 e-99
+-7.3151193 e-99
+2.73406340 e+98
+-2.7340634 e+98
+3.65755965 e-99
+-3.6575596 e-99
+5.46812681 e+98
+-5.4681268 e+98
+1.82877982 e-99
+-1.8287798 e-99
+1.09362536 e+99
+-1.0936253 e+99
+9.14389913 e-100
+-9.1438991 e-100
+2.18725072 e+99
+-2.1872507 e+99
+4.57194956 e-100
+-4.5719495 e-100
+4.37450144 e+99
+-4.3745014 e+99
+2.28597478 e-100
+-2.2859747 e-100
+8.74900289 e+99
+-8.7490028 e+99
+1.14298739 e-100
+-1.1429873 e-100
+1.74980057 e+100
+-1.7498005 e+100
+5.71493695 e-101
+-5.7149369 e-101
+3.49960115 e+100
+-3.4996011 e+100
+2.85746847 e-101
+-2.8574684 e-101
+6.99920231 e+100
+-6.9992023 e+100
+1.42873423 e-101
+-1.4287342 e-101
+1.39984046 e+101
+-1.3998404 e+101
+7.14367119 e-102
+-7.1436711 e-102
+2.79968092 e+101
+-2.7996809 e+101
+3.57183559 e-102
+-3.5718355 e-102
+5.59936185 e+101
+-5.5993618 e+101
+1.78591779 e-102
+-1.7859177 e-102
+1.11987237 e+102
+-1.1198723 e+102
+8.92958899 e-103
+-8.9295889 e-103
+2.23974474 e+102
+-2.2397447 e+102
+4.46479449 e-103
+-4.4647944 e-103
+4.47948948 e+102
+-4.4794894 e+102
+2.23239724 e-103
+-2.2323972 e-103
+8.95897896 e+102
+-8.9589789 e+102
+1.11619862 e-103
+-1.1161986 e-103
+1.79179579 e+103
+-1.7917957 e+103
+5.58099312 e-104
+-5.5809931 e-104
+3.58359158 e+103
+-3.5835915 e+103
+2.79049656 e-104
+-2.7904965 e-104
+7.16718317 e+103
+-7.1671831 e+103
+1.39524828 e-104
+-1.3952482 e-104
+1.43343663 e+104
+-1.4334366 e+104
+6.97624140 e-105
+-6.9762414 e-105
+2.86687326 e+104
+-2.8668732 e+104
+3.48812070 e-105
+-3.4881207 e-105
+5.73374653 e+104
+-5.7337465 e+104
+1.74406035 e-105
+-1.7440603 e-105
+1.14674930 e+105
+-1.1467493 e+105
+8.72030175 e-106
+-8.7203017 e-106
+2.29349861 e+105
+-2.2934986 e+105
+4.36015087 e-106
+-4.3601508 e-106
+4.58699723 e+105
+-4.5869972 e+105
+2.18007543 e-106
+-2.1800754 e-106
+9.17399446 e+105
+-9.1739944 e+105
+1.09003771 e-106
+-1.0900377 e-106
+1.83479889 e+106
+-1.8347988 e+106
+5.45018859 e-107
+-5.4501885 e-107
+3.66959778 e+106
+-3.6695977 e+106
+2.72509429 e-107
+-2.7250942 e-107
+7.33919557 e+106
+-7.3391955 e+106
+1.36254714 e-107
+-1.3625471 e-107
+1.46783911 e+107
+-1.4678391 e+107
+6.81273574 e-108
+-6.8127357 e-108
+2.93567822 e+107
+-2.9356782 e+107
+3.40636787 e-108
+-3.4063678 e-108
+5.87135645 e+107
+-5.8713564 e+107
+1.70318393 e-108
+-1.7031839 e-108
+1.17427129 e+108
+-1.1742712 e+108
+8.51591968 e-109
+-8.5159196 e-109
+2.34854258 e+108
+-2.3485425 e+108
+4.25795984 e-109
+-4.2579598 e-109
+4.69708516 e+108
+-4.6970851 e+108
+2.12897992 e-109
+-2.1289799 e-109
+9.39417033 e+108
+-9.3941703 e+108
+1.06448996 e-109
+-1.0644899 e-109
+1.87883406 e+109
+-1.8788340 e+109
+5.32244980 e-110
+-5.3224498 e-110
+3.75766813 e+109
+-3.7576681 e+109
+2.66122490 e-110
+-2.6612249 e-110
+7.51533626 e+109
+-7.5153362 e+109
+1.33061245 e-110
+-1.3306124 e-110
+1.50306725 e+110
+-1.5030672 e+110
+6.65306225 e-111
+-6.6530622 e-111
+3.00613450 e+110
+-3.0061345 e+110
+3.32653112 e-111
+-3.3265311 e-111
+6.01226901 e+110
+-6.0122690 e+110
+1.66326556 e-111
+-1.6632655 e-111
+1.20245380 e+111
+-1.2024538 e+111
+8.31632781 e-112
+-8.3163278 e-112
+2.40490760 e+111
+-2.4049076 e+111
+4.15816390 e-112
+-4.1581639 e-112
+4.80981520 e+111
+-4.8098152 e+111
+2.07908195 e-112
+-2.0790819 e-112
+9.61963041 e+111
+-9.6196304 e+111
+1.03954097 e-112
+-1.0395409 e-112
+1.92392608 e+112
+-1.9239260 e+112
+5.19770488 e-113
+-5.1977048 e-113
+3.84785216 e+112
+-3.8478521 e+112
+2.59885244 e-113
+-2.5988524 e-113
+7.69570433 e+112
+-7.6957043 e+112
+1.29942622 e-113
+-1.2994262 e-113
+1.53914086 e+113
+-1.5391408 e+113
+6.49713110 e-114
+-6.4971311 e-114
+3.07828173 e+113
+-3.0782817 e+113
+3.24856555 e-114
+-3.2485655 e-114
+6.15656346 e+113
+-6.1565634 e+113
+1.62428277 e-114
+-1.6242827 e-114
+1.23131269 e+114
+-1.2313126 e+114
+8.12141387 e-115
+-8.1214138 e-115
+2.46262538 e+114
+-2.4626253 e+114
+4.06070693 e-115
+-4.0607069 e-115
+4.92525077 e+114
+-4.9252507 e+114
+2.03035346 e-115
+-2.0303534 e-115
+9.85050154 e+114
+-9.8505015 e+114
+1.01517673 e-115
+-1.0151767 e-115
+1.97010030 e+115
+-1.9701003 e+115
+5.07588367 e-116
+-5.0758836 e-116
+3.94020061 e+115
+-3.9402006 e+115
+2.53794183 e-116
+-2.5379418 e-116
+7.88040123 e+115
+-7.8804012 e+115
+1.26897091 e-116
+-1.2689709 e-116
+1.57608024 e+116
+-1.5760802 e+116
+6.34485459 e-117
+-6.3448545 e-117
+3.15216049 e+116
+-3.1521604 e+116
+3.17242729 e-117
+-3.1724272 e-117
+6.30432099 e+116
+-6.3043209 e+116
+1.58621364 e-117
+-1.5862136 e-117
+1.26086419 e+117
+-1.2608641 e+117
+7.93106824 e-118
+-7.9310682 e-118
+2.52172839 e+117
+-2.5217283 e+117
+3.96553412 e-118
+-3.9655341 e-118
+5.04345679 e+117
+-5.0434567 e+117
+1.98276706 e-118
+-1.9827670 e-118
+1.00869135 e+118
+-1.0086913 e+118
+9.91383530 e-119
+-9.9138353 e-119
+2.01738271 e+118
+-2.0173827 e+118
+4.95691765 e-119
+-4.9569176 e-119
+4.03476543 e+118
+-4.0347654 e+118
+2.47845882 e-119
+-2.4784588 e-119
+8.06953086 e+118
+-8.0695308 e+118
+1.23922941 e-119
+-1.2392294 e-119
+1.61390617 e+119
+-1.6139061 e+119
+6.19614706 e-120
+-6.1961470 e-120
+3.22781234 e+119
+-3.2278123 e+119
+3.09807353 e-120
+-3.0980735 e-120
+6.45562469 e+119
+-6.4556246 e+119
+1.54903676 e-120
+-1.5490367 e-120
+1.29112493 e+120
+-1.2911249 e+120
+7.74518382 e-121
+-7.7451838 e-121
+2.58224987 e+120
+-2.5822498 e+120
+3.87259191 e-121
+-3.8725919 e-121
+5.16449975 e+120
+-5.1644997 e+120
+1.93629595 e-121
+-1.9362959 e-121
+1.03289995 e+121
+-1.0328999 e+121
+9.68147978 e-122
+-9.6814797 e-122
+2.06579990 e+121
+-2.0657999 e+121
+4.84073989 e-122
+-4.8407398 e-122
+4.13159980 e+121
+-4.1315998 e+121
+2.42036994 e-122
+-2.4203699 e-122
+8.26319960 e+121
+-8.2631996 e+121
+1.21018497 e-122
+-1.2101849 e-122
+1.65263992 e+122
+-1.6526399 e+122
+6.05092486 e-123
+-6.0509248 e-123
+3.30527984 e+122
+-3.3052798 e+122
+3.02546243 e-123
+-3.0254624 e-123
+6.61055968 e+122
+-6.6105596 e+122
+1.51273121 e-123
+-1.5127312 e-123
+1.32211193 e+123
+-1.3221119 e+123
+7.56365608 e-124
+-7.5636560 e-124
+2.64422387 e+123
+-2.6442238 e+123
+3.78182804 e-124
+-3.7818280 e-124
+5.28844775 e+123
+-5.2884477 e+123
+1.89091402 e-124
+-1.8909140 e-124
+1.05768955 e+124
+-1.0576895 e+124
+9.45457010 e-125
+-9.4545701 e-125
+2.11537910 e+124
+-2.1153791 e+124
+4.72728505 e-125
+-4.7272850 e-125
+4.23075820 e+124
+-4.2307582 e+124
+2.36364252 e-125
+-2.3636425 e-125
+8.46151640 e+124
+-8.4615164 e+124
+1.18182126 e-125
+-1.1818212 e-125
+1.69230328 e+125
+-1.6923032 e+125
+5.90910631 e-126
+-5.9091063 e-126
+3.38460656 e+125
+-3.3846065 e+125
+2.95455315 e-126
+-2.9545531 e-126
+6.76921312 e+125
+-6.7692131 e+125
+1.47727657 e-126
+-1.4772765 e-126
+1.35384262 e+126
+-1.3538426 e+126
+7.38638289 e-127
+-7.3863828 e-127
+2.70768524 e+126
+-2.7076852 e+126
+3.69319144 e-127
+-3.6931914 e-127
+5.41537049 e+126
+-5.4153704 e+126
+1.84659572 e-127
+-1.8465957 e-127
+1.08307409 e+127
+-1.0830740 e+127
+9.23297861 e-128
+-9.2329786 e-128
+2.16614819 e+127
+-2.1661481 e+127
+4.61648930 e-128
+-4.6164893 e-128
+4.33229639 e+127
+-4.3322963 e+127
+2.30824465 e-128
+-2.3082446 e-128
+8.66459279 e+127
+-8.6645927 e+127
+1.15412232 e-128
+-1.1541223 e-128
+1.73291855 e+128
+-1.7329185 e+128
+5.77061163 e-129
+-5.7706116 e-129
+3.46583711 e+128
+-3.4658371 e+128
+2.88530581 e-129
+-2.8853058 e-129
+6.93167423 e+128
+-6.9316742 e+128
+1.44265290 e-129
+-1.4426529 e-129
+1.38633484 e+129
+-1.3863348 e+129
+7.21326454 e-130
+-7.2132645 e-130
+2.77266969 e+129
+-2.7726696 e+129
+3.60663227 e-130
+-3.6066322 e-130
+5.54533938 e+129
+-5.5453393 e+129
+1.80331613 e-130
+-1.8033161 e-130
+1.10906787 e+130
+-1.1090678 e+130
+9.01658068 e-131
+-9.0165806 e-131
+2.21813575 e+130
+-2.2181357 e+130
+4.50829034 e-131
+-4.5082903 e-131
+4.43627151 e+130
+-4.4362715 e+130
+2.25414517 e-131
+-2.2541451 e-131
+8.87254302 e+130
+-8.8725430 e+130
+1.12707258 e-131
+-1.1270725 e-131
+1.77450860 e+131
+-1.7745086 e+131
+5.63536292 e-132
+-5.6353629 e-132
+3.54901720 e+131
+-3.5490172 e+131
+2.81768146 e-132
+-2.8176814 e-132
+7.09803441 e+131
+-7.0980344 e+131
+1.40884073 e-132
+-1.4088407 e-132
+1.41960688 e+132
+-1.4196068 e+132
+7.04420365 e-133
+-7.0442036 e-133
+2.83921376 e+132
+-2.8392137 e+132
+3.52210182 e-133
+-3.5221018 e-133
+5.67842753 e+132
+-5.6784275 e+132
+1.76105091 e-133
+-1.7610509 e-133
+1.13568550 e+133
+-1.1356855 e+133
+8.80525457 e-134
+-8.8052545 e-134
+2.27137101 e+133
+-2.2713710 e+133
+4.40262728 e-134
+-4.4026272 e-134
+4.54274202 e+133
+-4.5427420 e+133
+2.20131364 e-134
+-2.2013136 e-134
+9.08548405 e+133
+-9.0854840 e+133
+1.10065682 e-134
+-1.1006568 e-134
+1.81709681 e+134
+-1.8170968 e+134
+5.50328410 e-135
+-5.5032841 e-135
+3.63419362 e+134
+-3.6341936 e+134
+2.75164205 e-135
+-2.7516420 e-135
+7.26838724 e+134
+-7.2683872 e+134
+1.37582102 e-135
+-1.3758210 e-135
+1.45367744 e+135
+-1.4536774 e+135
+6.87910513 e-136
+-6.8791051 e-136
+2.90735489 e+135
+-2.9073548 e+135
+3.43955256 e-136
+-3.4395525 e-136
+5.81470979 e+135
+-5.8147097 e+135
+1.71977628 e-136
+-1.7197762 e-136
+1.16294195 e+136
+-1.1629419 e+136
+8.59888141 e-137
+-8.5988814 e-137
+2.32588391 e+136
+-2.3258839 e+136
+4.29944070 e-137
+-4.2994407 e-137
+4.65176783 e+136
+-4.6517678 e+136
+2.14972035 e-137
+-2.1497203 e-137
+9.30353567 e+136
+-9.3035356 e+136
+1.07486017 e-137
+-1.0748601 e-137
+1.86070713 e+137
+-1.8607071 e+137
+5.37430088 e-138
+-5.3743008 e-138
+3.72141426 e+137
+-3.7214142 e+137
+2.68715044 e-138
+-2.6871504 e-138
+7.44282853 e+137
+-7.4428285 e+137
+1.34357522 e-138
+-1.3435752 e-138
+1.48856570 e+138
+-1.4885657 e+138
+6.71787610 e-139
+-6.7178761 e-139
+2.97713141 e+138
+-2.9771314 e+138
+3.35893805 e-139
+-3.3589380 e-139
+5.95426282 e+138
+-5.9542628 e+138
+1.67946902 e-139
+-1.6794690 e-139
+1.19085256 e+139
+-1.1908525 e+139
+8.39734513 e-140
+-8.3973451 e-140
+2.38170513 e+139
+-2.3817051 e+139
+4.19867256 e-140
+-4.1986725 e-140
+4.76341026 e+139
+-4.7634102 e+139
+2.09933628 e-140
+-2.0993362 e-140
+9.52682052 e+139
+-9.5268205 e+139
+1.04966814 e-140
+-1.0496681 e-140
+1.90536410 e+140
+-1.9053641 e+140
+5.24834070 e-141
+-5.2483407 e-141
+3.81072821 e+140
+-3.8107282 e+140
+2.62417035 e-141
+-2.6241703 e-141
+7.62145642 e+140
+-7.6214564 e+140
+1.31208517 e-141
+-1.3120851 e-141
+1.52429128 e+141
+-1.5242912 e+141
+6.56042588 e-142
+-6.5604258 e-142
+3.04858256 e+141
+-3.0485825 e+141
+3.28021294 e-142
+-3.2802129 e-142
+6.09716513 e+141
+-6.0971651 e+141
+1.64010647 e-142
+-1.6401064 e-142
+1.21943302 e+142
+-1.2194330 e+142
+8.20053235 e-143
+-8.2005323 e-143
+2.43886605 e+142
+-2.4388660 e+142
+4.10026617 e-143
+-4.1002661 e-143
+4.87773210 e+142
+-4.8777321 e+142
+2.05013308 e-143
+-2.0501330 e-143
+9.75546421 e+142
+-9.7554642 e+142
+1.02506654 e-143
+-1.0250665 e-143
+1.95109284 e+143
+-1.9510928 e+143
+5.12533272 e-144
+-5.1253327 e-144
+3.90218568 e+143
+-3.9021856 e+143
+2.56266636 e-144
+-2.5626663 e-144
+7.80437137 e+143
+-7.8043713 e+143
+1.28133318 e-144
+-1.2813331 e-144
+1.56087427 e+144
+-1.5608742 e+144
+6.40666590 e-145
+-6.4066659 e-145
+3.12174855 e+144
+-3.1217485 e+144
+3.20333295 e-145
+-3.2033329 e-145
+6.24349710 e+144
+-6.2434971 e+144
+1.60166647 e-145
+-1.6016664 e-145
+1.24869942 e+145
+-1.2486994 e+145
+8.00833238 e-146
+-8.0083323 e-146
+2.49739884 e+145
+-2.4973988 e+145
+4.00416619 e-146
+-4.0041661 e-146
+4.99479768 e+145
+-4.9947976 e+145
+2.00208309 e-146
+-2.0020830 e-146
+9.98959536 e+145
+-9.9895953 e+145
+1.00104154 e-146
+-1.0010415 e-146
+1.99791907 e+146
+-1.9979190 e+146
+5.00520773 e-147
+-5.0052077 e-147
+3.99583814 e+146
+-3.9958381 e+146
+2.50260386 e-147
+-2.5026038 e-147
+7.99167628 e+146
+-7.9916762 e+146
+1.25130193 e-147
+-1.2513019 e-147
+1.59833525 e+147
+-1.5983352 e+147
+6.25650967 e-148
+-6.2565096 e-148
+3.19667051 e+147
+-3.1966705 e+147
+3.12825483 e-148
+-3.1282548 e-148
+6.39334103 e+147
+-6.3933410 e+147
+1.56412741 e-148
+-1.5641274 e-148
+1.27866820 e+148
+-1.2786682 e+148
+7.82063709 e-149
+-7.8206370 e-149
+2.55733641 e+148
+-2.5573364 e+148
+3.91031854 e-149
+-3.9103185 e-149
+5.11467282 e+148
+-5.1146728 e+148
+1.95515927 e-149
+-1.9551592 e-149
+1.02293456 e+149
+-1.0229345 e+149
+9.77579636 e-150
+-9.7757963 e-150
+2.04586912 e+149
+-2.0458691 e+149
+4.88789818 e-150
+-4.8878981 e-150
+4.09173825 e+149
+-4.0917382 e+149
+2.44394909 e-150
+-2.4439490 e-150
+8.18347651 e+149
+-8.1834765 e+149
+1.22197454 e-150
+-1.2219745 e-150
+1.63669530 e+150
+-1.6366953 e+150
+6.10987272 e-151
+-6.1098727 e-151
+3.27339060 e+150
+-3.2733906 e+150
+3.05493636 e-151
+-3.0549363 e-151
+6.54678121 e+150
+-6.5467812 e+150
+1.52746818 e-151
+-1.5274681 e-151
+1.30935624 e+151
+-1.3093562 e+151
+7.63734090 e-152
+-7.6373409 e-152
+2.61871248 e+151
+-2.6187124 e+151
+3.81867045 e-152
+-3.8186704 e-152
+5.23742497 e+151
+-5.2374249 e+151
+1.90933522 e-152
+-1.9093352 e-152
+1.04748499 e+152
+-1.0474849 e+152
+9.54667613 e-153
+-9.5466761 e-153
+2.09496998 e+152
+-2.0949699 e+152
+4.77333806 e-153
+-4.7733380 e-153
+4.18993997 e+152
+-4.1899399 e+152
+2.38666903 e-153
+-2.3866690 e-153
+8.37987995 e+152
+-8.3798799 e+152
+1.19333451 e-153
+-1.1933345 e-153
+1.67597599 e+153
+-1.6759759 e+153
+5.96667258 e-154
+-5.9666725 e-154
+3.35195198 e+153
+-3.3519519 e+153
+2.98333629 e-154
+-2.9833362 e-154
+6.70390396 e+153
+-6.7039039 e+153
+1.49166814 e-154
+-1.4916681 e-154
+1.34078079 e+154
+-1.3407807 e+154
+7.45834073 e-155
+-7.4583407 e-155
+2.68156158 e+154
+-2.6815615 e+154
+3.72917036 e-155
+-3.7291703 e-155
+5.36312317 e+154
+-5.3631231 e+154
+1.86458518 e-155
+-1.8645851 e-155
+1.07262463 e+155
+-1.0726246 e+155
+9.32292591 e-156
+-9.3229259 e-156
+2.14524926 e+155
+-2.1452492 e+155
+4.66146295 e-156
+-4.6614629 e-156
+4.29049853 e+155
+-4.2904985 e+155
+2.33073147 e-156
+-2.3307314 e-156
+8.58099707 e+155
+-8.5809970 e+155
+1.16536573 e-156
+-1.1653657 e-156
+1.71619941 e+156
+-1.7161994 e+156
+5.82682869 e-157
+-5.8268286 e-157
+3.43239883 e+156
+-3.4323988 e+156
+2.91341434 e-157
+-2.9134143 e-157
+6.86479766 e+156
+-6.8647976 e+156
+1.45670717 e-157
+-1.4567071 e-157
+1.37295953 e+157
+-1.3729595 e+157
+7.28353587 e-158
+-7.2835358 e-158
+2.74591906 e+157
+-2.7459190 e+157
+3.64176793 e-158
+-3.6417679 e-158
+5.49183812 e+157
+-5.4918381 e+157
+1.82088396 e-158
+-1.8208839 e-158
+1.09836762 e+158
+-1.0983676 e+158
+9.10441983 e-159
+-9.1044198 e-159
+2.19673525 e+158
+-2.1967352 e+158
+4.55220991 e-159
+-4.5522099 e-159
+4.39347050 e+158
+-4.3934705 e+158
+2.27610495 e-159
+-2.2761049 e-159
+8.78694100 e+158
+-8.7869410 e+158
+1.13805247 e-159
+-1.1380524 e-159
+1.75738820 e+159
+-1.7573882 e+159
+5.69026239 e-160
+-5.6902623 e-160
+3.51477640 e+159
+-3.5147764 e+159
+2.84513119 e-160
+-2.8451311 e-160
+7.02955280 e+159
+-7.0295528 e+159
+1.42256559 e-160
+-1.4225655 e-160
+1.40591056 e+160
+-1.4059105 e+160
+7.11282799 e-161
+-7.1128279 e-161
+2.81182112 e+160
+-2.8118211 e+160
+3.55641399 e-161
+-3.5564139 e-161
+5.62364224 e+160
+-5.6236422 e+160
+1.77820699 e-161
+-1.7782069 e-161
+1.12472844 e+161
+-1.1247284 e+161
+8.89103499 e-162
+-8.8910349 e-162
+2.24945689 e+161
+-2.2494568 e+161
+4.44551749 e-162
+-4.4455174 e-162
+4.49891379 e+161
+-4.4989137 e+161
+2.22275874 e-162
+-2.2227587 e-162
+8.99782758 e+161
+-8.9978275 e+161
+1.11137937 e-162
+-1.1113793 e-162
+1.79956551 e+162
+-1.7995655 e+162
+5.55689687 e-163
+-5.5568968 e-163
+3.59913103 e+162
+-3.5991310 e+162
+2.77844843 e-163
+-2.7784484 e-163
+7.19826207 e+162
+-7.1982620 e+162
+1.38922421 e-163
+-1.3892242 e-163
+1.43965241 e+163
+-1.4396524 e+163
+6.94612109 e-164
+-6.9461210 e-164
+2.87930482 e+163
+-2.8793048 e+163
+3.47306054 e-164
+-3.4730605 e-164
+5.75860965 e+163
+-5.7586096 e+163
+1.73653027 e-164
+-1.7365302 e-164
+1.15172193 e+164
+-1.1517219 e+164
+8.68265136 e-165
+-8.6826513 e-165
+2.30344386 e+164
+-2.3034438 e+164
+4.34132568 e-165
+-4.3413256 e-165
+4.60688772 e+164
+-4.6068877 e+164
+2.17066284 e-165
+-2.1706628 e-165
+9.21377545 e+164
+-9.2137754 e+164
+1.08533142 e-165
+-1.0853314 e-165
+1.84275509 e+165
+-1.8427550 e+165
+5.42665710 e-166
+-5.4266571 e-166
+3.68551018 e+165
+-3.6855101 e+165
+2.71332855 e-166
+-2.7133285 e-166
+7.37102036 e+165
+-7.3710203 e+165
+1.35666427 e-166
+-1.3566642 e-166
+1.47420407 e+166
+-1.4742040 e+166
+6.78332137 e-167
+-6.7833213 e-167
+2.94840814 e+166
+-2.9484081 e+166
+3.39166068 e-167
+-3.3916606 e-167
+5.89681628 e+166
+-5.8968162 e+166
+1.69583034 e-167
+-1.6958303 e-167
+1.17936325 e+167
+-1.1793632 e+167
+8.47915172 e-168
+-8.4791517 e-168
+2.35872651 e+167
+-2.3587265 e+167
+4.23957586 e-168
+-4.2395758 e-168
+4.71745303 e+167
+-4.7174530 e+167
+2.11978793 e-168
+-2.1197879 e-168
+9.43490606 e+167
+-9.4349060 e+167
+1.05989396 e-168
+-1.0598939 e-168
+1.88698121 e+168
+-1.8869812 e+168
+5.29946982 e-169
+-5.2994698 e-169
+3.77396242 e+168
+-3.7739624 e+168
+2.64973491 e-169
+-2.6497349 e-169
+7.54792484 e+168
+-7.5479248 e+168
+1.32486745 e-169
+-1.3248674 e-169
+1.50958496 e+169
+-1.5095849 e+169
+6.62433728 e-170
+-6.6243372 e-170
+3.01916993 e+169
+-3.0191699 e+169
+3.31216864 e-170
+-3.3121686 e-170
+6.03833987 e+169
+-6.0383398 e+169
+1.65608432 e-170
+-1.6560843 e-170
+1.20766797 e+170
+-1.2076679 e+170
+8.28042160 e-171
+-8.2804216 e-171
+2.41533595 e+170
+-2.4153359 e+170
+4.14021080 e-171
+-4.1402108 e-171
+4.83067190 e+170
+-4.8306719 e+170
+2.07010540 e-171
+-2.0701054 e-171
+9.66134380 e+170
+-9.6613438 e+170
+1.03505270 e-171
+-1.0350527 e-171
+1.93226876 e+171
+-1.9322687 e+171
+5.17526350 e-172
+-5.1752635 e-172
+3.86453752 e+171
+-3.8645375 e+171
+2.58763175 e-172
+-2.5876317 e-172
+7.72907504 e+171
+-7.7290750 e+171
+1.29381587 e-172
+-1.2938158 e-172
+1.54581500 e+172
+-1.5458150 e+172
+6.46907937 e-173
+-6.4690793 e-173
+3.09163001 e+172
+-3.0916300 e+172
+3.23453968 e-173
+-3.2345396 e-173
+6.18326003 e+172
+-6.1832600 e+172
+1.61726984 e-173
+-1.6172698 e-173
+1.23665200 e+173
+-1.2366520 e+173
+8.08634922 e-174
+-8.0863492 e-174
+2.47330401 e+173
+-2.4733040 e+173
+4.04317461 e-174
+-4.0431746 e-174
+4.94660802 e+173
+-4.9466080 e+173
+2.02158730 e-174
+-2.0215873 e-174
+9.89321605 e+173
+-9.8932160 e+173
+1.01079365 e-174
+-1.0107936 e-174
+1.97864321 e+174
+-1.9786432 e+174
+5.05396826 e-175
+-5.0539682 e-175
+3.95728642 e+174
+-3.9572864 e+174
+2.52698413 e-175
+-2.5269841 e-175
+7.91457284 e+174
+-7.9145728 e+174
+1.26349206 e-175
+-1.2634920 e-175
+1.58291456 e+175
+-1.5829145 e+175
+6.31746033 e-176
+-6.3174603 e-176
+3.16582913 e+175
+-3.1658291 e+175
+3.15873016 e-176
+-3.1587301 e-176
+6.33165827 e+175
+-6.3316582 e+175
+1.57936508 e-176
+-1.5793650 e-176
+1.26633165 e+176
+-1.2663316 e+176
+7.89682541 e-177
+-7.8968254 e-177
+2.53266331 e+176
+-2.5326633 e+176
+3.94841270 e-177
+-3.9484127 e-177
+5.06532662 e+176
+-5.0653266 e+176
+1.97420635 e-177
+-1.9742063 e-177
+1.01306532 e+177
+-1.0130653 e+177
+9.87103176 e-178
+-9.8710317 e-178
+2.02613064 e+177
+-2.0261306 e+177
+4.93551588 e-178
+-4.9355158 e-178
+4.05226129 e+177
+-4.0522612 e+177
+2.46775794 e-178
+-2.4677579 e-178
+8.10452259 e+177
+-8.1045225 e+177
+1.23387897 e-178
+-1.2338789 e-178
+1.62090451 e+178
+-1.6209045 e+178
+6.16939485 e-179
+-6.1693948 e-179
+3.24180903 e+178
+-3.2418090 e+178
+3.08469742 e-179
+-3.0846974 e-179
+6.48361807 e+178
+-6.4836180 e+178
+1.54234871 e-179
+-1.5423487 e-179
+1.29672361 e+179
+-1.2967236 e+179
+7.71174356 e-180
+-7.7117435 e-180
+2.59344723 e+179
+-2.5934472 e+179
+3.85587178 e-180
+-3.8558717 e-180
+5.18689446 e+179
+-5.1868944 e+179
+1.92793589 e-180
+-1.9279358 e-180
+1.03737889 e+180
+-1.0373788 e+180
+9.63967946 e-181
+-9.6396794 e-181
+2.07475778 e+180
+-2.0747577 e+180
+4.81983973 e-181
+-4.8198397 e-181
+4.14951556 e+180
+-4.1495155 e+180
+2.40991986 e-181
+-2.4099198 e-181
+8.29903113 e+180
+-8.2990311 e+180
+1.20495993 e-181
+-1.2049599 e-181
+1.65980622 e+181
+-1.6598062 e+181
+6.02479966 e-182
+-6.0247996 e-182
+3.31961245 e+181
+-3.3196124 e+181
+3.01239983 e-182
+-3.0123998 e-182
+6.63922491 e+181
+-6.6392249 e+181
+1.50619991 e-182
+-1.5061999 e-182
+1.32784498 e+182
+-1.3278449 e+182
+7.53099957 e-183
+-7.5309995 e-183
+2.65568996 e+182
+-2.6556899 e+182
+3.76549978 e-183
+-3.7654997 e-183
+5.31137992 e+182
+-5.3113799 e+182
+1.88274989 e-183
+-1.8827498 e-183
+1.06227598 e+183
+-1.0622759 e+183
+9.41374947 e-184
+-9.4137494 e-184
+2.12455197 e+183
+-2.1245519 e+183
+4.70687473 e-184
+-4.7068747 e-184
+4.24910394 e+183
+-4.2491039 e+183
+2.35343736 e-184
+-2.3534373 e-184
+8.49820788 e+183
+-8.4982078 e+183
+1.17671868 e-184
+-1.1767186 e-184
+1.69964157 e+184
+-1.6996415 e+184
+5.88359342 e-185
+-5.8835934 e-185
+3.39928315 e+184
+-3.3992831 e+184
+2.94179671 e-185
+-2.9417967 e-185
+6.79856630 e+184
+-6.7985663 e+184
+1.47089835 e-185
+-1.4708983 e-185
+1.35971326 e+185
+-1.3597132 e+185
+7.35449177 e-186
+-7.3544917 e-186
+2.71942652 e+185
+-2.7194265 e+185
+3.67724588 e-186
+-3.6772458 e-186
+5.43885304 e+185
+-5.4388530 e+185
+1.83862294 e-186
+-1.8386229 e-186
+1.08777060 e+186
+-1.0877706 e+186
+9.19311471 e-187
+-9.1931147 e-187
+2.17554121 e+186
+-2.1755412 e+186
+4.59655735 e-187
+-4.5965573 e-187
+4.35108243 e+186
+-4.3510824 e+186
+2.29827867 e-187
+-2.2982786 e-187
+8.70216487 e+186
+-8.7021648 e+186
+1.14913933 e-187
+-1.1491393 e-187
+1.74043297 e+187
+-1.7404329 e+187
+5.74569669 e-188
+-5.7456966 e-188
+3.48086594 e+187
+-3.4808659 e+187
+2.87284834 e-188
+-2.8728483 e-188
+6.96173189 e+187
+-6.9617318 e+187
+1.43642417 e-188
+-1.4364241 e-188
+1.39234637 e+188
+-1.3923463 e+188
+7.18212087 e-189
+-7.1821208 e-189
+2.78469275 e+188
+-2.7846927 e+188
+3.59106043 e-189
+-3.5910604 e-189
+5.56938551 e+188
+-5.5693855 e+188
+1.79553021 e-189
+-1.7955302 e-189
+1.11387710 e+189
+-1.1138771 e+189
+8.97765109 e-190
+-8.9776510 e-190
+2.22775420 e+189
+-2.2277542 e+189
+4.48882554 e-190
+-4.4888255 e-190
+4.45550841 e+189
+-4.4555084 e+189
+2.24441277 e-190
+-2.2444127 e-190
+8.91101683 e+189
+-8.9110168 e+189
+1.12220638 e-190
+-1.1222063 e-190
+1.78220336 e+190
+-1.7822033 e+190
+5.61103193 e-191
+-5.6110319 e-191
+3.56440673 e+190
+-3.5644067 e+190
+2.80551596 e-191
+-2.8055159 e-191
+7.12881346 e+190
+-7.1288134 e+190
+1.40275798 e-191
+-1.4027579 e-191
+1.42576269 e+191
+-1.4257626 e+191
+7.01378991 e-192
+-7.0137899 e-192
+2.85152538 e+191
+-2.8515253 e+191
+3.50689495 e-192
+-3.5068949 e-192
+5.70305077 e+191
+-5.7030507 e+191
+1.75344747 e-192
+-1.7534474 e-192
+1.14061015 e+192
+-1.1406101 e+192
+8.76723739 e-193
+-8.7672373 e-193
+2.28122030 e+192
+-2.2812203 e+192
+4.38361869 e-193
+-4.3836186 e-193
+4.56244061 e+192
+-4.5624406 e+192
+2.19180934 e-193
+-2.1918093 e-193
+9.12488123 e+192
+-9.1248812 e+192
+1.09590467 e-193
+-1.0959046 e-193
+1.82497624 e+193
+-1.8249762 e+193
+5.47952337 e-194
+-5.4795233 e-194
+3.64995249 e+193
+-3.6499524 e+193
+2.73976168 e-194
+-2.7397616 e-194
+7.29990498 e+193
+-7.2999049 e+193
+1.36988084 e-194
+-1.3698808 e-194
+1.45998099 e+194
+-1.4599809 e+194
+6.84940421 e-195
+-6.8494042 e-195
+2.91996199 e+194
+-2.9199619 e+194
+3.42470210 e-195
+-3.4247021 e-195
+5.83992399 e+194
+-5.8399239 e+194
+1.71235105 e-195
+-1.7123510 e-195
+1.16798479 e+195
+-1.1679847 e+195
+8.56175526 e-196
+-8.5617552 e-196
+2.33596959 e+195
+-2.3359695 e+195
+4.28087763 e-196
+-4.2808776 e-196
+4.67193919 e+195
+-4.6719391 e+195
+2.14043881 e-196
+-2.1404388 e-196
+9.34387838 e+195
+-9.3438783 e+195
+1.07021940 e-196
+-1.0702194 e-196
+1.86877567 e+196
+-1.8687756 e+196
+5.35109704 e-197
+-5.3510970 e-197
+3.73755135 e+196
+-3.7375513 e+196
+2.67554852 e-197
+-2.6755485 e-197
+7.47510270 e+196
+-7.4751027 e+196
+1.33777426 e-197
+-1.3377742 e-197
+1.49502054 e+197
+-1.4950205 e+197
+6.68887130 e-198
+-6.6888713 e-198
+2.99004108 e+197
+-2.9900410 e+197
+3.34443565 e-198
+-3.3444356 e-198
+5.98008216 e+197
+-5.9800821 e+197
+1.67221782 e-198
+-1.6722178 e-198
+1.19601643 e+198
+-1.1960164 e+198
+8.36108913 e-199
+-8.3610891 e-199
+2.39203286 e+198
+-2.3920328 e+198
+4.18054456 e-199
+-4.1805445 e-199
+4.78406573 e+198
+-4.7840657 e+198
+2.09027228 e-199
+-2.0902722 e-199
+9.56813146 e+198
+-9.5681314 e+198
+1.04513614 e-199
+-1.0451361 e-199
+1.91362629 e+199
+-1.9136262 e+199
+5.22568070 e-200
+-5.2256807 e-200
+3.82725258 e+199
+-3.8272525 e+199
+2.61284035 e-200
+-2.6128403 e-200
+7.65450517 e+199
+-7.6545051 e+199
+1.30642017 e-200
+-1.3064201 e-200
+1.53090103 e+200
+-1.5309010 e+200
+6.53210088 e-201
+-6.5321008 e-201
+3.06180206 e+200
+-3.0618020 e+200
+3.26605044 e-201
+-3.2660504 e-201
+6.12360413 e+200
+-6.1236041 e+200
+1.63302522 e-201
+-1.6330252 e-201
+1.22472082 e+201
+-1.2247208 e+201
+8.16512610 e-202
+-8.1651261 e-202
+2.44944165 e+201
+-2.4494416 e+201
+4.08256305 e-202
+-4.0825630 e-202
+4.89888331 e+201
+-4.8988833 e+201
+2.04128152 e-202
+-2.0412815 e-202
+9.79776662 e+201
+-9.7977666 e+201
+1.02064076 e-202
+-1.0206407 e-202
+1.95955332 e+202
+-1.9595533 e+202
+5.10320381 e-203
+-5.1032038 e-203
+3.91910664 e+202
+-3.9191066 e+202
+2.55160190 e-203
+-2.5516019 e-203
+7.83821329 e+202
+-7.8382132 e+202
+1.27580095 e-203
+-1.2758009 e-203
+1.56764265 e+203
+-1.5676426 e+203
+6.37900476 e-204
+-6.3790047 e-204
+3.13528531 e+203
+-3.1352853 e+203
+3.18950238 e-204
+-3.1895023 e-204
+6.27057063 e+203
+-6.2705706 e+203
+1.59475119 e-204
+-1.5947511 e-204
+1.25411412 e+204
+-1.2541141 e+204
+7.97375596 e-205
+-7.9737559 e-205
+2.50822825 e+204
+-2.5082282 e+204
+3.98687798 e-205
+-3.9868779 e-205
+5.01645651 e+204
+-5.0164565 e+204
+1.99343899 e-205
+-1.9934389 e-205
+1.00329130 e+205
+-1.0032913 e+205
+9.96719495 e-206
+-9.9671949 e-206
+2.00658260 e+205
+-2.0065826 e+205
+4.98359747 e-206
+-4.9835974 e-206
+4.01316520 e+205
+-4.0131652 e+205
+2.49179873 e-206
+-2.4917987 e-206
+8.02633041 e+205
+-8.0263304 e+205
+1.24589936 e-206
+-1.2458993 e-206
+1.60526608 e+206
+-1.6052660 e+206
+6.22949684 e-207
+-6.2294968 e-207
+3.21053216 e+206
+-3.2105321 e+206
+3.11474842 e-207
+-3.1147484 e-207
+6.42106433 e+206
+-6.4210643 e+206
+1.55737421 e-207
+-1.5573742 e-207
+1.28421286 e+207
+-1.2842128 e+207
+7.78687105 e-208
+-7.7868710 e-208
+2.56842573 e+207
+-2.5684257 e+207
+3.89343552 e-208
+-3.8934355 e-208
+5.13685146 e+207
+-5.1368514 e+207
+1.94671776 e-208
+-1.9467177 e-208
+1.02737029 e+208
+-1.0273702 e+208
+9.73358881 e-209
+-9.7335888 e-209
+2.05474058 e+208
+-2.0547405 e+208
+4.86679440 e-209
+-4.8667944 e-209
+4.10948117 e+208
+-4.1094811 e+208
+2.43339720 e-209
+-2.4333972 e-209
+8.21896234 e+208
+-8.2189623 e+208
+1.21669860 e-209
+-1.2166986 e-209
+1.64379246 e+209
+-1.6437924 e+209
+6.08349301 e-210
+-6.0834930 e-210
+3.28758493 e+209
+-3.2875849 e+209
+3.04174650 e-210
+-3.0417465 e-210
+6.57516987 e+209
+-6.5751698 e+209
+1.52087325 e-210
+-1.5208732 e-210
+1.31503397 e+210
+-1.3150339 e+210
+7.60436626 e-211
+-7.6043662 e-211
+2.63006795 e+210
+-2.6300679 e+210
+3.80218313 e-211
+-3.8021831 e-211
+5.26013590 e+210
+-5.2601359 e+210
+1.90109156 e-211
+-1.9010915 e-211
+1.05202718 e+211
+-1.0520271 e+211
+9.50545783 e-212
+-9.5054578 e-212
+2.10405436 e+211
+-2.1040543 e+211
+4.75272891 e-212
+-4.7527289 e-212
+4.20810872 e+211
+-4.2081087 e+211
+2.37636445 e-212
+-2.3763644 e-212
+8.41621744 e+211
+-8.4162174 e+211
+1.18818222 e-212
+-1.1881822 e-212
+1.68324348 e+212
+-1.6832434 e+212
+5.94091114 e-213
+-5.9409111 e-213
+3.36648697 e+212
+-3.3664869 e+212
+2.97045557 e-213
+-2.9704555 e-213
+6.73297395 e+212
+-6.7329739 e+212
+1.48522778 e-213
+-1.4852277 e-213
+1.34659479 e+213
+-1.3465947 e+213
+7.42613893 e-214
+-7.4261389 e-214
+2.69318958 e+213
+-2.6931895 e+213
+3.71306946 e-214
+-3.7130694 e-214
+5.38637916 e+213
+-5.3863791 e+213
+1.85653473 e-214
+-1.8565347 e-214
+1.07727583 e+214
+-1.0772758 e+214
+9.28267366 e-215
+-9.2826736 e-215
+2.15455166 e+214
+-2.1545516 e+214
+4.64133683 e-215
+-4.6413368 e-215
+4.30910333 e+214
+-4.3091033 e+214
+2.32066841 e-215
+-2.3206684 e-215
+8.61820666 e+214
+-8.6182066 e+214
+1.16033420 e-215
+-1.1603342 e-215
+1.72364133 e+215
+-1.7236413 e+215
+5.80167103 e-216
+-5.8016710 e-216
+3.44728266 e+215
+-3.4472826 e+215
+2.90083551 e-216
+-2.9008355 e-216
+6.89456532 e+215
+-6.8945653 e+215
+1.45041775 e-216
+-1.4504177 e-216
+1.37891306 e+216
+-1.3789130 e+216
+7.25208879 e-217
+-7.2520887 e-217
+2.75782613 e+216
+-2.7578261 e+216
+3.62604439 e-217
+-3.6260443 e-217
+5.51565226 e+216
+-5.5156522 e+216
+1.81302219 e-217
+-1.8130221 e-217
+1.10313045 e+217
+-1.1031304 e+217
+9.06511099 e-218
+-9.0651109 e-218
+2.20626090 e+217
+-2.2062609 e+217
+4.53255549 e-218
+-4.5325554 e-218
+4.41252181 e+217
+-4.4125218 e+217
+2.26627774 e-218
+-2.2662777 e-218
+8.82504362 e+217
+-8.8250436 e+217
+1.13313887 e-218
+-1.1331388 e-218
+1.76500872 e+218
+-1.7650087 e+218
+5.66569437 e-219
+-5.6656943 e-219
+3.53001744 e+218
+-3.5300174 e+218
+2.83284718 e-219
+-2.8328471 e-219
+7.06003489 e+218
+-7.0600348 e+218
+1.41642359 e-219
+-1.4164235 e-219
+1.41200697 e+219
+-1.4120069 e+219
+7.08211796 e-220
+-7.0821179 e-220
+2.82401395 e+219
+-2.8240139 e+219
+3.54105898 e-220
+-3.5410589 e-220
+5.64802791 e+219
+-5.6480279 e+219
+1.77052949 e-220
+-1.7705294 e-220
+1.12960558 e+220
+-1.1296055 e+220
+8.85264746 e-221
+-8.8526474 e-221
+2.25921116 e+220
+-2.2592111 e+220
+4.42632373 e-221
+-4.4263237 e-221
+4.51842233 e+220
+-4.5184223 e+220
+2.21316186 e-221
+-2.2131618 e-221
+9.03684466 e+220
+-9.0368446 e+220
+1.10658093 e-221
+-1.1065809 e-221
+1.80736893 e+221
+-1.8073689 e+221
+5.53290466 e-222
+-5.5329046 e-222
+3.61473786 e+221
+-3.6147378 e+221
+2.76645233 e-222
+-2.7664523 e-222
+7.22947573 e+221
+-7.2294757 e+221
+1.38322616 e-222
+-1.3832261 e-222
+1.44589514 e+222
+-1.4458951 e+222
+6.91613082 e-223
+-6.9161308 e-223
+2.89179029 e+222
+-2.8917902 e+222
+3.45806541 e-223
+-3.4580654 e-223
+5.78358058 e+222
+-5.7835805 e+222
+1.72903270 e-223
+-1.7290327 e-223
+1.15671611 e+223
+-1.1567161 e+223
+8.64516353 e-224
+-8.6451635 e-224
+2.31343223 e+223
+-2.3134322 e+223
+4.32258176 e-224
+-4.3225817 e-224
+4.62686446 e+223
+-4.6268644 e+223
+2.16129088 e-224
+-2.1612908 e-224
+9.25372893 e+223
+-9.2537289 e+223
+1.08064544 e-224
+-1.0806454 e-224
+1.85074578 e+224
+-1.8507457 e+224
+5.40322720 e-225
+-5.4032272 e-225
+3.70149157 e+224
+-3.7014915 e+224
+2.70161360 e-225
+-2.7016136 e-225
+7.40298315 e+224
+-7.4029831 e+224
+1.35080680 e-225
+-1.3508068 e-225
+1.48059663 e+225
+-1.4805966 e+225
+6.75403401 e-226
+-6.7540340 e-226
+2.96119326 e+225
+-2.9611932 e+225
+3.37701700 e-226
+-3.3770170 e-226
+5.92238652 e+225
+-5.9223865 e+225
+1.68850850 e-226
+-1.6885085 e-226
+1.18447730 e+226
+-1.1844773 e+226
+8.44254251 e-227
+-8.4425425 e-227
+2.36895460 e+226
+-2.3689546 e+226
+4.22127125 e-227
+-4.2212712 e-227
+4.73790921 e+226
+-4.7379092 e+226
+2.11063562 e-227
+-2.1106356 e-227
+9.47581843 e+226
+-9.4758184 e+226
+1.05531781 e-227
+-1.0553178 e-227
+1.89516368 e+227
+-1.8951636 e+227
+5.27658907 e-228
+-5.2765890 e-228
+3.79032737 e+227
+-3.7903273 e+227
+2.63829453 e-228
+-2.6382945 e-228
+7.58065474 e+227
+-7.5806547 e+227
+1.31914726 e-228
+-1.3191472 e-228
+1.51613094 e+228
+-1.5161309 e+228
+6.59573634 e-229
+-6.5957363 e-229
+3.03226189 e+228
+-3.0322618 e+228
+3.29786817 e-229
+-3.2978681 e-229
+6.06452379 e+228
+-6.0645237 e+228
+1.64893408 e-229
+-1.6489340 e-229
+1.21290475 e+229
+-1.2129047 e+229
+8.24467042 e-230
+-8.2446704 e-230
+2.42580951 e+229
+-2.4258095 e+229
+4.12233521 e-230
+-4.1223352 e-230
+4.85161903 e+229
+-4.8516190 e+229
+2.06116760 e-230
+-2.0611676 e-230
+9.70323807 e+229
+-9.7032380 e+229
+1.03058380 e-230
+-1.0305838 e-230
+1.94064761 e+230
+-1.9406476 e+230
+5.15291901 e-231
+-5.1529190 e-231
+3.88129523 e+230
+-3.8812952 e+230
+2.57645950 e-231
+-2.5764595 e-231
+7.76259046 e+230
+-7.7625904 e+230
+1.28822975 e-231
+-1.2882297 e-231
+1.55251809 e+231
+-1.5525180 e+231
+6.44114876 e-232
+-6.4411487 e-232
+3.10503618 e+231
+-3.1050361 e+231
+3.22057438 e-232
+-3.2205743 e-232
+6.21007236 e+231
+-6.2100723 e+231
+1.61028719 e-232
+-1.6102871 e-232
+1.24201447 e+232
+-1.2420144 e+232
+8.05143596 e-233
+-8.0514359 e-233
+2.48402894 e+232
+-2.4840289 e+232
+4.02571798 e-233
+-4.0257179 e-233
+4.96805789 e+232
+-4.9680578 e+232
+2.01285899 e-233
+-2.0128589 e-233
+9.93611579 e+232
+-9.9361157 e+232
+1.00642949 e-233
+-1.0064294 e-233
+1.98722315 e+233
+-1.9872231 e+233
+5.03214747 e-234
+-5.0321474 e-234
+3.97444631 e+233
+-3.9744463 e+233
+2.51607373 e-234
+-2.5160737 e-234
+7.94889263 e+233
+-7.9488926 e+233
+1.25803686 e-234
+-1.2580368 e-234
+1.58977852 e+234
+-1.5897785 e+234
+6.29018434 e-235
+-6.2901843 e-235
+3.17955705 e+234
+-3.1795570 e+234
+3.14509217 e-235
+-3.1450921 e-235
+6.35911410 e+234
+-6.3591141 e+234
+1.57254608 e-235
+-1.5725460 e-235
+1.27182282 e+235
+-1.2718228 e+235
+7.86273043 e-236
+-7.8627304 e-236
+2.54364564 e+235
+-2.5436456 e+235
+3.93136521 e-236
+-3.9313652 e-236
+5.08729128 e+235
+-5.0872912 e+235
+1.96568260 e-236
+-1.9656826 e-236
+1.01745825 e+236
+-1.0174582 e+236
+9.82841303 e-237
+-9.8284130 e-237
+2.03491651 e+236
+-2.0349165 e+236
+4.91420651 e-237
+-4.9142065 e-237
+4.06983302 e+236
+-4.0698330 e+236
+2.45710325 e-237
+-2.4571032 e-237
+8.13966605 e+236
+-8.1396660 e+236
+1.22855162 e-237
+-1.2285516 e-237
+1.62793321 e+237
+-1.6279332 e+237
+6.14275814 e-238
+-6.1427581 e-238
+3.25586642 e+237
+-3.2558664 e+237
+3.07137907 e-238
+-3.0713790 e-238
+6.51173284 e+237
+-6.5117328 e+237
+1.53568953 e-238
+-1.5356895 e-238
+1.30234656 e+238
+-1.3023465 e+238
+7.67844768 e-239
+-7.6784476 e-239
+2.60469313 e+238
+-2.6046931 e+238
+3.83922384 e-239
+-3.8392238 e-239
+5.20938627 e+238
+-5.2093862 e+238
+1.91961192 e-239
+-1.9196119 e-239
+1.04187725 e+239
+-1.0418772 e+239
+9.59805960 e-240
+-9.5980596 e-240
+2.08375451 e+239
+-2.0837545 e+239
+4.79902980 e-240
+-4.7990298 e-240
+4.16750902 e+239
+-4.1675090 e+239
+2.39951490 e-240
+-2.3995149 e-240
+8.33501804 e+239
+-8.3350180 e+239
+1.19975745 e-240
+-1.1997574 e-240
+1.66700360 e+240
+-1.6670036 e+240
+5.99878725 e-241
+-5.9987872 e-241
+3.33400721 e+240
+-3.3340072 e+240
+2.99939362 e-241
+-2.9993936 e-241
+6.66801443 e+240
+-6.6680144 e+240
+1.49969681 e-241
+-1.4996968 e-241
+1.33360288 e+241
+-1.3336028 e+241
+7.49848406 e-242
+-7.4984840 e-242
+2.66720577 e+241
+-2.6672057 e+241
+3.74924203 e-242
+-3.7492420 e-242
+5.33441154 e+241
+-5.3344115 e+241
+1.87462101 e-242
+-1.8746210 e-242
+1.06688230 e+242
+-1.0668823 e+242
+9.37310508 e-243
+-9.3731050 e-243
+2.13376461 e+242
+-2.1337646 e+242
+4.68655254 e-243
+-4.6865525 e-243
+4.26752923 e+242
+-4.2675292 e+242
+2.34327627 e-243
+-2.3432762 e-243
+8.53505847 e+242
+-8.5350584 e+242
+1.17163813 e-243
+-1.1716381 e-243
+1.70701169 e+243
+-1.7070116 e+243
+5.85819067 e-244
+-5.8581906 e-244
+3.41402338 e+243
+-3.4140233 e+243
+2.92909533 e-244
+-2.9290953 e-244
+6.82804677 e+243
+-6.8280467 e+243
+1.46454766 e-244
+-1.4645476 e-244
+1.36560935 e+244
+-1.3656093 e+244
+7.32273834 e-245
+-7.3227383 e-245
+2.73121871 e+244
+-2.7312187 e+244
+3.66136917 e-245
+-3.6613691 e-245
+5.46243742 e+244
+-5.4624374 e+244
+1.83068458 e-245
+-1.8306845 e-245
+1.09248748 e+245
+-1.0924874 e+245
+9.15342293 e-246
+-9.1534229 e-246
+2.18497496 e+245
+-2.1849749 e+245
+4.57671146 e-246
+-4.5767114 e-246
+4.36994993 e+245
+-4.3699499 e+245
+2.28835573 e-246
+-2.2883557 e-246
+8.73989987 e+245
+-8.7398998 e+245
+1.14417786 e-246
+-1.1441778 e-246
+1.74797997 e+246
+-1.7479799 e+246
+5.72088933 e-247
+-5.7208893 e-247
+3.49595995 e+246
+-3.4959599 e+246
+2.86044466 e-247
+-2.8604446 e-247
+6.99191990 e+246
+-6.9919199 e+246
+1.43022233 e-247
+-1.4302223 e-247
+1.39838398 e+247
+-1.3983839 e+247
+7.15111166 e-248
+-7.1511116 e-248
+2.79676796 e+247
+-2.7967679 e+247
+3.57555583 e-248
+-3.5755558 e-248
+5.59353592 e+247
+-5.5935359 e+247
+1.78777791 e-248
+-1.7877779 e-248
+1.11870718 e+248
+-1.1187071 e+248
+8.93888958 e-249
+-8.9388895 e-249
+2.23741436 e+248
+-2.2374143 e+248
+4.46944479 e-249
+-4.4694447 e-249
+4.47482873 e+248
+-4.4748287 e+248
+2.23472239 e-249
+-2.2347223 e-249
+8.94965747 e+248
+-8.9496574 e+248
+1.11736119 e-249
+-1.1173611 e-249
+1.78993149 e+249
+-1.7899314 e+249
+5.58680599 e-250
+-5.5868059 e-250
+3.57986298 e+249
+-3.5798629 e+249
+2.79340299 e-250
+-2.7934029 e-250
+7.15972597 e+249
+-7.1597259 e+249
+1.39670149 e-250
+-1.3967014 e-250
+1.43194519 e+250
+-1.4319451 e+250
+6.98350748 e-251
+-6.9835074 e-251
+2.86389039 e+250
+-2.8638903 e+250
+3.49175374 e-251
+-3.4917537 e-251
+5.72778078 e+250
+-5.7277807 e+250
+1.74587687 e-251
+-1.7458768 e-251
+1.14555615 e+251
+-1.1455561 e+251
+8.72938436 e-252
+-8.7293843 e-252
+2.29111231 e+251
+-2.2911123 e+251
+4.36469218 e-252
+-4.3646921 e-252
+4.58222462 e+251
+-4.5822246 e+251
+2.18234609 e-252
+-2.1823460 e-252
+9.16444925 e+251
+-9.1644492 e+251
+1.09117304 e-252
+-1.0911730 e-252
+1.83288985 e+252
+-1.8328898 e+252
+5.45586522 e-253
+-5.4558652 e-253
+3.66577970 e+252
+-3.6657797 e+252
+2.72793261 e-253
+-2.7279326 e-253
+7.33155940 e+252
+-7.3315594 e+252
+1.36396630 e-253
+-1.3639663 e-253
+1.46631188 e+253
+-1.4663118 e+253
+6.81983153 e-254
+-6.8198315 e-254
+2.93262376 e+253
+-2.9326237 e+253
+3.40991576 e-254
+-3.4099157 e-254
+5.86524752 e+253
+-5.8652475 e+253
+1.70495788 e-254
+-1.7049578 e-254
+1.17304950 e+254
+-1.1730495 e+254
+8.52478941 e-255
+-8.5247894 e-255
+2.34609900 e+254
+-2.3460990 e+254
+4.26239470 e-255
+-4.2623947 e-255
+4.69219801 e+254
+-4.6921980 e+254
+2.13119735 e-255
+-2.1311973 e-255
+9.38439603 e+254
+-9.3843960 e+254
+1.06559867 e-255
+-1.0655986 e-255
+1.87687920 e+255
+-1.8768792 e+255
+5.32799338 e-256
+-5.3279933 e-256
+3.75375841 e+255
+-3.7537584 e+255
+2.66399669 e-256
+-2.6639966 e-256
+7.50751682 e+255
+-7.5075168 e+255
+1.33199834 e-256
+-1.3319983 e-256
+1.50150336 e+256
+-1.5015033 e+256
+6.65999173 e-257
+-6.6599917 e-257
+3.00300673 e+256
+-3.0030067 e+256
+3.32999586 e-257
+-3.3299958 e-257
+6.00601346 e+256
+-6.0060134 e+256
+1.66499793 e-257
+-1.6649979 e-257
+1.20120269 e+257
+-1.2012026 e+257
+8.32498966 e-258
+-8.3249896 e-258
+2.40240538 e+257
+-2.4024053 e+257
+4.16249483 e-258
+-4.1624948 e-258
+4.80481077 e+257
+-4.8048107 e+257
+2.08124741 e-258
+-2.0812474 e-258
+9.60962154 e+257
+-9.6096215 e+257
+1.04062370 e-258
+-1.0406237 e-258
+1.92192430 e+258
+-1.9219243 e+258
+5.20311853 e-259
+-5.2031185 e-259
+3.84384861 e+258
+-3.8438486 e+258
+2.60155926 e-259
+-2.6015592 e-259
+7.68769723 e+258
+-7.6876972 e+258
+1.30077963 e-259
+-1.3007796 e-259
+1.53753944 e+259
+-1.5375394 e+259
+6.50389817 e-260
+-6.5038981 e-260
+3.07507889 e+259
+-3.0750788 e+259
+3.25194908 e-260
+-3.2519490 e-260
+6.15015778 e+259
+-6.1501577 e+259
+1.62597454 e-260
+-1.6259745 e-260
+1.23003155 e+260
+-1.2300315 e+260
+8.12987271 e-261
+-8.1298727 e-261
+2.46006311 e+260
+-2.4600631 e+260
+4.06493635 e-261
+-4.0649363 e-261
+4.92012622 e+260
+-4.9201262 e+260
+2.03246817 e-261
+-2.0324681 e-261
+9.84025245 e+260
+-9.8402524 e+260
+1.01623408 e-261
+-1.0162340 e-261
+1.96805049 e+261
+-1.9680504 e+261
+5.08117044 e-262
+-5.0811704 e-262
+3.93610098 e+261
+-3.9361009 e+261
+2.54058522 e-262
+-2.5405852 e-262
+7.87220196 e+261
+-7.8722019 e+261
+1.27029261 e-262
+-1.2702926 e-262
+1.57444039 e+262
+-1.5744403 e+262
+6.35146306 e-263
+-6.3514630 e-263
+3.14888078 e+262
+-3.1488807 e+262
+3.17573153 e-263
+-3.1757315 e-263
+6.29776157 e+262
+-6.2977615 e+262
+1.58786576 e-263
+-1.5878657 e-263
+1.25955231 e+263
+-1.2595523 e+263
+7.93932882 e-264
+-7.9393288 e-264
+2.51910462 e+263
+-2.5191046 e+263
+3.96966441 e-264
+-3.9696644 e-264
+5.03820925 e+263
+-5.0382092 e+263
+1.98483220 e-264
+-1.9848322 e-264
+1.00764185 e+264
+-1.0076418 e+264
+9.92416103 e-265
+-9.9241610 e-265
+2.01528370 e+264
+-2.0152837 e+264
+4.96208051 e-265
+-4.9620805 e-265
+4.03056740 e+264
+-4.0305674 e+264
+2.48104025 e-265
+-2.4810402 e-265
+8.06113481 e+264
+-8.0611348 e+264
+1.24052012 e-265
+-1.2405201 e-265
+1.61222696 e+265
+-1.6122269 e+265
+6.20260064 e-266
+-6.2026006 e-266
+3.22445392 e+265
+-3.2244539 e+265
+3.10130032 e-266
+-3.1013003 e-266
+6.44890785 e+265
+-6.4489078 e+265
+1.55065016 e-266
+-1.5506501 e-266
+1.28978157 e+266
+-1.2897815 e+266
+7.75325080 e-267
+-7.7532508 e-267
+2.57956314 e+266
+-2.5795631 e+266
+3.87662540 e-267
+-3.8766254 e-267
+5.15912628 e+266
+-5.1591262 e+266
+1.93831270 e-267
+-1.9383127 e-267
+1.03182525 e+267
+-1.0318252 e+267
+9.69156350 e-268
+-9.6915635 e-268
+2.06365051 e+267
+-2.0636505 e+267
+4.84578175 e-268
+-4.8457817 e-268
+4.12730102 e+267
+-4.1273010 e+267
+2.42289087 e-268
+-2.4228908 e-268
+8.25460204 e+267
+-8.2546020 e+267
+1.21144543 e-268
+-1.2114454 e-268
+1.65092040 e+268
+-1.6509204 e+268
+6.05722719 e-269
+-6.0572271 e-269
+3.30184081 e+268
+-3.3018408 e+268
+3.02861359 e-269
+-3.0286135 e-269
+6.60368163 e+268
+-6.6036816 e+268
+1.51430679 e-269
+-1.5143067 e-269
+1.32073632 e+269
+-1.3207363 e+269
+7.57153399 e-270
+-7.5715339 e-270
+2.64147265 e+269
+-2.6414726 e+269
+3.78576699 e-270
+-3.7857669 e-270
+5.28294531 e+269
+-5.2829453 e+269
+1.89288349 e-270
+-1.8928834 e-270
+1.05658906 e+270
+-1.0565890 e+270
+9.46441748 e-271
+-9.4644174 e-271
+2.11317812 e+270
+-2.1131781 e+270
+4.73220874 e-271
+-4.7322087 e-271
+4.22635624 e+270
+-4.2263562 e+270
+2.36610437 e-271
+-2.3661043 e-271
+8.45271249 e+270
+-8.4527124 e+270
+1.18305218 e-271
+-1.1830521 e-271
+1.69054249 e+271
+-1.6905424 e+271
+5.91526093 e-272
+-5.9152609 e-272
+3.38108499 e+271
+-3.3810849 e+271
+2.95763046 e-272
+-2.9576304 e-272
+6.76216999 e+271
+-6.7621699 e+271
+1.47881523 e-272
+-1.4788152 e-272
+1.35243399 e+272
+-1.3524339 e+272
+7.39407616 e-273
+-7.3940761 e-273
+2.70486799 e+272
+-2.7048679 e+272
+3.69703808 e-273
+-3.6970380 e-273
+5.40973599 e+272
+-5.4097359 e+272
+1.84851904 e-273
+-1.8485190 e-273
+1.08194719 e+273
+-1.0819471 e+273
+9.24259520 e-274
+-9.2425952 e-274
+2.16389439 e+273
+-2.1638943 e+273
+4.62129760 e-274
+-4.6212976 e-274
+4.32778879 e+273
+-4.3277887 e+273
+2.31064880 e-274
+-2.3106488 e-274
+8.65557759 e+273
+-8.6555775 e+273
+1.15532440 e-274
+-1.1553244 e-274
+1.73111551 e+274
+-1.7311155 e+274
+5.77662200 e-275
+-5.7766220 e-275
+3.46223103 e+274
+-3.4622310 e+274
+2.88831100 e-275
+-2.8883110 e-275
+6.92446207 e+274
+-6.9244620 e+274
+1.44415550 e-275
+-1.4441555 e-275
+1.38489241 e+275
+-1.3848924 e+275
+7.22077750 e-276
+-7.2207775 e-276
+2.76978483 e+275
+-2.7697848 e+275
+3.61038875 e-276
+-3.6103887 e-276
+5.53956966 e+275
+-5.5395696 e+275
+1.80519437 e-276
+-1.8051943 e-276
+1.10791393 e+276
+-1.1079139 e+276
+9.02597187 e-277
+-9.0259718 e-277
+2.21582786 e+276
+-2.2158278 e+276
+4.51298593 e-277
+-4.5129859 e-277
+4.43165573 e+276
+-4.4316557 e+276
+2.25649296 e-277
+-2.2564929 e-277
+8.86331146 e+276
+-8.8633114 e+276
+1.12824648 e-277
+-1.1282464 e-277
+1.77266229 e+277
+-1.7726622 e+277
+5.64123242 e-278
+-5.6412324 e-278
+3.54532458 e+277
+-3.5453245 e+277
+2.82061621 e-278
+-2.8206162 e-278
+7.09064916 e+277
+-7.0906491 e+277
+1.41030810 e-278
+-1.4103081 e-278
+1.41812983 e+278
+-1.4181298 e+278
+7.05154053 e-279
+-7.0515405 e-279
+2.83625966 e+278
+-2.8362596 e+278
+3.52577026 e-279
+-3.5257702 e-279
+5.67251933 e+278
+-5.6725193 e+278
+1.76288513 e-279
+-1.7628851 e-279
+1.13450386 e+279
+-1.1345038 e+279
+8.81442566 e-280
+-8.8144256 e-280
+2.26900773 e+279
+-2.2690077 e+279
+4.40721283 e-280
+-4.4072128 e-280
+4.53801546 e+279
+-4.5380154 e+279
+2.20360641 e-280
+-2.2036064 e-280
+9.07603093 e+279
+-9.0760309 e+279
+1.10180320 e-280
+-1.1018032 e-280
+1.81520618 e+280
+-1.8152061 e+280
+5.50901603 e-281
+-5.5090160 e-281
+3.63041237 e+280
+-3.6304123 e+280
+2.75450801 e-281
+-2.7545080 e-281
+7.26082474 e+280
+-7.2608247 e+280
+1.37725400 e-281
+-1.3772540 e-281
+1.45216494 e+281
+-1.4521649 e+281
+6.88627004 e-282
+-6.8862700 e-282
+2.90432989 e+281
+-2.9043298 e+281
+3.44313502 e-282
+-3.4431350 e-282
+5.80865979 e+281
+-5.8086597 e+281
+1.72156751 e-282
+-1.7215675 e-282
+1.16173195 e+282
+-1.1617319 e+282
+8.60783756 e-283
+-8.6078375 e-283
+2.32346391 e+282
+-2.3234639 e+282
+4.30391878 e-283
+-4.3039187 e-283
+4.64692783 e+282
+-4.6469278 e+282
+2.15195939 e-283
+-2.1519593 e-283
+9.29385567 e+282
+-9.2938556 e+282
+1.07597969 e-283
+-1.0759796 e-283
+1.85877113 e+283
+-1.8587711 e+283
+5.37989847 e-284
+-5.3798984 e-284
+3.71754227 e+283
+-3.7175422 e+283
+2.68994923 e-284
+-2.6899492 e-284
+7.43508454 e+283
+-7.4350845 e+283
+1.34497461 e-284
+-1.3449746 e-284
+1.48701690 e+284
+-1.4870169 e+284
+6.72487309 e-285
+-6.7248730 e-285
+2.97403381 e+284
+-2.9740338 e+284
+3.36243654 e-285
+-3.3624365 e-285
+5.94806763 e+284
+-5.9480676 e+284
+1.68121827 e-285
+-1.6812182 e-285
+1.18961352 e+285
+-1.1896135 e+285
+8.40609136 e-286
+-8.4060913 e-286
+2.37922705 e+285
+-2.3792270 e+285
+4.20304568 e-286
+-4.2030456 e-286
+4.75845410 e+285
+-4.7584541 e+285
+2.10152284 e-286
+-2.1015228 e-286
+9.51690821 e+285
+-9.5169082 e+285
+1.05076142 e-286
+-1.0507614 e-286
+1.90338164 e+286
+-1.9033816 e+286
+5.25380710 e-287
+-5.2538071 e-287
+3.80676328 e+286
+-3.8067632 e+286
+2.62690355 e-287
+-2.6269035 e-287
+7.61352657 e+286
+-7.6135265 e+286
+1.31345177 e-287
+-1.3134517 e-287
+1.52270531 e+287
+-1.5227053 e+287
+6.56725888 e-288
+-6.5672588 e-288
+3.04541062 e+287
+-3.0454106 e+287
+3.28362944 e-288
+-3.2836294 e-288
+6.09082125 e+287
+-6.0908212 e+287
+1.64181472 e-288
+-1.6418147 e-288
+1.21816425 e+288
+-1.2181642 e+288
+8.20907360 e-289
+-8.2090736 e-289
+2.43632850 e+288
+-2.4363285 e+288
+4.10453680 e-289
+-4.1045368 e-289
+4.87265700 e+288
+-4.8726570 e+288
+2.05226840 e-289
+-2.0522684 e-289
+9.74531401 e+288
+-9.7453140 e+288
+1.02613420 e-289
+-1.0261342 e-289
+1.94906280 e+289
+-1.9490628 e+289
+5.13067100 e-290
+-5.1306710 e-290
+3.89812560 e+289
+-3.8981256 e+289
+2.56533550 e-290
+-2.5653355 e-290
+7.79625120 e+289
+-7.7962512 e+289
+1.28266775 e-290
+-1.2826677 e-290
+1.55925024 e+290
+-1.5592502 e+290
+6.41333875 e-291
+-6.4133387 e-291
+3.11850048 e+290
+-3.1185004 e+290
+3.20666937 e-291
+-3.2066693 e-291
+6.23700096 e+290
+-6.2370009 e+290
+1.60333468 e-291
+-1.6033346 e-291
+1.24740019 e+291
+-1.2474001 e+291
+8.01667344 e-292
+-8.0166734 e-292
+2.49480038 e+291
+-2.4948003 e+291
+4.00833672 e-292
+-4.0083367 e-292
+4.98960077 e+291
+-4.9896007 e+291
+2.00416836 e-292
+-2.0041683 e-292
+9.97920154 e+291
+-9.9792015 e+291
+1.00208418 e-292
+-1.0020841 e-292
+1.99584030 e+292
+-1.9958403 e+292
+5.01042090 e-293
+-5.0104209 e-293
+3.99168061 e+292
+-3.9916806 e+292
+2.50521045 e-293
+-2.5052104 e-293
+7.98336123 e+292
+-7.9833612 e+292
+1.25260522 e-293
+-1.2526052 e-293
+1.59667224 e+293
+-1.5966722 e+293
+6.26302612 e-294
+-6.2630261 e-294
+3.19334449 e+293
+-3.1933444 e+293
+3.13151306 e-294
+-3.1315130 e-294
+6.38668899 e+293
+-6.3866889 e+293
+1.56575653 e-294
+-1.5657565 e-294
+1.27733779 e+294
+-1.2773377 e+294
+7.82878265 e-295
+-7.8287826 e-295
+2.55467559 e+294
+-2.5546755 e+294
+3.91439132 e-295
+-3.9143913 e-295
+5.10935119 e+294
+-5.1093511 e+294
+1.95719566 e-295
+-1.9571956 e-295
+1.02187023 e+295
+-1.0218702 e+295
+9.78597832 e-296
+-9.7859783 e-296
+2.04374047 e+295
+-2.0437404 e+295
+4.89298916 e-296
+-4.8929891 e-296
+4.08748095 e+295
+-4.0874809 e+295
+2.44649458 e-296
+-2.4464945 e-296
+8.17496190 e+295
+-8.1749619 e+295
+1.22324729 e-296
+-1.2232472 e-296
+1.63499238 e+296
+-1.6349923 e+296
+6.11623645 e-297
+-6.1162364 e-297
+3.26998476 e+296
+-3.2699847 e+296
+3.05811822 e-297
+-3.0581182 e-297
+6.53996952 e+296
+-6.5399695 e+296
+1.52905911 e-297
+-1.5290591 e-297
+1.30799390 e+297
+-1.3079939 e+297
+7.64529556 e-298
+-7.6452955 e-298
+2.61598781 e+297
+-2.6159878 e+297
+3.82264778 e-298
+-3.8226477 e-298
+5.23197562 e+297
+-5.2319756 e+297
+1.91132389 e-298
+-1.9113238 e-298
+1.04639512 e+298
+-1.0463951 e+298
+9.55661945 e-299
+-9.5566194 e-299
+2.09279024 e+298
+-2.0927902 e+298
+4.77830972 e-299
+-4.7783097 e-299
+4.18558049 e+298
+-4.1855804 e+298
+2.38915486 e-299
+-2.3891548 e-299
+8.37116099 e+298
+-8.3711609 e+298
+1.19457743 e-299
+-1.1945774 e-299
+1.67423219 e+299
+-1.6742321 e+299
+5.97288715 e-300
+-5.9728871 e-300
+3.34846439 e+299
+-3.3484643 e+299
+2.98644357 e-300
+-2.9864435 e-300
+6.69692879 e+299
+-6.6969287 e+299
+1.49322178 e-300
+-1.4932217 e-300
+1.33938575 e+300
+-1.3393857 e+300
+7.46610894 e-301
+-7.4661089 e-301
+2.67877151 e+300
+-2.6787715 e+300
+3.73305447 e-301
+-3.7330544 e-301
+5.35754303 e+300
+-5.3575430 e+300
+1.86652723 e-301
+-1.8665272 e-301
+1.07150860 e+301
+-1.0715086 e+301
+9.33263618 e-302
+-9.3326361 e-302
+2.14301721 e+301
+-2.1430172 e+301
+4.66631809 e-302
+-4.6663180 e-302
+4.28603442 e+301
+-4.2860344 e+301
+2.33315904 e-302
+-2.3331590 e-302
+8.57206885 e+301
+-8.5720688 e+301
+1.16657952 e-302
+-1.1665795 e-302
+1.71441377 e+302
+-1.7144137 e+302
+5.83289761 e-303
+-5.8328976 e-303
+3.42882754 e+302
+-3.4288275 e+302
+2.91644880 e-303
+-2.9164488 e-303
+6.85765508 e+302
+-6.8576550 e+302
+1.45822440 e-303
+-1.4582244 e-303
+1.37153101 e+303
+-1.3715310 e+303
+7.29112201 e-304
+-7.2911220 e-304
+2.74306203 e+303
+-2.7430620 e+303
+3.64556100 e-304
+-3.6455610 e-304
+5.48612406 e+303
+-5.4861240 e+303
+1.82278050 e-304
+-1.8227805 e-304
+1.09722481 e+304
+-1.0972248 e+304
+9.11390252 e-305
+-9.1139025 e-305
+2.19444962 e+304
+-2.1944496 e+304
+4.55695126 e-305
+-4.5569512 e-305
+4.38889925 e+304
+-4.3888992 e+304
+2.27847563 e-305
+-2.2784756 e-305
+8.77779851 e+304
+-8.7777985 e+304
+1.13923781 e-305
+-1.1392378 e-305
+1.75555970 e+305
+-1.7555597 e+305
+5.69618907 e-306
+-5.6961890 e-306
+3.51111940 e+305
+-3.5111194 e+305
+2.84809453 e-306
+-2.8480945 e-306
+7.02223880 e+305
+-7.0222388 e+305
+1.42404726 e-306
+-1.4240472 e-306
+1.40444776 e+306
+-1.4044477 e+306
+7.12023634 e-307
+-7.1202363 e-307
+2.80889552 e+306
+-2.8088955 e+306
+3.56011817 e-307
+-3.5601181 e-307
+5.61779104 e+306
+-5.6177910 e+306
+1.78005908 e-307
+-1.7800590 e-307
+1.12355820 e+307
+-1.1235582 e+307
+8.90029543 e-308
+-8.9002954 e-308
+2.24711641 e+307
+-2.2471164 e+307
+4.45014771 e-308
+-4.4501477 e-308
+4.49423283 e+307
+-4.4942328 e+307
+2.22507385 e-308
+-2.2250738 e-308
+8.98846567 e+307
+-8.9884656 e+307
+1.11253692 e-308
+-1.1125369 e-308
+Infinity
diff --git a/nashorn/test/script/basic/NASHORN-637.js b/nashorn/test/script/basic/NASHORN-637.js
new file mode 100644
index 0000000..606d893
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-637.js
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-637: SyntaxError: Illegal repetition near index 109" on a regexp literal accepted by other engines
+ *
+ * @test
+ * @run
+ */
+
+// Make sure these regexps compile
+print(/(?:[^[#\s\\]+|\\(?:[\S\s]|$)|\[\^?]?(?:[^\\\]]+|\\(?:[\S\s]|$))*]?)+|(\s*#[^\n\r\u2028\u2029]*\s*|\s+)([?*+]|{[0-9]+(?:,[0-9]*)?})?/g);
+print(/{[0-9]+}?/g);
+print(/{[0-9]+}?/g.exec("{123}"));
+
+// Curly brace should match itself if not at the beginning of a valid quantifier
+print(/{a}/.exec("{a}"));
+print(/f{a}/.exec("f{a}"));
+print(/f{1}/.exec("f"));
+try {
+    print(new RegExp("{1}").exec("{1}"));
+} catch (e) {
+    print(e.name);
+}
+try {
+    print(new RegExp("f{1}{1}").exec("f"));
+} catch (e) {
+    print(e.name);
+}
diff --git a/nashorn/test/script/basic/NASHORN-637.js.EXPECTED b/nashorn/test/script/basic/NASHORN-637.js.EXPECTED
new file mode 100644
index 0000000..ab34506
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-637.js.EXPECTED
@@ -0,0 +1,8 @@
+/(?:[^[#\s\\]+|\\(?:[\S\s]|$)|\[\^?]?(?:[^\\\]]+|\\(?:[\S\s]|$))*]?)+|(\s*#[^\n\r\u2028\u2029]*\s*|\s+)([?*+]|{[0-9]+(?:,[0-9]*)?})?/g
+/{[0-9]+}?/g
+{123}
+{a}
+f{a}
+f
+SyntaxError
+SyntaxError
diff --git a/nashorn/test/script/basic/NASHORN-639.js b/nashorn/test/script/basic/NASHORN-639.js
new file mode 100644
index 0000000..fcc02e0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-639.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-639 : Array.prototype.push throws NPE when null is pushed
+ *
+ * @test
+ * @run
+ */
+
+var arr = [];
+arr.push(null);
+
+if (arr.length != 1) {
+    fail("expected arr.length to be 1, it is " + arr.length);
+}
+
+if (arr[0] !== null) {
+    fail("expected arr[0] to be null, it is " + arr[0]);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-64.js b/nashorn/test/script/basic/NASHORN-64.js
new file mode 100644
index 0000000..03d95b2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-64.js
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-64 : <, <=, >, >= implementations are broken.
+ *
+ * @test
+ * @run
+ */
+
+if (! ("abc" < "abceasy")) {
+    print("Error: 'abc' < 'abceasy' is false");
+}
+
+if (! (2 < 3)) {
+    print("Error: 2 < 3 is false");
+}
+
+if (! ("abc" <= "abceasy")) {
+    print("Error: 'abc' <= 'abceasy' is false");
+}
+
+if (! (2 <= 3)) {
+    print("Error: 2 <= 3 is false");
+}
+
+if (! ("abceasy" > "abc")) {
+    print("Error: 'abceasy' > 'abc' is false");
+}
+
+if (! (3 > 2)) {
+    print("Error: 3 > 2 is false");
+}
+
+if (! ("abceasy" >= "abc")) {
+    print("Error: 'abceasy' >= 'abc' is false");
+}
+
+if (! (3 >= 2)) {
+    print("Error: 3 >= 2 is false");
+}
diff --git a/nashorn/test/script/basic/NASHORN-642.js b/nashorn/test/script/basic/NASHORN-642.js
new file mode 100644
index 0000000..acbd602
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-642.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-642: Missing String getter overrides.
+ *
+ * @test
+ * @run
+ */
+
+var k = 14;
+var l = 16;
+
+function test() {
+    var d = "2012-10-09T14:55:52.119Z";
+    print(d, d.length - 1);
+    print(d[d.length - 1], d[d.length - 2] - 1, d[d.length - 2] | 0, d[d.length - 2] >>> 0);
+    print(d[k], d[k] - 1, d[k] | 0, d[k] >>> 0, d[l], d[l] - 1, d[l] | 0, d[l] >>> 0);
+}
+test();
+
diff --git a/nashorn/test/script/basic/NASHORN-642.js.EXPECTED b/nashorn/test/script/basic/NASHORN-642.js.EXPECTED
new file mode 100644
index 0000000..d279890
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-642.js.EXPECTED
@@ -0,0 +1,3 @@
+2012-10-09T14:55:52.119Z 23
+Z 8 9 9
+5 4 5 5 : NaN 0 0
diff --git a/nashorn/test/script/basic/NASHORN-646.js b/nashorn/test/script/basic/NASHORN-646.js
new file mode 100644
index 0000000..493a798
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-646.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-646: Valid JS code with regexp is not parsable by nashorn.
+ *
+ * @test
+ * @run
+ */
+
+function test() { /foo/; }
diff --git a/nashorn/test/script/basic/NASHORN-658.js b/nashorn/test/script/basic/NASHORN-658.js
new file mode 100644
index 0000000..13e5e29
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-658.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-658: nasgen generated constructor functions all have function id 0.
+ *
+ * @test
+ * @run
+ */
+
+function C1() {}
+function C2() {}
+function C3() {}
+
+var ctors = [C1,C2,Number,String,Date,C3];
+
+(function() {
+for (var i in ctors) {
+  var c = ctors[i];
+  if (new c().constructor !== c) {
+    throw "Error: new c().constructor !== c";
+  }
+}
+})();
+
diff --git a/nashorn/test/script/basic/NASHORN-659.js b/nashorn/test/script/basic/NASHORN-659.js
new file mode 100644
index 0000000..7c6c150
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-659.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-659 :  Array literal initialization bug
+ *
+ * @test
+ * @run
+ */
+
+var arr = [17, 0xffffffff];
+if (arr[0] !== 17) {
+    fail("arr[0] !== 17");
+}
+
+if (arr[1] !== 0xffffffff) {
+    fail("arr[1] !== 0xffffffff");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-66.js b/nashorn/test/script/basic/NASHORN-66.js
new file mode 100644
index 0000000..f1455ff
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-66.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-66 :  Date when called as function should return date as a string
+ *
+ * @test
+ * @run
+ */
+
+print("typeof Date() is " + typeof Date());
+print("typeof new Date() is " + typeof new Date());
+
diff --git a/nashorn/test/script/basic/NASHORN-66.js.EXPECTED b/nashorn/test/script/basic/NASHORN-66.js.EXPECTED
new file mode 100644
index 0000000..6b6ca05
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-66.js.EXPECTED
@@ -0,0 +1,2 @@
+typeof Date() is string
+typeof new Date() is object
diff --git a/nashorn/test/script/basic/NASHORN-664.js b/nashorn/test/script/basic/NASHORN-664.js
new file mode 100644
index 0000000..268d5df
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-664.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-664 : Can not set nashorn extension properties such as fileName, lineNumber and columnNumber of Error objects
+ *
+ * @test
+ * @run
+ */
+
+try {
+    throw new Error();
+} catch (e) {
+    e.fileName = "foo";
+    if (e.fileName !== 'foo') {
+        fail("can not set e.fileName");
+    } 
+    e.lineNumber = 100;
+    if (e.lineNumber !== 100) {
+        fail("can not set e.lineNumber");
+    } 
+    e.columnNumber = 33;
+    if (e.columnNumber !== 33) {
+        fail("can not set e.columnNumber");
+    }
+    e.stack = "mystack";
+    if (e.stack !== 'mystack') {
+        fail("can not set e.stack");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-665.js b/nashorn/test/script/basic/NASHORN-665.js
new file mode 100644
index 0000000..54e7f08
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-665.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-665 : delete on string index should return false
+ *
+ * @test
+ * @run
+ */
+
+function func(str) {
+   'use strict';
+
+   try {
+       delete str[0];
+       fail("expected TypeError");
+   } catch (e) {
+       if (! (e instanceof TypeError)) {
+           fail("expected TypeError, got " + e);
+       }
+   }
+}
+
+func(new String("hello"));
+func("hello");
+
+var str = new String("hello");
+if (delete str[0] != false) {
+    fail("delete str[0] does not result in false");
+}
+
+str = "hello";
+if (delete str[0] != false) {
+    fail("delete str[0] does not result in false");
+}
diff --git a/nashorn/test/script/basic/NASHORN-67.js b/nashorn/test/script/basic/NASHORN-67.js
new file mode 100644
index 0000000..b273b42
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-67.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-67 : Nashorn generates nested try catches in the wrong order in the byte code
+ *
+ * @test
+ * @run
+ */
+
+function test_nested() {
+      try {
+	  try {	      
+	      throw new Error("bam!");
+	  } catch (e) {
+	      print("SUCCESS")
+	  }
+      } catch (e2) {
+	  fail("inner catch should have caught the exception");
+      } 
+      
+}
+
+test_nested()
diff --git a/nashorn/test/script/basic/NASHORN-67.js.EXPECTED b/nashorn/test/script/basic/NASHORN-67.js.EXPECTED
new file mode 100644
index 0000000..ff43ca4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-67.js.EXPECTED
@@ -0,0 +1 @@
+SUCCESS
diff --git a/nashorn/test/script/basic/NASHORN-678.js b/nashorn/test/script/basic/NASHORN-678.js
new file mode 100644
index 0000000..e585eb8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-678.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-678 : AssertionError from codegen on indexed access followed by call on 'false' primitive value
+ *
+ * @test
+ * @run
+ */
+
+var prop = "toString";
+if (false[prop]() !== "false") {
+    fail("false['toString']() !== 'false'");
+}
+
+// expand the test to cover access node and scope calls too
+
+if ((33).toString() !== "33") {
+    fail("33.toString() !== '33'");
+}
+
+try {
+    33();
+    fail("should have thrown error"); 
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("expected TypeError, got " + e);
+    }
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-68.js b/nashorn/test/script/basic/NASHORN-68.js
new file mode 100644
index 0000000..d56da36
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-68.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-68 :  Global functions encodeURI, encodeURIComponent are not implemented.
+ *
+ * @test
+ * @run
+ */
+
+print(encodeURI("It's me!!"));
+print(encodeURI("http://en.wikipedia.org/wiki/Алексей"));
+print(encodeURI("http://en.wikipedia.org/wiki/Bj%C3%B6rk"));
+print(encodeURIComponent("Skål"));
diff --git a/nashorn/test/script/basic/NASHORN-68.js.EXPECTED b/nashorn/test/script/basic/NASHORN-68.js.EXPECTED
new file mode 100644
index 0000000..86f442f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-68.js.EXPECTED
@@ -0,0 +1,4 @@
+It's%20me!!
+http://en.wikipedia.org/wiki/%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B5%D0%B9
+http://en.wikipedia.org/wiki/Bj%25C3%25B6rk
+Sk%C3%A5l
diff --git a/nashorn/test/script/basic/NASHORN-689.js b/nashorn/test/script/basic/NASHORN-689.js
new file mode 100644
index 0000000..938b111
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-689.js
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-689 : Any method needs to be able to split even if it contains break, continue or return
+ *
+ * @test
+ * @run
+ */
+
+function x(){}
+
+function test1() {
+  print((function f(a) {
+    print("a="+a);
+    if (a <= 0) { return 0; }
+
+    x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();
+
+    x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();
+
+    return 1 + f(a - 1);
+  })(10));
+}
+
+function test2() {
+    var a = 0;
+    outer: while(true) {
+        while(true) {
+            print("a="+a);
+            if (a >= 10) { break outer; }
+            x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();
+
+            x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();
+            a++;
+        }
+    }
+    print("ok");
+}
+
+function test3() {
+    var a = 0;
+    outer: while(true) {
+        a--;
+        inner: while(++a <= 10) {
+            while(true) {
+                print("a="+a);
+                x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();
+
+                if (a <= 10) { continue inner; }
+
+                x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();
+                throw new Error();
+            }
+            throw new Error();
+        }
+        break;
+    }
+    print("done");
+}
+
+function test4() {
+    // trigger vararg
+    if (!arguments[0])
+        print("no arg");
+
+    var a = {x: 0};
+    while(a.x < 10) {
+        while(true) {
+            with(a) {
+                print("x="+x);
+            }
+            x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();
+
+            with (a) {
+                if (x >= 10) { break; }
+            }
+
+            x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();
+
+            with(a) {
+                x++;
+            }
+        }
+        print("ok");
+        break;
+    }
+    print("done");
+}
+
+test1();
+test2();
+test3();
+test4();
diff --git a/nashorn/test/script/basic/NASHORN-689.js.EXPECTED b/nashorn/test/script/basic/NASHORN-689.js.EXPECTED
new file mode 100644
index 0000000..6244df2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-689.js.EXPECTED
@@ -0,0 +1,50 @@
+a=10
+a=9
+a=8
+a=7
+a=6
+a=5
+a=4
+a=3
+a=2
+a=1
+a=0
+10
+a=0
+a=1
+a=2
+a=3
+a=4
+a=5
+a=6
+a=7
+a=8
+a=9
+a=10
+ok
+a=0
+a=1
+a=2
+a=3
+a=4
+a=5
+a=6
+a=7
+a=8
+a=9
+a=10
+done
+no arg
+x=0
+x=1
+x=2
+x=3
+x=4
+x=5
+x=6
+x=7
+x=8
+x=9
+x=10
+ok
+done
diff --git a/nashorn/test/script/basic/NASHORN-69.js b/nashorn/test/script/basic/NASHORN-69.js
new file mode 100644
index 0000000..9ec39a3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-69.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-69
+ *
+ * @test
+ * @run
+ */
+
+print(-1 >>> 0);
+print(-2147483647 >>> 0);
+print(-1.234 >>> 0);
+print("-1.234" >>> 0);
+print(-5.4321 >>> 0);
+print(2147483648 >>> 0);
+print(4294967295 >>> 0);
+print(2147483648.1 >>> 0);
+print(4294967295 >>> -32.1);
+print(Number.POSITIVE_INFINITY >>> 1);
+print(Number.POSITIVE_INFINITY >>> 0);
+print(Number.NEGATIVE_INFINITY >>> 1);
+print(Number.NEGATIVE_INFINITY >>> 0);
+print(Number.NaN >>> 0);
+print(Number.NaN >>> 1);
diff --git a/nashorn/test/script/basic/NASHORN-69.js.EXPECTED b/nashorn/test/script/basic/NASHORN-69.js.EXPECTED
new file mode 100644
index 0000000..0f81cc0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-69.js.EXPECTED
@@ -0,0 +1,15 @@
+4294967295
+2147483649
+4294967295
+4294967295
+4294967291
+2147483648
+4294967295
+2147483648
+4294967295
+0
+0
+0
+0
+0
+0
diff --git a/nashorn/test/script/basic/NASHORN-691.js b/nashorn/test/script/basic/NASHORN-691.js
new file mode 100644
index 0000000..ec36eed
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-691.js
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-691 :  Get rid of function id guard
+ *
+ * @test
+ * @run
+ */
+
+function func(x) {
+    return function(name) {
+        return x;
+    }
+};
+
+var delegate = {
+   __get__: func(33)
+};
+
+var x = new JSAdapter(delegate);
+
+function f(o) {
+   print('o.foo = ' + o.foo);
+}
+
+f(x);
+
+// now change __get__
+delegate.__get__ = func(44);
+f(x);
+
+var obj = {};
+obj.__noSuchProperty__ = func(3);
+f(obj);
+obj.__noSuchProperty__ = func("hello");
+f(obj);
diff --git a/nashorn/test/script/basic/NASHORN-691.js.EXPECTED b/nashorn/test/script/basic/NASHORN-691.js.EXPECTED
new file mode 100644
index 0000000..693e382
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-691.js.EXPECTED
@@ -0,0 +1,4 @@
+o.foo = 33
+o.foo = 44
+o.foo = 3
+o.foo = hello
diff --git a/nashorn/test/script/basic/NASHORN-694.js b/nashorn/test/script/basic/NASHORN-694.js
new file mode 100644
index 0000000..eb1d294
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-694.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-694 : Provide parser API to parse scripts
+ *
+ * @test
+ * @run
+ */
+
+load("nashorn:parser.js");
+var ast = parse("print('hello')");
+print(ast.type);
+print(ast.body[0].type);
+var callExpr = ast.body[0].expression;
+print(callExpr.type);
+print(callExpr.callee.name);
+print(callExpr.arguments[0].type);
+print(callExpr.arguments[0].value);
diff --git a/nashorn/test/script/basic/NASHORN-694.js.EXPECTED b/nashorn/test/script/basic/NASHORN-694.js.EXPECTED
new file mode 100644
index 0000000..83ceb25
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-694.js.EXPECTED
@@ -0,0 +1,6 @@
+Program
+ExpressionStatement
+CallExpression
+print
+Literal
+hello
diff --git a/nashorn/test/script/basic/NASHORN-697.js b/nashorn/test/script/basic/NASHORN-697.js
new file mode 100644
index 0000000..012f33b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-697.js
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-697 : ScriptFunction should differentiate between "strict" and "builtin"
+ *
+ * @test
+ * @run
+ */
+
+// make sure 'this' transformation is not done for built-ins
+var toString = Object.prototype.toString;
+
+if (toString() !== "[object Undefined]") {
+    fail("toString() !== [object Undefined]");
+}
+
+if (toString.call(null) !== "[object Null]") {
+    fail("toString.call(null) !== [object Null]");
+}
+
+
+// make sure builtin functions are not strict! For example,
+// trying to access arguments and caller should not result in TypeError
+try {
+    if (toString.arguments) {
+        fail("toString.arguments is defined!");
+    }
+} catch (e) {
+    fail("got " + e, e);
+}
+
+try {
+    if (toString.caller) {
+        fail("toString.caller is defined!");
+    }
+} catch (e) {
+    fail("got " + e, e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-703.js b/nashorn/test/script/basic/NASHORN-703.js
new file mode 100644
index 0000000..41d3570
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-703.js
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-703
+ *
+ * Self modifying assignments and ++/-- operators had two issues
+ * 1) the base was loaded twice
+ * 2) if the base was anything but an IdentNode, AccessNode or IndexNode and in the scope, it would
+ *    only be evaluated once, leading to bytecode stack underflow
+ *
+ * This file is split into two tests as the presence of eval affects the whole script
+ *
+ * @test
+ * @run 
+ */
+
+function template() {
+    this.count = 17;
+}
+
+//self assignment to accessnode in scope
+function test1() {
+    a.count++;
+}
+
+function test2() {
+    a2[0].count++;
+}
+
+function test3() {
+    a3[0]++;
+}
+
+function test4() {
+    a4 *= 17;
+}
+
+function test5() {
+    a5.count *= 17;
+}
+
+function test6() {
+    a6[0].count *= 17;
+}
+
+function test7() {
+    a7[0] *= 17;
+}
+
+function tpl() {
+    return new template();
+}
+
+function count() {
+    tpl().count++;
+}
+
+var a = new template();
+test1();
+print(a.count);
+
+var a2 = [new template()];
+test2();
+print(a2[0].count);
+
+var a3 = [1];
+test3();
+print(a3);
+
+var a4 = 4711;
+test4();
+print(a4);
+
+var a5 = new template();
+test5();
+print(a5.count);
+
+var a6 = [new template()];
+test6();
+print(a6[0].count);
+
+var a7 = [1];
+test7();
+print(a7[0]);
+
+
+
+
+
+
+
+
diff --git a/nashorn/test/script/basic/NASHORN-703.js.EXPECTED b/nashorn/test/script/basic/NASHORN-703.js.EXPECTED
new file mode 100644
index 0000000..b5c9084
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-703.js.EXPECTED
@@ -0,0 +1,7 @@
+18
+18
+2
+80087
+289
+289
+17
diff --git a/nashorn/test/script/basic/NASHORN-703a.js b/nashorn/test/script/basic/NASHORN-703a.js
new file mode 100644
index 0000000..18c26a4
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-703a.js
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-703
+ *
+ * Self modifying assignments and ++/-- operators had two issues
+ * 1) the base was loaded twice
+ * 2) if the base was anything but an IdentNode, AccessNode or IndexNode and in the scope, it would
+ *    only be evaluated once, leading to bytecode stack underflow
+ *
+ * This file is split into two tests as the presence of eval affects the whole script
+ *
+ * @test
+ * @run 
+ */
+
+function template() {
+    this.count = 17;
+    eval();
+}
+
+//self assignment to accessnode in scope
+function test1() {
+    a.count++;
+    eval();
+}
+
+function test2() {
+    a2[0].count++;
+    eval();
+}
+
+function test3() {
+    a3[0]++;
+    eval();
+}
+
+function test4() {
+    a4 *= 17;
+    eval();
+}
+
+function test5() {
+    a5.count *= 17;
+    eval();
+}
+
+function test6() {
+    a6[0].count *= 17;
+    eval();
+}
+
+function test7() {
+    a7[0] *= 17;
+    eval();
+}
+
+function tpl() {
+    return new template();
+}
+
+function count() {
+    tpl().count++;
+    eval();
+}
+
+var a = new template();
+test1();
+print(a.count);
+
+var a2 = [new template()];
+test2();
+print(a2[0].count);
+
+var a3 = [1];
+test3();
+print(a3);
+
+var a4 = 4711;
+test4();
+print(a4);
+
+var a5 = new template();
+test5();
+print(a5.count);
+
+var a6 = [new template()];
+test6();
+print(a6[0].count);
+
+var a7 = [1];
+test7();
+print(a7[0]);
+
+
+
+
+
+
+
+
diff --git a/nashorn/test/script/basic/NASHORN-703a.js.EXPECTED b/nashorn/test/script/basic/NASHORN-703a.js.EXPECTED
new file mode 100644
index 0000000..b5c9084
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-703a.js.EXPECTED
@@ -0,0 +1,7 @@
+18
+18
+2
+80087
+289
+289
+17
diff --git a/nashorn/test/script/basic/NASHORN-705.js b/nashorn/test/script/basic/NASHORN-705.js
new file mode 100644
index 0000000..a65ef84
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-705.js
@@ -0,0 +1,35 @@
+#this-line-is-ignored
+/*
+ * 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.
+ */
+
+
+/**
+ * NASHORN-705 : Teach the parser to ignore leading comment lines with # as comment identifier
+ *
+ * @test
+ * @run
+ */
+
+if (! $OPTIONS._scripting) {
+    fail("expected scripting mode with # line");
+}
diff --git a/nashorn/test/script/basic/NASHORN-71.js b/nashorn/test/script/basic/NASHORN-71.js
new file mode 100644
index 0000000..913ff76
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-71.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-71 :  Global functions decodeURI, decodeURICompondet are not implemented.
+ *
+ * @test
+ * @run
+ */
+
+if (decodeURI("It's%20me!!") != "It's me!!") {
+    fail("#1 decodeURI failed");
+}
+
+if (decodeURI("http://en.wikipedia.org/wiki/%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B5%D0%B9") != "http://en.wikipedia.org/wiki/\u0410\u043B\u0435\u043A\u0441\u0435\u0439") {
+    fail("#2 decodeURI failed");
+}
+
+if (decodeURIComponent("Sk%C3%A5l") != "Sk\u00E5l") {
+    fail("decodeURIComponent failed");
+}
diff --git a/nashorn/test/script/basic/NASHORN-710.js b/nashorn/test/script/basic/NASHORN-710.js
new file mode 100644
index 0000000..83b1778
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-710.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-710 - TypeError in Octane pdfjs.js and code-load.js after rev 3364:59041b3f7641
+ *
+ * @test
+ * @run
+ */
+
+var jQuery = (function() {
+
+   var fun = "value";
+
+   var obj =  {
+       a: function() {
+           fun;
+       },
+       b: fun,
+   };
+
+})();
diff --git a/nashorn/test/script/basic/NASHORN-711.js b/nashorn/test/script/basic/NASHORN-711.js
new file mode 100644
index 0000000..af6e9c8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-711.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * NASHORN-711 - Strings broken to multiple lines throw out the line numbering.
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+var x = "aaa\\aaa\r\naaaaa\
+bbbb\"bb\rbbb\
+cccccccc";
+
+print("current line:", new java.lang.Throwable().getStackTrace()[0].getLineNumber());
+try {
+    throw new Error();
+} catch (error) {
+    print("thrown in line:", error.lineNumber);
+}
+
+<<END
+aaaaaaaaa
+bbbbbbbbb
+ccccccccc
+END
+
+print("current line:", new java.lang.Throwable().getStackTrace()[0].getLineNumber());
+try {
+    throw new Error();
+} catch (error) {
+    print("thrown in line:", error.lineNumber);
+}
diff --git a/nashorn/test/script/basic/NASHORN-711.js.EXPECTED b/nashorn/test/script/basic/NASHORN-711.js.EXPECTED
new file mode 100644
index 0000000..7a4e4e8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-711.js.EXPECTED
@@ -0,0 +1,4 @@
+current line: 36
+thrown in line: 38
+current line: 49
+thrown in line: 51
diff --git a/nashorn/test/script/basic/NASHORN-72.js b/nashorn/test/script/basic/NASHORN-72.js
new file mode 100644
index 0000000..edf0a23
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-72.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-72 :  new Object(value) is not properly implemented.
+ *
+ * @test
+ * @run
+ */
+
+var val = new Object("hello");
+print(val);
+
+val = new Object(true);
+print(val);
+
+val = new Object(3.14);
+print(val);
+
+obj = new Object();
+val = new Object(obj);
+print(val);
+print(val === obj);
+
+function func() {}
+val = new Object(func);
+print(val);
+
+// undefined and null value ignored
+val = new Object(null);
+print(val);
+
+val = new Object(undefined);
+print(val);
diff --git a/nashorn/test/script/basic/NASHORN-72.js.EXPECTED b/nashorn/test/script/basic/NASHORN-72.js.EXPECTED
new file mode 100644
index 0000000..6dcbc8d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-72.js.EXPECTED
@@ -0,0 +1,8 @@
+hello
+true
+3.14
+[object Object]
+true
+function func() {}
+[object Object]
+[object Object]
diff --git a/nashorn/test/script/basic/NASHORN-722.js b/nashorn/test/script/basic/NASHORN-722.js
new file mode 100644
index 0000000..e1584ab
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-722.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-722 : NativeStrictArguments doesn't use callee
+ *
+ * @test
+ * @run
+ */
+
+(function () {
+   'use strict';
+
+   try {
+       print(arguments.callee);
+       fail("no TypeError for strict mode arguments.callee");
+   } catch (e) {
+       if (! (e instanceof TypeError)) {
+           fail("expected TypeError, got " + e);
+       }
+   }
+})();
diff --git a/nashorn/test/script/basic/NASHORN-73.js b/nashorn/test/script/basic/NASHORN-73.js
new file mode 100644
index 0000000..04c9690
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-73.js
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-73 :  Loop break should not skip variable declarations.
+ *
+ * @test
+ * @run
+ */
+
+print("x = " + x);
+do {
+   break;
+   var x;
+} while (true);
+
+
+print("y = " + y);
+while (true) {
+    break;
+    var y;
+}
+
+print("z = " + z);
+for ( ; ; ) {
+   break;
+   var z;
+   print("THIS SHOULD NEVER BE PRINTED!");
+}
+
+while (true) {
+    break;
+    if (true) { 
+	var s; 
+    }
+}
+
+print("s = "+s);
+
+print("u = "+u);
+for ( ; ; ) {
+    break;
+    while (true) {
+	do {
+	    var u;
+	} while (true);
+    }    
+}
+
+function terminal() {
+    print("r = "+r);
+    print("t = "+t);
+    for (;;) {
+	var r;
+	return;
+	var t;
+	print("THIS SHOULD NEVER BE PRINTED!");
+    }
+    print("NEITHER SHOULD THIS");
+}
+
+terminal();
+
+function terminal2() {
+    print("q = "+q);
+    for (;;) {
+	return;
+	print("THIS SHOULD NEVER BE PRINTED!");
+    }
+    print("NEITHER SHOULD THIS");
+}
+
+try { 
+    terminal2();
+} catch (e) {
+    print(e);
+}
+
+function scope2() {
+    var b = 10;
+    print("b = "+b);
+}
+
+scope2();
+
+try {
+    print("b is = "+b);
+}  catch (e) {
+    print(e);
+}
+	
+
+function disp_a() {
+    var a = 20;
+    print("Value of 'a' inside the function " + a);
+}
+	
+var a = 10;
+
+disp_a();
+
+print("Value of 'a' outside the function " + a);
diff --git a/nashorn/test/script/basic/NASHORN-73.js.EXPECTED b/nashorn/test/script/basic/NASHORN-73.js.EXPECTED
new file mode 100644
index 0000000..4a513f9
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-73.js.EXPECTED
@@ -0,0 +1,12 @@
+x = undefined
+y = undefined
+z = undefined
+s = undefined
+u = undefined
+r = undefined
+t = undefined
+ReferenceError: "q" is not defined
+b = 10
+ReferenceError: "b" is not defined
+Value of 'a' inside the function 20
+Value of 'a' outside the function 10
diff --git a/nashorn/test/script/basic/NASHORN-737.js b/nashorn/test/script/basic/NASHORN-737.js
new file mode 100644
index 0000000..44169d0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-737.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-737 : NodeVisitor methods with LabeledNode parameters never called
+ *
+ * @test
+ * @run
+ */
+
+load("nashorn:parser.js");
+var ast = parse("label: while(true) break label;");
+print(JSON.stringify(ast));
diff --git a/nashorn/test/script/basic/NASHORN-737.js.EXPECTED b/nashorn/test/script/basic/NASHORN-737.js.EXPECTED
new file mode 100644
index 0000000..8f82834
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-737.js.EXPECTED
@@ -0,0 +1 @@
+{"type":"Program","rest":null,"body":[{"type":"LabeledStatement","label":{"type":"Identifier","name":"label"},"body":{"type":"BlockStatement","body":[{"type":"WhileStatement","test":{"type":"Literal","value":true},"block":{"type":"BlockStatement","body":[{"type":"BreakStatement","label":"label"}]}}]}}]}
diff --git a/nashorn/test/script/basic/NASHORN-74.js b/nashorn/test/script/basic/NASHORN-74.js
new file mode 100644
index 0000000..1d44e06
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-74.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-74
+ *
+ * @test
+ * @run
+ */
+
+for (;;) {
+    break;
+}
+print("after for loop");
+
diff --git a/nashorn/test/script/basic/NASHORN-74.js.EXPECTED b/nashorn/test/script/basic/NASHORN-74.js.EXPECTED
new file mode 100644
index 0000000..9863a4b
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-74.js.EXPECTED
@@ -0,0 +1 @@
+after for loop
diff --git a/nashorn/test/script/basic/NASHORN-740.js b/nashorn/test/script/basic/NASHORN-740.js
new file mode 100644
index 0000000..553efdd
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-740.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-740 : Lexer/parser treating division as regexp
+ *
+ * @test
+ * @run
+ */
+
+var x = 1;
+print(x++/2/3);
+print(x++/2/3+x);
diff --git a/nashorn/test/script/basic/NASHORN-740.js.EXPECTED b/nashorn/test/script/basic/NASHORN-740.js.EXPECTED
new file mode 100644
index 0000000..23bd8b6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-740.js.EXPECTED
@@ -0,0 +1,2 @@
+0.16666666666666666
+3.3333333333333335
diff --git a/nashorn/test/script/basic/NASHORN-75.js b/nashorn/test/script/basic/NASHORN-75.js
new file mode 100644
index 0000000..ebcd782
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-75.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-75 :  Calling non-functions should result in TypeError
+ *
+ * @test
+ * @run
+ */
+
+try {
+    RegExp("a|b", "g")();
+} catch (e) {
+    print(e);
+}
+
+try {
+    new String("hello")();
+} catch (e) {
+    print(e);
+}
+
+try {
+    new Object()();
+} catch (e) {
+    print(e);
+}
diff --git a/nashorn/test/script/basic/NASHORN-75.js.EXPECTED b/nashorn/test/script/basic/NASHORN-75.js.EXPECTED
new file mode 100644
index 0000000..e1352a3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-75.js.EXPECTED
@@ -0,0 +1,3 @@
+TypeError: [RegExp /a|b/g] is not a function
+TypeError: [String hello] is not a function
+TypeError: [object Object] is not a function
diff --git a/nashorn/test/script/basic/NASHORN-758.js b/nashorn/test/script/basic/NASHORN-758.js
new file mode 100644
index 0000000..f57eaf1
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-758.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-758 : nashorn shell command line options improvements
+ *
+ * @test
+ * @option -Dnashorn.test.foo=bar
+ * @option -Dnashorn.test.hello=world
+ * @run
+ */
+
+
+if (java.lang.System.getProperty("nashorn.test.foo") != "bar") {
+    fail("System property 'nashorn.test.foo' != 'bar'");
+}
+
+if (java.lang.System.getProperty("nashorn.test.hello") != "world") {
+    fail("System property 'nashorn.test.hello' != 'world'");
+}
diff --git a/nashorn/test/script/basic/NASHORN-759.js b/nashorn/test/script/basic/NASHORN-759.js
new file mode 100644
index 0000000..09d2b3e
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-759.js
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+/*
+ * NASHORN-759 - Efficient string concatenation with + operator
+ *
+ * @test
+ * @run
+ */
+
+// Check invalidation of callsite for non-string CharSequence
+function checkProps(s) {
+    print(typeof s);
+    print(typeof s.length);
+    print(s.charCodeAt === String.prototype.charCodeAt);
+    print();
+}
+
+var s1 = "foo";
+var s2 = "bar";
+var s3 = s1 + s2 + s1 + s2;
+var s4 = new java.lang.StringBuilder("abc");
+checkProps(s1);
+checkProps(s2);
+checkProps(s3);
+checkProps(s4);
+
+// Rebuild string and compare to original
+function rebuildString(s) {
+    var buf = s.split("");
+    print(buf);
+    while (buf.length > 1) {
+        var result = [];
+        buf.reduce(function(previous, current, index) {
+            if (previous) {
+                result.push(previous + current);
+                return null;
+            } else if (index === buf.length - 1) {
+                result.push(current);
+                return null;
+            } else {
+                return current;
+            }
+        });
+        buf = result;
+        print(buf);
+    }
+    return buf[0];
+}
+
+var n1 = "The quick gray nashorn jumps over the lazy zebra.";
+var n2 = rebuildString(n1);
+print(n1, n2, n2.length, n1 == n2, n1 === n2, n1 < n2, n1 <= n2, n1 > n2, n1 >= n2);
+checkProps(n2);
+
+var n3 = rebuildString(rebuildString(n2));
+print(n3, n3.length, n1 == n3, n2 == n3, n1 === n3, n2 === n3);
+checkProps(n3);
diff --git a/nashorn/test/script/basic/NASHORN-759.js.EXPECTED b/nashorn/test/script/basic/NASHORN-759.js.EXPECTED
new file mode 100644
index 0000000..ccb88e0
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-759.js.EXPECTED
@@ -0,0 +1,47 @@
+string
+number
+true
+
+string
+number
+true
+
+string
+number
+true
+
+object
+object
+false
+
+T,h,e, ,q,u,i,c,k, ,g,r,a,y, ,n,a,s,h,o,r,n, ,j,u,m,p,s, ,o,v,e,r, ,t,h,e, ,l,a,z,y, ,z,e,b,r,a,.
+Th,e ,qu,ic,k ,gr,ay, n,as,ho,rn, j,um,ps, o,ve,r ,th,e ,la,zy, z,eb,ra,.
+The ,quic,k gr,ay n,asho,rn j,umps, ove,r th,e la,zy z,ebra,.
+The quic,k gray n,ashorn j,umps ove,r the la,zy zebra,.
+The quick gray n,ashorn jumps ove,r the lazy zebra,.
+The quick gray nashorn jumps ove,r the lazy zebra.
+The quick gray nashorn jumps over the lazy zebra.
+The quick gray nashorn jumps over the lazy zebra. The quick gray nashorn jumps over the lazy zebra. 49 true true false true false true
+string
+number
+true
+
+T,h,e, ,q,u,i,c,k, ,g,r,a,y, ,n,a,s,h,o,r,n, ,j,u,m,p,s, ,o,v,e,r, ,t,h,e, ,l,a,z,y, ,z,e,b,r,a,.
+Th,e ,qu,ic,k ,gr,ay, n,as,ho,rn, j,um,ps, o,ve,r ,th,e ,la,zy, z,eb,ra,.
+The ,quic,k gr,ay n,asho,rn j,umps, ove,r th,e la,zy z,ebra,.
+The quic,k gray n,ashorn j,umps ove,r the la,zy zebra,.
+The quick gray n,ashorn jumps ove,r the lazy zebra,.
+The quick gray nashorn jumps ove,r the lazy zebra.
+The quick gray nashorn jumps over the lazy zebra.
+T,h,e, ,q,u,i,c,k, ,g,r,a,y, ,n,a,s,h,o,r,n, ,j,u,m,p,s, ,o,v,e,r, ,t,h,e, ,l,a,z,y, ,z,e,b,r,a,.
+Th,e ,qu,ic,k ,gr,ay, n,as,ho,rn, j,um,ps, o,ve,r ,th,e ,la,zy, z,eb,ra,.
+The ,quic,k gr,ay n,asho,rn j,umps, ove,r th,e la,zy z,ebra,.
+The quic,k gray n,ashorn j,umps ove,r the la,zy zebra,.
+The quick gray n,ashorn jumps ove,r the lazy zebra,.
+The quick gray nashorn jumps ove,r the lazy zebra.
+The quick gray nashorn jumps over the lazy zebra.
+The quick gray nashorn jumps over the lazy zebra. 49 true true true true
+string
+number
+true
+
diff --git a/nashorn/test/script/basic/NASHORN-760.js b/nashorn/test/script/basic/NASHORN-760.js
new file mode 100644
index 0000000..1974dde
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-760.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-111 :  ClassCastException from JSON.stringify
+ *
+ * @test
+ * @run
+ */
+// problem 1
+// the conversions in TernaryNode are not necessary, but they should not cause problems. They did
+// this was because the result of Global.allocate(Object[])Object which returns a NativeObject. 
+// was tracked as an object type on our stack. The type system did not recognize this as an array. 
+// Then the explicit conversions became "convert NativeArray->Object[]" which is a checkccast Object[]
+// which naturally failed.
+
+// I pushed the appropriate arraytype on the stack for Global.allocate.
+
+// I also removed the conversions in CodeGen, all conversions should be done in Lower, as
+// NASHORN-706 states.
+
+var silent = false;
+var stdio = silent ? ['pipe', 'pipe', 'pipe', 'ipc'] : [0, 1, 2, 'ipc'];
+
+// This made the test pass, but it's still not correct to pick widest types for array
+// and primitives. Widest(Object[], int) gave us Object[] which makes no sense. This is used
+// by lower to type the conversions, so function b below also failed until I made a change
+// ty type widest to actually return the widest common denominator, if both aren't arrays
+
+function b() {
+    var silent2 = false;
+    var stdio2 = silent2 ? [1,2,3] : 17;
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-768.js b/nashorn/test/script/basic/NASHORN-768.js
new file mode 100644
index 0000000..5723d6d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-768.js
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-768 :  Implement cross context property/function access and browser JSObject access by JSObject dynalink linker
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+// create another nashorn engine
+var m = new javax.script.ScriptEngineManager();
+var engine = m.getEngineByName("nashorn");
+
+// our global var 'id'
+var id = "global-id";
+
+engine.eval(<<CODE
+
+// code evaluated in engine
+
+// engine code's id
+var id = "engine-global-id";
+
+// global object
+var obj = {
+    foo: 42,
+    bar: function(x) { 
+        if (id != "engine-global-id") {
+            throw "id != 'engine-global-id'";
+        }
+        // check this.foo is accessible
+        if (this.foo != 42) {
+            throw "this.foo != 42";
+        }
+
+        return x;
+    }
+};
+
+// global function
+function func(callback) {
+    var res = callback(id);
+    if (res != id) {
+        fail("result of callback is wrong");
+    }
+}
+
+CODE);
+
+var obj = engine.get("obj");
+if (obj.bar("hello") != "hello") {
+    fail("obj.bar('hello') return value is wrong");
+}
+
+if (obj.foo != 42) {
+    fail("obj.foo != 42");
+}
+
+var func = engine.get("func");
+var inside_f = false;
+function f(arg) {
+    inside_f = true;
+    if (id != "global-id") {
+        fail("id != 'global-id'");
+    }
+    return arg;
+}
+func(f);
+if (! inside_f) {
+    fail("function 'f' was not called");
+}
diff --git a/nashorn/test/script/basic/NASHORN-778.js b/nashorn/test/script/basic/NASHORN-778.js
new file mode 100644
index 0000000..b165882
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-778.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-778 : Debug.toString prints "undefined" That is wrong.
+ *
+ * @test
+ * @run
+ */
+
+if (typeof Debug != 'undefined' && Debug.toString() !== "[object Debug]") {
+    fail("Debug.toString() !== '[object Debug]'");
+}
diff --git a/nashorn/test/script/basic/NASHORN-78.js b/nashorn/test/script/basic/NASHORN-78.js
new file mode 100644
index 0000000..549164d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-78.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-78 :  Calling undefined global function should result in ReferenceError and not TypeError.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    x();
+} catch (e) {
+    if (! (e instanceof ReferenceError)) {
+        fail("expecting ReferenceError");
+    }
+}
+
+try {
+    var obj = {};
+    obj.x();
+} catch (e2) {
+    if (! (e2 instanceof TypeError)) {
+        fail("expecting TypeError");
+    }
+}
+
+try {
+    obj(); // call obj which is not a function!
+} catch (e3) {
+    if (! (e3 instanceof TypeError)) {
+        fail("expecting TypeError");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-79.js b/nashorn/test/script/basic/NASHORN-79.js
new file mode 100644
index 0000000..d6f1e05
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-79.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-79 :  Functions defined inside expressions can be recursive.
+ *
+ * @test
+ * @run
+ */
+
+
+print((function f(a) {
+    return a == 0? 1 : a*f(a-1);
+})(4));
+ 
+ 
+print((function g(a) {
+    function g(a) { return 1000; }
+    return a == 0? 1 : a*g(a-1);
+})(4));
diff --git a/nashorn/test/script/basic/NASHORN-79.js.EXPECTED b/nashorn/test/script/basic/NASHORN-79.js.EXPECTED
new file mode 100644
index 0000000..6c763b8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-79.js.EXPECTED
@@ -0,0 +1,2 @@
+24
+4000
diff --git a/nashorn/test/script/basic/NASHORN-792.js b/nashorn/test/script/basic/NASHORN-792.js
new file mode 100644
index 0000000..3ba0102
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-792.js
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-792 :  Parser accepts identifiers that are invalid per the ES5 spec.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval("var \\u002E = 10;");
+} catch (ex) {
+    print(ex.constructor.name);
+}
+
+try {
+    eval("var a\\u002Eb = 10;");
+} catch (ex) {
+    print(ex.constructor.name);
+}
+
+try {
+    eval("var a\\u002xb = 10;");
+} catch (ex) {
+    print(ex.constructor.name);
+}
+
+try {
+    eval("function \\u002B() {}");
+} catch (ex) {
+    print(ex.constructor.name);
+}
+
+try {
+    eval("function a\\u002Bb() {}");
+} catch (ex) {
+    print(ex.constructor.name);
+}
+
+try {
+    eval("function a\\u002xb() {}");
+} catch (ex) {
+    print(ex.constructor.name);
+}
+
+try {
+    eval("function \\u0030() {}");
+} catch (ex) {
+    print(ex.constructor.name);
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-792.js.EXPECTED b/nashorn/test/script/basic/NASHORN-792.js.EXPECTED
new file mode 100644
index 0000000..bef69eb
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-792.js.EXPECTED
@@ -0,0 +1,7 @@
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
diff --git a/nashorn/test/script/basic/NASHORN-80.js b/nashorn/test/script/basic/NASHORN-80.js
new file mode 100644
index 0000000..aeb496f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-80.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-80 :  Default values of built-in prototypes are wrong.
+ *
+ * @test
+ * @run
+ */
+
+print(Boolean.prototype);
+print(Number.prototype);
+print(String.prototype);
+print(RegExp.prototype);
+print(Date.prototype);
diff --git a/nashorn/test/script/basic/NASHORN-80.js.EXPECTED b/nashorn/test/script/basic/NASHORN-80.js.EXPECTED
new file mode 100644
index 0000000..c799bac
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-80.js.EXPECTED
@@ -0,0 +1,5 @@
+false
+0
+
+/(?:)/
+Invalid Date
diff --git a/nashorn/test/script/basic/NASHORN-81.js b/nashorn/test/script/basic/NASHORN-81.js
new file mode 100644
index 0000000..44cda68
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-81.js
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-81:  RHS of "in" operator should be of Object type, TypeError should be thrown otherwise
+ *
+ * @test
+ * @run
+ */
+
+try {
+    print("foo" in false);
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#1: TypeError expected");
+    }
+}
+
+try {
+    print("foo" in 3.14);
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#2: TypeError expected");
+    }
+}
+
+try {
+    print("foo" in "bar");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#3: TypeError expected");
+    }
+}
+
+try {
+    print("foo" in "bar");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#4: TypeError expected");
+    }
+}
+
+try {
+    print("foo" in null);
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#5: TypeError expected");
+    }
+}
+
+try {
+    print("foo" in undefined);
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#6: TypeError expected");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-833.js b/nashorn/test/script/basic/NASHORN-833.js
new file mode 100644
index 0000000..b3d0d31
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-833.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-833 : __lookupGetter__ and __lookupSetter__ in mozilla_compat.js don't return inherited properties
+ *
+ * @test
+ * @run
+ */
+
+load("nashorn:mozilla_compat.js");
+
+var x = {};
+x.__defineGetter__("a", function() {print("Getting a");});
+x.__defineSetter__("a", function() {print("Setting a");});
+
+var y = Object.create(x);
+
+y.__lookupGetter__("a")();
+y.__lookupSetter__("a")();
diff --git a/nashorn/test/script/basic/NASHORN-833.js.EXPECTED b/nashorn/test/script/basic/NASHORN-833.js.EXPECTED
new file mode 100644
index 0000000..41a3390
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-833.js.EXPECTED
@@ -0,0 +1,2 @@
+Getting a
+Setting a
diff --git a/nashorn/test/script/basic/NASHORN-837.js b/nashorn/test/script/basic/NASHORN-837.js
new file mode 100644
index 0000000..0632fb3
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-837.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-837 : refSymbol lookup caused nullpointer exception in Lower
+ *
+ * @test
+ * @run
+ */
+
+var failed = false;
+
+try {
+    try {
+	throw new TypeError('error');
+    } catch (iox) {
+	function f() {
+	    print(iox.message);
+	}
+    }
+    f();
+} catch (e) {
+    failed = (e instanceof ReferenceError);
+    //iox not defined should be thrown
+}
+
+if (!failed) {
+    print("Failure! iox did not throw correct exception");
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-85.js b/nashorn/test/script/basic/NASHORN-85.js
new file mode 100644
index 0000000..bdad20f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-85.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-85 :  String.prototype.length field should not be undefined
+ *
+ * @test
+ * @run
+ */
+
+print("String.prototype.length is " + String.prototype.length);
diff --git a/nashorn/test/script/basic/NASHORN-85.js.EXPECTED b/nashorn/test/script/basic/NASHORN-85.js.EXPECTED
new file mode 100644
index 0000000..ee929d7
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-85.js.EXPECTED
@@ -0,0 +1 @@
+String.prototype.length is 0
diff --git a/nashorn/test/script/basic/NASHORN-86.js b/nashorn/test/script/basic/NASHORN-86.js
new file mode 100644
index 0000000..0723726
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-86.js
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-86 :  right hand side of instanceof operator should be objects that have [[HasInstance]]
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+
+try {
+    print(obj instanceof true);
+    fail("#1 TypeError expected");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#1 TypeError expected");
+    }
+}
+
+try {
+    print(obj instanceof 3.14);
+    fail("#2 TypeError expected");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#2 TypeError expected");
+    }
+}
+
+try {
+    print(obj instanceof "hello");
+    fail("#3 TypeError expected");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#3 TypeError expected");
+    }
+}
+try {
+    var foo = {};
+    print(obj instanceof foo);
+    fail("#4 TypeError expected");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("#4 TypeError expected");
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-87.js b/nashorn/test/script/basic/NASHORN-87.js
new file mode 100644
index 0000000..2283dcd
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-87.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-87 :  NativeDate class misses @Function for few functions
+ *
+ * @test
+ * @run
+ */
+
+function check(func, name) {
+    if (typeof func != 'function') {
+        throw Error("Date.prototype." + name + " is not function");
+    }
+}
+
+check(Date.prototype.getUTCMonth, "getUTCMonth")
+check(Date.prototype.getUTCDay, "getUTCDay");
+check(Date.prototype.setMilliseconds, "setMilliseconds");
+check(Date.prototype.setUTCMilliseconds, "setUTCMilliseconds");
diff --git a/nashorn/test/script/basic/NASHORN-89.js b/nashorn/test/script/basic/NASHORN-89.js
new file mode 100644
index 0000000..5491239
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-89.js
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-89 :  Date functions and constructor should evaluate vararg arguments in the order of appearance.
+ *
+ * @test
+ * @run
+ */
+
+function MyObj(val) {
+    return {
+        valueOf: function() { throw "value-" + val; }
+    }
+}
+
+try {
+    var d = new Date(1980, new MyObj(2), new MyObj(3), new MyObj(4));
+} catch(e) {
+    if (e != 'value-2') {
+        fail("expecting 'value-2' got " + e);
+    }
+}
+
+try {
+    var d = new Date(1980, 2, new MyObj(3), new MyObj(4), new MyObj(5));
+} catch(e) {
+    if (e != 'value-3') {
+        fail("expecting 'value-3' got " + e);
+    }
+}
+
+try {
+    var d = new Date(1980, 2, 1, new MyObj(4), new MyObj(5), new MyObj(6));
+} catch(e) {
+    if (e != 'value-4') {
+        fail("expecting 'value-4' got " + e);
+    }
+}
+
+try {
+    var d = new Date(1980, 2, 1, 1, new MyObj(5), new MyObj(6), new MyObj(7));
+} catch(e) {
+    if (e != 'value-5') {
+        fail("expecting 'value-5' got " + e);
+    }
+}
+try {
+    var d = new Date(1980, 2, 1, 1, 1, new MyObj(6), new MyObj(7));
+} catch(e) {
+    if (e != 'value-6') {
+        fail("expecting 'value-6' got " + e);
+    }
+}
+try {
+    var d = new Date(1980, 2, 1, 1, 1, 1, new MyObj(7));
+} catch(e) {
+    if (e != 'value-7') {
+        fail("expecting 'value-7' got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/NASHORN-90.js b/nashorn/test/script/basic/NASHORN-90.js
new file mode 100644
index 0000000..99c2a4a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-90.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-90 : Function constructor does not work when creating function accepting many arguments.
+ *
+ * @test
+ * @run
+ */
+
+var avg = new Function("x", "y", "return x + y/ 2");
+print("avg.length = " + avg.length);
+print(avg);
+print("avg(34, 44) = " + avg(34, 44));
diff --git a/nashorn/test/script/basic/NASHORN-90.js.EXPECTED b/nashorn/test/script/basic/NASHORN-90.js.EXPECTED
new file mode 100644
index 0000000..400d39d
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-90.js.EXPECTED
@@ -0,0 +1,5 @@
+avg.length = 2
+function (x,y) {
+return x + y/ 2
+}
+avg(34, 44) = 56
diff --git a/nashorn/test/script/basic/NASHORN-91.js b/nashorn/test/script/basic/NASHORN-91.js
new file mode 100644
index 0000000..1e1df61
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-91.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-91 :  Date.prototype.setYear is undefined.
+ *
+ * @test
+ * @run
+ */
+
+if (typeof Date.prototype.setYear != 'function') {
+    fail("Date.prototype.setYear is not a function");
+}
+
+print("Date.prototype.setYear.length = " + Date.prototype.setYear.length);
+
+var d = new Date(1990, 1, 1);
+print(d.getYear());
+d.setYear(89);
+print(d.getYear());
+d.setYear(2013);
+print(d.getYear());
diff --git a/nashorn/test/script/basic/NASHORN-91.js.EXPECTED b/nashorn/test/script/basic/NASHORN-91.js.EXPECTED
new file mode 100644
index 0000000..a665a14
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-91.js.EXPECTED
@@ -0,0 +1,4 @@
+Date.prototype.setYear.length = 1
+90
+89
+113
diff --git a/nashorn/test/script/basic/NASHORN-92.js b/nashorn/test/script/basic/NASHORN-92.js
new file mode 100644
index 0000000..a05997f
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-92.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-92 :  Date.prototype.toGMTString is undefined.
+ *
+ * @test
+ * @run
+ */
+
+if ((typeof Date.prototype.toGMTString) != 'function') {
+    fail("Date.prototype.toGMTString is not a function");
+}
+
+print("Date.prototype.toGMTString.length = " + Date.prototype.toGMTString.length);
+
+var d = new Date();
+d.setUTCFullYear(1999, 1, 1);
+if (d.toGMTString() != d.toUTCString()) {
+    fail("toGMTString() and toUTCString() return different values");
+}
+print(d.toGMTString().substring(0, 16));
diff --git a/nashorn/test/script/basic/NASHORN-92.js.EXPECTED b/nashorn/test/script/basic/NASHORN-92.js.EXPECTED
new file mode 100644
index 0000000..a09cab2
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-92.js.EXPECTED
@@ -0,0 +1,2 @@
+Date.prototype.toGMTString.length = 0
+Mon, 01 Feb 1999
diff --git a/nashorn/test/script/basic/NASHORN-93.js b/nashorn/test/script/basic/NASHORN-93.js
new file mode 100644
index 0000000..c424728
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-93.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-93 :  redeclaration of variable does not work as expected
+ *
+ * @test
+ * @run
+ */
+
+var x = 3;
+if (typeof x != 'number') {
+    fail("typeof x should be 'number' but got " + (typeof x));
+}
+var x = new Object();
+if (typeof x != 'object') {
+    fail("typeof x should be 'object' but got " + (typeof x));
+}
+
diff --git a/nashorn/test/script/basic/NASHORN-95.js b/nashorn/test/script/basic/NASHORN-95.js
new file mode 100644
index 0000000..38d7285
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-95.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-95 :  function length is always -1 when it uses "arguments" regardless of actual formals specified.
+ *
+ *
+ * @test
+ * @run
+ */
+
+function func1() {
+    print(arguments);
+}
+
+function func2(x, y) {
+    print(arguments);
+}
+
+function func3(x, y, z) {
+    print(arguments);
+}
+
+// more than arglimit number of arguments - so uses varargs in impl..
+function func4(a, b, c, d, e, f, g, h, i, j) {}
+
+print("func1.length = " + func1.length);
+print("func2.length = " + func2.length);
+print("func3.length = " + func3.length);
+print("func4.length = " + func4.length);
diff --git a/nashorn/test/script/basic/NASHORN-95.js.EXPECTED b/nashorn/test/script/basic/NASHORN-95.js.EXPECTED
new file mode 100644
index 0000000..3926ff6
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-95.js.EXPECTED
@@ -0,0 +1,4 @@
+func1.length = 0
+func2.length = 2
+func3.length = 3
+func4.length = 10
diff --git a/nashorn/test/script/basic/NASHORN-96.js b/nashorn/test/script/basic/NASHORN-96.js
new file mode 100644
index 0000000..451b018
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-96.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-96 : split with parenthesis grups
+ *
+ * @test
+ * @run
+ */
+
+var __result = "One dog, two dogs in the yard.".split(/(d)(o)(g)/);
+print(__result);
+regexp = new RegExp("(d)(o)(g)");
+__result = "One dog, two dogs in the yard.".split(regexp);
+print(__result);
diff --git a/nashorn/test/script/basic/NASHORN-96.js.EXPECTED b/nashorn/test/script/basic/NASHORN-96.js.EXPECTED
new file mode 100644
index 0000000..c1a0cb8
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-96.js.EXPECTED
@@ -0,0 +1,2 @@
+One ,d,o,g,, two ,d,o,g,s in the yard.
+One ,d,o,g,, two ,d,o,g,s in the yard.
diff --git a/nashorn/test/script/basic/NASHORN-97.js b/nashorn/test/script/basic/NASHORN-97.js
new file mode 100644
index 0000000..0f7128a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-97.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-97 :  Function.prototype should return undefined when invoked as a function
+ *
+ * @test
+ * @run
+ */
+
+if ( Function.prototype(23) !== undefined) {
+    throw new Error("#1 Function.prototype should return undefined when invoked");
+}
+
+if ( Function.prototype(23, "hello", {}) !== undefined) {
+    throw new Error("#2 Function.prototype should return undefined when invoked");
+}
diff --git a/nashorn/test/script/basic/NASHORN-98.js b/nashorn/test/script/basic/NASHORN-98.js
new file mode 100644
index 0000000..3e50cf5
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-98.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-98 :  Array literal elements and object literal properties should be comma separated.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval("var x = [ 23 34 ]");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+       fail("syntax error expected here got " + e);
+    }
+    print(e.toString().replace(/\\/g, '/'));
+} 
+
+try {
+    eval("var x = { foo: 33 bar: 'hello' }");
+} catch (e) {
+    if (! (e instanceof SyntaxError)) {
+       fail("syntax error expected here got " + e);
+    }
+    print(e.toString().replace(/\\/g, '/'));
+} 
diff --git a/nashorn/test/script/basic/NASHORN-98.js.EXPECTED b/nashorn/test/script/basic/NASHORN-98.js.EXPECTED
new file mode 100644
index 0000000..93a8936
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-98.js.EXPECTED
@@ -0,0 +1,6 @@
+SyntaxError: test/script/basic/NASHORN-98.js#32<eval>:1:13 Expected comma but found decimal
+var x = [ 23 34 ]
+             ^
+SyntaxError: test/script/basic/NASHORN-98.js#41<eval>:1:18 Expected comma but found ident
+var x = { foo: 33 bar: 'hello' }
+                  ^
diff --git a/nashorn/test/script/basic/NASHORN-99.js b/nashorn/test/script/basic/NASHORN-99.js
new file mode 100644
index 0000000..eaf717a
--- /dev/null
+++ b/nashorn/test/script/basic/NASHORN-99.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/**
+ * NASHORN-99 :  Passing less number of arguments to a native varargs function results in IllegalArgumentException.
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+}
+
+try {
+    func.call();
+} catch (e) {
+    fail("func.call() failed", e);
+}
+
+var obj = Object.create(Function.prototype);
+
+if (typeof obj.call !== "function") {
+    fail('#1: call method not found!');
+}
+
+try {
+    obj.call();
+    fail('#2: No [[Call]] property, a TypeError expected');
+} catch (e) {
+    if (!(e instanceof TypeError)) {
+        fail('#3: TypeError expected but got ' + e);
+    }
+}
diff --git a/nashorn/test/script/basic/access-specializer.js b/nashorn/test/script/basic/access-specializer.js
new file mode 100644
index 0000000..d60260a
--- /dev/null
+++ b/nashorn/test/script/basic/access-specializer.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * This is a simple test that checks that access specialization in FinalizeTypes is consistent.
+ * Here, a2 = 0 will be turned int {I}a2 = 0, and all would be fine and well, only we can't change
+ * the symbol type for a2 from double, and we can't as it's not a temporary. Either we have to put 
+ * a temporary in at the late finalize stage and add another assignment, or we genericize the check
+ * in CodeGenerator#Store so we detect whether a target is of the wrong type before storing. It 
+ * is hopefully very rare, and will only be a problem when assignment results that have been
+ * specialized live on the stack
+ *
+ * @test
+ * @run
+ */
+
+function f() {
+    var a0 = a1 = a2 = 0;
+    a0 = 16.1;
+    a1 = 17.1;
+    a2 = 18.1;
+}
+f();
diff --git a/nashorn/test/script/basic/addition.js b/nashorn/test/script/basic/addition.js
new file mode 100644
index 0000000..6f8d099
--- /dev/null
+++ b/nashorn/test/script/basic/addition.js
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+/**
+ * Checks for binary addition operator.
+ *
+ * @test
+ * @run
+ */
+
+// number addition
+var x = Math.PI + Math.E;
+print(typeof(x));
+print(x);
+
+// string concatenation
+x = "hello, " + "world";
+print(typeof(x));
+print(x);
+
+// string + number
+x = "E is " + Math.E;
+print(typeof(x));
+print(x);
+
+// number + string
+x = Math.PI + " is PI";
+print(typeof(x));
+print(x);
+
+// number + undefined
+x = Math.E + undefined;
+print(typeof(x));
+print(x);
+
+x = undefined + Math.PI;
+print(typeof(x));
+print(x);
+
+// object with "valueOf" method added to number
+var obj = {
+    valueOf: function() { return 44.55; }
+};
+
+x = 45.66 + obj;
+print(typeof(x));
+print(x);
+
+x = obj + 3.14;
+print(typeof(x));
+print(x);
+
+// object with "toString" method added to number
+var obj2 = {
+    toString: function() { return "obj2.toString"; }
+};
+
+x = "hello, " + obj2;
+print(typeof(x));
+print(x);
+
+x = obj2 + " hello";
+print(typeof(x));
+print(x);
diff --git a/nashorn/test/script/basic/addition.js.EXPECTED b/nashorn/test/script/basic/addition.js.EXPECTED
new file mode 100644
index 0000000..3a91f04
--- /dev/null
+++ b/nashorn/test/script/basic/addition.js.EXPECTED
@@ -0,0 +1,20 @@
+number
+5.859874482048838
+string
+hello, world
+string
+E is 2.718281828459045
+string
+3.141592653589793 is PI
+number
+NaN
+number
+NaN
+number
+90.21
+number
+47.69
+string
+hello, obj2.toString
+string
+obj2.toString hello
diff --git a/nashorn/test/script/basic/allgettersetters.js b/nashorn/test/script/basic/allgettersetters.js
new file mode 100644
index 0000000..0f6753c
--- /dev/null
+++ b/nashorn/test/script/basic/allgettersetters.js
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+/**
+ * Exercise all setters on standard objects.
+ *
+ * @test
+ * @run
+ */
+
+function checkGetterSetter(obj, expectError) {
+    while (obj != undefined && obj != null) {
+        var properties = Object.getOwnPropertyNames(obj);
+        for (var i in properties) {
+            var prop = properties[i];
+            try {
+                obj[prop] = obj[prop];
+            } catch (e) {
+                if (!expectError || !(e instanceof TypeError)) {
+                    fail(e + ": " + obj.toString() +"." + prop, e);
+                }
+            }
+        }
+        obj = Object.getPrototypeOf(obj);
+    }
+}
+
+// objects
+checkGetterSetter([2, 23]);
+checkGetterSetter(new Boolean(true));
+checkGetterSetter(new Date(0));
+checkGetterSetter(new Error());
+checkGetterSetter(new EvalError());
+if (typeof JSAdapter != 'undefined') {
+    checkGetterSetter(new JSAdapter({}));
+}
+if (typeof JavaImporter != 'undefined') {
+    checkGetterSetter(new JavaImporter(java.io));
+}
+checkGetterSetter(function() {});
+checkGetterSetter(new Number(42));
+checkGetterSetter(new Object());
+checkGetterSetter(new RangeError());
+checkGetterSetter(new ReferenceError());
+checkGetterSetter(/nashorn/);
+checkGetterSetter(new String('hello'));
+checkGetterSetter(new SyntaxError());
+checkGetterSetter(new TypeError());
+checkGetterSetter(new URIError());
+
+// constructors and prototypes
+checkGetterSetter(Array);
+checkGetterSetter(Array.prototype);
+checkGetterSetter(Boolean);
+checkGetterSetter(Boolean.prototype);
+checkGetterSetter(Error);
+checkGetterSetter(Error.prototype);
+checkGetterSetter(EvalError);
+checkGetterSetter(EvalError.prototype);
+checkGetterSetter(Function);
+checkGetterSetter(Function.prototype);
+if (typeof JSAdapter != 'undefined') {
+    checkGetterSetter(JSAdapter);
+    checkGetterSetter(JSAdapter.prototype);
+}
+if (typeof JavaImporter != 'undefined') {
+    checkGetterSetter(JavaImporter);
+    checkGetterSetter(JavaImporter.prototype);
+}
+checkGetterSetter(Number);
+checkGetterSetter(Number.prototype);
+checkGetterSetter(Object);
+checkGetterSetter(Object.prototype);
+checkGetterSetter(RangeError);
+checkGetterSetter(RangeError.prototype);
+checkGetterSetter(ReferenceError);
+checkGetterSetter(ReferenceError.prototype);
+checkGetterSetter(RegExp);
+checkGetterSetter(RegExp.prototype);
+checkGetterSetter(String);
+checkGetterSetter(String.prototype);
+checkGetterSetter(SyntaxError);
+checkGetterSetter(SyntaxError.prototype);
+checkGetterSetter(TypeError);
+checkGetterSetter(TypeError.prototype);
+checkGetterSetter(URIError);
+checkGetterSetter(URIError.prototype);
+
+// misc. objects
+checkGetterSetter(this);
+
+if (typeof Packages != 'undefined') {
+    checkGetterSetter(Packages);
+    checkGetterSetter(java);
+    checkGetterSetter(javax);
+}
+
+if (typeof Java != 'undefined') {
+    checkGetterSetter(Java);
+    checkGetterSetter(Java.prototype);
+}
+
+if (typeof Debug != 'undefined') {
+    checkGetterSetter(Debug);
+}
+
+checkGetterSetter((function() { return arguments; })());
+// TypeError expected on certain property getter/setter for strict arguments
+checkGetterSetter((function() { 'use strict'; return arguments; })(), true);
+checkGetterSetter(JSON);
+checkGetterSetter(JSON.prototype);
+checkGetterSetter(Math);
+checkGetterSetter(Math.prototype);
diff --git a/nashorn/test/script/basic/andor.js b/nashorn/test/script/basic/andor.js
new file mode 100644
index 0000000..7d65ee1
--- /dev/null
+++ b/nashorn/test/script/basic/andor.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * and or test.
+ *
+ * @test
+ * @run 
+ */
+
+print("a" && "b");
+print(false && "b");
+print("a" || "b");
+print(false || "b");
+
diff --git a/nashorn/test/script/basic/andor.js.EXPECTED b/nashorn/test/script/basic/andor.js.EXPECTED
new file mode 100644
index 0000000..935746a
--- /dev/null
+++ b/nashorn/test/script/basic/andor.js.EXPECTED
@@ -0,0 +1,4 @@
+b
+false
+a
+b
diff --git a/nashorn/test/script/basic/anonrecur.js b/nashorn/test/script/basic/anonrecur.js
new file mode 100644
index 0000000..393a2ac
--- /dev/null
+++ b/nashorn/test/script/basic/anonrecur.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * Call anonymous function recursively using arguments.callee.
+ *
+ * @test
+ * @run
+ */
+
+print((function(x) {
+   return x == 0? 1 :  x*arguments.callee(x-1);
+})(5));
+
diff --git a/nashorn/test/script/basic/anonrecur.js.EXPECTED b/nashorn/test/script/basic/anonrecur.js.EXPECTED
new file mode 100644
index 0000000..52bd8e4
--- /dev/null
+++ b/nashorn/test/script/basic/anonrecur.js.EXPECTED
@@ -0,0 +1 @@
+120
diff --git a/nashorn/test/script/basic/applycall.js b/nashorn/test/script/basic/applycall.js
new file mode 100644
index 0000000..6756ead
--- /dev/null
+++ b/nashorn/test/script/basic/applycall.js
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/**
+ * Verify "length" property of functions is arity.
+ * Verify that function can be called by apply and call.
+ *
+ * @test
+ * @run
+ */
+
+function func(x, y) { print(x); print(y); }
+
+print(func.call);
+print("func.call.length = " + func.call.length);
+
+func.call(this, "hello, ", "world");
+func.apply(this, [ "hello, " , "world" ]);
+func("hello, ", "world");
+
+// extension: you can pass java List to apply
+
+var list = new java.util.ArrayList();
+list.add("invokedynamic");
+list.add(" is great!");
+func.apply(this, list);
+
+print("func.apply.length = " + func.apply.length);
+
+function func2() {
+    print("I am func2");
+}
+
+func2.apply(this);
+
+func.apply(this);
diff --git a/nashorn/test/script/basic/applycall.js.EXPECTED b/nashorn/test/script/basic/applycall.js.EXPECTED
new file mode 100644
index 0000000..734fa7a
--- /dev/null
+++ b/nashorn/test/script/basic/applycall.js.EXPECTED
@@ -0,0 +1,14 @@
+function call() { [native code] }
+func.call.length = 1
+hello, 
+world
+hello, 
+world
+hello, 
+world
+invokedynamic
+ is great!
+func.apply.length = 2
+I am func2
+undefined
+undefined
diff --git a/nashorn/test/script/basic/args.js b/nashorn/test/script/basic/args.js
new file mode 100644
index 0000000..7b8ff0a
--- /dev/null
+++ b/nashorn/test/script/basic/args.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * Messing with arguments.
+ *
+ * @test
+ * @run
+ */
+
+function myfunc(a, b, a) {
+  return a;
+}
+
+function myArgsfunc(arguments) {
+  return arguments[0];
+}
+
+function myArgsfunc2(args2) {
+    return arguments[0];
+}
+
+print(myfunc(10, 20, 30));
+
+print(myArgsfunc(10, 20, 30));
+
+print(myArgsfunc2(10, 20, 30));
diff --git a/nashorn/test/script/basic/args.js.EXPECTED b/nashorn/test/script/basic/args.js.EXPECTED
new file mode 100644
index 0000000..cc4938f
--- /dev/null
+++ b/nashorn/test/script/basic/args.js.EXPECTED
@@ -0,0 +1,3 @@
+30
+undefined
+10
diff --git a/nashorn/test/script/basic/arity.js b/nashorn/test/script/basic/arity.js
new file mode 100644
index 0000000..b53b298
--- /dev/null
+++ b/nashorn/test/script/basic/arity.js
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+/**
+ * arity test.
+ *
+ * @test
+ * @run 
+ */
+
+function func1(a) { print(a); }
+function func2(a, b) { print(a, b); }
+function func3(a, b, c) { print(a, b, c); }
+function func4(a, b, c, d) { print(a, b, c, d); }
+function func5(a, b, c, d, e) { print(a, b, c, d, e); }
+function func6(a, b, c, d, e, f) { print(a, b, c, d, e, f); }
+function func7(a, b, c, d, e, f, g) { print(a, b, c, d, e, f, g); }
+function func8(a, b, c, d, e, f, g, h) { print(a, b, c, d, e, f, g, h); }
+function func9(a, b, c, d, e, f, g, h, i) { print(a, b, c, d, e, f, g, h, i); }
+function func10(a, b, c, d, e, f, g, h, i, j) { print(a, b, c, d, e, f, g, h, i, j); }
+function func11(a, b, c, d, e, f, g, h, i, j, k) { print(a, b, c, d, e, f, g, h, i, j, k); }
+function func12(a, b, c, d, e, f, g, h, i, j, k, l) { print(a, b, c, d, e, f, g, h, i, j, k, l); }
+function func13(a, b, c, d, e, f, g, h, i, j, k, l, m) { print(a, b, c, d, e, f, g, h, i, j, k, l, m); }
+
+function vfunc1(a) { print(a); arguments; }
+function vfunc2(a, b) { print(a, b); arguments; }
+function vfunc3(a, b, c) { print(a, b, c); arguments; }
+function vfunc4(a, b, c, d) { print(a, b, c, d); arguments; }
+function vfunc5(a, b, c, d, e) { print(a, b, c, d, e); arguments; }
+function vfunc6(a, b, c, d, e, f) { print(a, b, c, d, e, f); arguments; }
+function vfunc7(a, b, c, d, e, f, g) { print(a, b, c, d, e, f, g); arguments; }
+function vfunc8(a, b, c, d, e, f, g, h) { print(a, b, c, d, e, f, g, h); arguments; }
+function vfunc9(a, b, c, d, e, f, g, h, i) { print(a, b, c, d, e, f, g, h, i); arguments; }
+function vfunc10(a, b, c, d, e, f, g, h, i, j) { print(a, b, c, d, e, f, g, h, i, j); arguments; }
+function vfunc11(a, b, c, d, e, f, g, h, i, j, k) { print(a, b, c, d, e, f, g, h, i, j, k); arguments; }
+function vfunc12(a, b, c, d, e, f, g, h, i, j, k, l) { print(a, b, c, d, e, f, g, h, i, j, k, l); arguments; }
+function vfunc13(a, b, c, d, e, f, g, h, i, j, k, l, m) { print(a, b, c, d, e, f, g, h, i, j, k, l, m); arguments; }
+
+func1(1);
+func2(1, 2);
+func3(1, 2, 3);
+func4(1, 2, 3, 4);
+func5(1, 2, 3, 4, 5);
+func6(1, 2, 3, 4, 5, 6);
+func7(1, 2, 3, 4, 5, 6, 7);
+func8(1, 2, 3, 4, 5, 6, 7, 8);
+func9(1, 2, 3, 4, 5, 6, 7, 8, 9);
+func10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+func11(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+func12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+func13(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+
+func1(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+func13(1);
+
+vfunc1(1);
+vfunc2(1, 2);
+vfunc3(1, 2, 3);
+vfunc4(1, 2, 3, 4);
+vfunc5(1, 2, 3, 4, 5);
+vfunc6(1, 2, 3, 4, 5, 6);
+vfunc7(1, 2, 3, 4, 5, 6, 7);
+vfunc8(1, 2, 3, 4, 5, 6, 7, 8);
+vfunc9(1, 2, 3, 4, 5, 6, 7, 8, 9);
+vfunc10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+vfunc11(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+vfunc12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+vfunc13(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+
+vfunc1(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+vfunc13(1);
diff --git a/nashorn/test/script/basic/arity.js.EXPECTED b/nashorn/test/script/basic/arity.js.EXPECTED
new file mode 100644
index 0000000..c7e00c5
--- /dev/null
+++ b/nashorn/test/script/basic/arity.js.EXPECTED
@@ -0,0 +1,30 @@
+1
+1 2
+1 2 3
+1 2 3 4
+1 2 3 4 5
+1 2 3 4 5 6
+1 2 3 4 5 6 7
+1 2 3 4 5 6 7 8
+1 2 3 4 5 6 7 8 9
+1 2 3 4 5 6 7 8 9 10
+1 2 3 4 5 6 7 8 9 10 11
+1 2 3 4 5 6 7 8 9 10 11 12
+1 2 3 4 5 6 7 8 9 10 11 12 13
+1
+1 undefined undefined undefined undefined undefined undefined undefined undefined undefined undefined undefined undefined
+1
+1 2
+1 2 3
+1 2 3 4
+1 2 3 4 5
+1 2 3 4 5 6
+1 2 3 4 5 6 7
+1 2 3 4 5 6 7 8
+1 2 3 4 5 6 7 8 9
+1 2 3 4 5 6 7 8 9 10
+1 2 3 4 5 6 7 8 9 10 11
+1 2 3 4 5 6 7 8 9 10 11 12
+1 2 3 4 5 6 7 8 9 10 11 12 13
+1
+1 undefined undefined undefined undefined undefined undefined undefined undefined undefined undefined undefined undefined
diff --git a/nashorn/test/script/basic/arrayprotoclass.js b/nashorn/test/script/basic/arrayprotoclass.js
new file mode 100644
index 0000000..f5993c0
--- /dev/null
+++ b/nashorn/test/script/basic/arrayprotoclass.js
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check Array.prototype class name.
+ *
+ * @test
+ * @run
+ */
+
+Array.prototype.getClass = Object.prototype.toString;
+print(Array.prototype.getClass()); // print [object Array]
diff --git a/nashorn/test/script/basic/arrayprotoclass.js.EXPECTED b/nashorn/test/script/basic/arrayprotoclass.js.EXPECTED
new file mode 100644
index 0000000..711d714
--- /dev/null
+++ b/nashorn/test/script/basic/arrayprotoclass.js.EXPECTED
@@ -0,0 +1 @@
+[object Array]
diff --git a/nashorn/test/script/basic/arrays.js b/nashorn/test/script/basic/arrays.js
new file mode 100644
index 0000000..6cab375
--- /dev/null
+++ b/nashorn/test/script/basic/arrays.js
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic Array tests.
+ *
+ * @test
+ * @run
+ */
+
+var arr = new Array(3);
+print(arr.length);
+
+print("isArray.length = " + Array.isArray.length);
+print(Array.isArray(44));
+print(Array.isArray([44]));
+
+function even(num) {
+    return (num % 2) == 0;
+}
+
+print("join.length = " + Array.prototype.join.length);
+print(["javascript", "is", "great"].join("<->"));
+
+var arr = [4, 56, 5];
+print("every.length = " + Array.prototype.every.length);
+print(arr.toString() + " every even? = " + arr.every(even));
+arr = [4, 56, 688];
+print(arr.toString() + " every even? = " + arr.every(even));
+
+print("some.length = " + Array.prototype.some.length);
+arr = [4, 56, 5];
+print(arr.toString() + " some even? = " + arr.some(even));
+arr = [3, 5, 17];
+print(arr.toString() + " some even? = " + arr.some(even));
+
+print("forEach.length = " + Array.prototype.forEach.length);
+arr = [ "java", "javascript", "jython", "jruby"];
+arr.forEach(function(val, idx, obj) {
+    print(obj.toString() + "[" + idx + "] is " + val);
+});
+
+print(arr.map(function(val) { return val.toUpperCase(); }));
+print("shifted is " + arr.shift() + ", remaining is " + arr.toString() + ", length is " + arr.length);
+
+arr = [ "c++", "java", "javascript", "objective c" ];
+print(arr.filter(function(val) { return val.charAt(0) == 'j'; }));
+
+print([3, 66, 2, 44].reduce(function (acc, e) { return acc + e; }));
+print([1, 2, 3, 4, 5].reduce(function (acc, e) { return acc * e; }));
+
+print(arr.reduce(
+    function(acc, e) { return acc + " " + e; }
+));
+
+print(["javascript", "from", "world", "hello"].reduceRight(
+    function(acc, x) { return acc + " " + x; }
+));
+
+var langs = ["java", "javascript", "jython", "jruby", "c"];
+print("indexOf.length = " + Array.prototype.indexOf.length);
+print("indexOf('java') = " + langs.indexOf("java"));
+print("indexOf('javascript') = " + langs.indexOf("javascript"));
+print("indexOf('javascript', 3) = " + langs.indexOf("javascript", 3));
+print("indexOf('c++') = " + langs.indexOf("c++"));
+print("[].indexOf('any') = " + [].indexOf("any"));
+
+langs = ["java", "javascript", "jython", "jruby", "java", "jython", "c"];
+print("lastIndexOf.length = " + Array.prototype.lastIndexOf.length);
+print("lastIndexOf('java') = " + langs.lastIndexOf("java"));
+print("lastIndexOf('jython') = " + langs.lastIndexOf("jython"));
+print("lastIndexOf('c') = " + langs.lastIndexOf("c"));
+print("lastIndexOf('c++') = " + langs.lastIndexOf("c++"));
+print("[].lastIndexOf('any') = " + [].lastIndexOf("any"));
+
+print("concat.length = " + Array.prototype.concat.length);
+print(["foo", "bar"].concat(["x", "y"], 34, "sss", [3, 4, 2]));
+
+
+// Check various array length arguments to constructor
+
+function expectRangeError(length) {
+    try {
+        var arr = new Array(length);
+        print("range error expected for " + length);
+    } catch (e) {
+        if (! (e instanceof RangeError)) {
+            print("range error expected for " + length);
+        }
+    }
+}
+
+expectRangeError(NaN);
+expectRangeError(Infinity);
+expectRangeError(-Infinity);
+expectRangeError(-10);
+
+var arr = new Array("10");
+if (arr.length != 1 && arr[0] != '10') {
+    throw new Error("expected length 1 array");
+}
+
+arr = new Array(new Number(34));
+if (arr.length != 1 && arr[0] != new Number(34)) {
+    throw new Error("expected length 1 array");
+}
+
+arr = new Array(15);
+if (arr.length != 15) {
+    throw new Error("expected length 15 array");
+}
+
+print("Array.length = " + Array.length);
+
+print([NaN,NaN,NaN]);
+
+// check setting array's length
+arr = [3,2,1];
+arr.length = 1;
+print(arr);
+print(arr.length);
+
+// test typeof array
+var numberArray = [];
+numberArray[0] = 1;
+print(typeof numberArray[0]);
+
+print(numberArray.toLocaleString());
+
+// Array functions on non-array objects
+
+print(Array.prototype.join.call(new java.lang.Object()));
+print(Array.prototype.concat.call("hello", "world"));
+print(Array.prototype.map.call("hello", function() {}));
+print(Array.prototype.reduce.call("hello", function() {}));
+print(Array.prototype.toString.call(new java.lang.Object()));
+print(Array.prototype.toLocaleString.call(new java.lang.Object()));
+print(Array.prototype.reduceRight.call(new java.lang.Object(), 
+      function() {}, 33));
+
diff --git a/nashorn/test/script/basic/arrays.js.EXPECTED b/nashorn/test/script/basic/arrays.js.EXPECTED
new file mode 100644
index 0000000..6c783bd
--- /dev/null
+++ b/nashorn/test/script/basic/arrays.js.EXPECTED
@@ -0,0 +1,51 @@
+3
+isArray.length = 1
+false
+true
+join.length = 1
+javascript<->is<->great
+every.length = 1
+4,56,5 every even? = false
+4,56,688 every even? = true
+some.length = 1
+4,56,5 some even? = true
+3,5,17 some even? = false
+forEach.length = 1
+java,javascript,jython,jruby[0] is java
+java,javascript,jython,jruby[1] is javascript
+java,javascript,jython,jruby[2] is jython
+java,javascript,jython,jruby[3] is jruby
+JAVA,JAVASCRIPT,JYTHON,JRUBY
+shifted is java, remaining is javascript,jython,jruby, length is 3
+java,javascript
+115
+120
+c++ java javascript objective c
+hello world from javascript
+indexOf.length = 1
+indexOf('java') = 0
+indexOf('javascript') = 1
+indexOf('javascript', 3) = -1
+indexOf('c++') = -1
+[].indexOf('any') = -1
+lastIndexOf.length = 1
+lastIndexOf('java') = 4
+lastIndexOf('jython') = 5
+lastIndexOf('c') = 6
+lastIndexOf('c++') = -1
+[].lastIndexOf('any') = -1
+concat.length = 1
+foo,bar,x,y,34,sss,3,4,2
+Array.length = 1
+NaN,NaN,NaN
+3
+1
+number
+1
+
+hello,world
+,,,,
+undefined
+[object java.lang.Object]
+
+33
diff --git a/nashorn/test/script/basic/arrays2.js b/nashorn/test/script/basic/arrays2.js
new file mode 100644
index 0000000..1342c17
--- /dev/null
+++ b/nashorn/test/script/basic/arrays2.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic Array tests.
+ *
+ * @test
+ * @run
+ */
+
+print("Array.prototype.length = " + Array.prototype.length);
+print("Array.prototype.slice.prototype = " + Array.prototype.slice.prototype);
+try {
+    throw new Array.prototype.slice();
+} catch (e) {
+    print(e instanceof TypeError);
+}
+
+var x = [];
+x[true] = 1;
+print(x["true"]);
+
+x = [];
+x[NaN] = 1;
+print(x["NaN"]);
+
+x = [];
+x["0"] = 0;
+print(x[0]);
+
+x = [];
+x[true] = 1;
+print(x["true"]);
diff --git a/nashorn/test/script/basic/arrays2.js.EXPECTED b/nashorn/test/script/basic/arrays2.js.EXPECTED
new file mode 100644
index 0000000..d8da598
--- /dev/null
+++ b/nashorn/test/script/basic/arrays2.js.EXPECTED
@@ -0,0 +1,7 @@
+Array.prototype.length = 0
+Array.prototype.slice.prototype = undefined
+true
+1
+1
+0
+1
diff --git a/nashorn/test/script/basic/arraysIntKey.js b/nashorn/test/script/basic/arraysIntKey.js
new file mode 100644
index 0000000..c9182ef
--- /dev/null
+++ b/nashorn/test/script/basic/arraysIntKey.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Checks that we override array entries with defineProperty.
+ *
+ * @test
+ * @run
+ */
+ 
+var o = [0];
+Object.defineProperty(o, "0", { get: function() { return "zero"; }, set: function(v) { print(v); }, configurable: true });
+
+print(o[0]);
+o[0] = "one";
diff --git a/nashorn/test/script/basic/arraysIntKey.js.EXPECTED b/nashorn/test/script/basic/arraysIntKey.js.EXPECTED
new file mode 100644
index 0000000..2edebd4
--- /dev/null
+++ b/nashorn/test/script/basic/arraysIntKey.js.EXPECTED
@@ -0,0 +1,2 @@
+zero
+one
diff --git a/nashorn/test/script/basic/arrayset.js b/nashorn/test/script/basic/arrayset.js
new file mode 100644
index 0000000..2fbd2bc
--- /dev/null
+++ b/nashorn/test/script/basic/arrayset.js
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Tests setting an array element
+ *
+ * @test
+ * @run
+ */
+
+var arr = []; 
+print(arr.length);
+print(arr.hasOwnProperty(10000));
+print(arr.hasOwnProperty(10));
+arr[10000] = 13;
+print(arr.length);
+print(arr.hasOwnProperty(10000));
+print(arr.hasOwnProperty(10));
+
diff --git a/nashorn/test/script/basic/arrayset.js.EXPECTED b/nashorn/test/script/basic/arrayset.js.EXPECTED
new file mode 100644
index 0000000..75e9e23
--- /dev/null
+++ b/nashorn/test/script/basic/arrayset.js.EXPECTED
@@ -0,0 +1,6 @@
+0
+false
+false
+10001
+true
+false
diff --git a/nashorn/test/script/basic/arrayundefined.js b/nashorn/test/script/basic/arrayundefined.js
new file mode 100644
index 0000000..3866c85
--- /dev/null
+++ b/nashorn/test/script/basic/arrayundefined.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Undefined elements of (numeric) array should be "undefined".
+ *
+ * @test
+ * @run
+ */
+
+var x = [0];
+x.length = 4;
+print(x[0]);
+print(x[1]);
+print(x[2]);
+print(x[3]);
diff --git a/nashorn/test/script/basic/arrayundefined.js.EXPECTED b/nashorn/test/script/basic/arrayundefined.js.EXPECTED
new file mode 100644
index 0000000..e03b226
--- /dev/null
+++ b/nashorn/test/script/basic/arrayundefined.js.EXPECTED
@@ -0,0 +1,4 @@
+0
+undefined
+undefined
+undefined
diff --git a/nashorn/test/script/basic/assign.js b/nashorn/test/script/basic/assign.js
new file mode 100644
index 0000000..abcc504
--- /dev/null
+++ b/nashorn/test/script/basic/assign.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Assign test.
+ *
+ * @test
+ * @run 
+ */
+
+var x = 10;
+print(x += 10);
+print(x -= 5);
+print(x *= 100);
+print(x /= 10);
+print(x %= 7);
+
+var b = 0xff;
+print(b &= 0xf);
+print(b |= 0xf0);
+print(b ^= 0xf);
+print(b <<= 24);
+print(b >>= 24);
+print(b >>>= 16);
+
+var a = [1, 2, 3, 4, 5];
+print(a[2 + a[0]] += 10);
+
+var o = {a:10, b:20};
+print(o.a += 10);
diff --git a/nashorn/test/script/basic/assign.js.EXPECTED b/nashorn/test/script/basic/assign.js.EXPECTED
new file mode 100644
index 0000000..027a300
--- /dev/null
+++ b/nashorn/test/script/basic/assign.js.EXPECTED
@@ -0,0 +1,13 @@
+20
+15
+1500
+150
+3
+15
+255
+240
+-268435456
+-16
+65535
+14
+20
diff --git a/nashorn/test/script/basic/assign_builtin_func_props.js b/nashorn/test/script/basic/assign_builtin_func_props.js
new file mode 100644
index 0000000..faf297d
--- /dev/null
+++ b/nashorn/test/script/basic/assign_builtin_func_props.js
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * Check that we can assign to all properties from builtin functions and their
+ * prototypes. This is to make sure all such properties are writable.
+ *
+ * @test
+ * @run
+ */
+
+(function() {
+    var PropNamesGetter = Object.getOwnPropertyNames;
+    var ObjectType = Object;
+
+    function assignAll(obj) {
+        if (! (obj instanceof ObjectType)) {
+            return;
+        }
+        var props = PropNamesGetter(obj);
+        for (var p in props) {
+            var value = obj[props[p]];
+            obj[props[p]] = value;
+        }
+    }
+
+    var globalProps = PropNamesGetter(this);
+    for (var i in globalProps) {
+        var prop = globalProps[i];
+        if (typeof this[prop] == 'function') {
+            assignAll(this[prop].prototype);
+            assignAll(this[prop]);
+        }
+    }
+})();
diff --git a/nashorn/test/script/basic/bitwise_and.js b/nashorn/test/script/basic/bitwise_and.js
new file mode 100644
index 0000000..32583d4
--- /dev/null
+++ b/nashorn/test/script/basic/bitwise_and.js
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check bitwise AND on various (hex) int values.
+ *
+ * @test
+ * @run
+ */
+
+print(0x00000000 & 0xffffffff);
+print(0x11111111 & 0xffffffff);
+print(0x22222222 & 0xffffffff);
+print(0x33333333 & 0xffffffff);
+print(0x44444444 & 0xffffffff);
+print(0x55555555 & 0xffffffff);
+print(0x66666666 & 0xffffffff);
+print(0x77777777 & 0xffffffff);
+print(0x88888888 & 0xffffffff);
+print(0x99999999 & 0xffffffff);
+print(0xaaaaaaaa & 0xffffffff);
+print(0xbbbbbbbb & 0xffffffff);
+print(0xcccccccc & 0xffffffff);
+print(0xdddddddd & 0xffffffff);
+print(0xeeeeeeee & 0xffffffff);
+print(0xffffffff & 0xffffffff);
+
+// try non-literal value as well
+var a = 0xffffff00;
+print(a);
+print(a & 0xff); // expected 0
diff --git a/nashorn/test/script/basic/bitwise_and.js.EXPECTED b/nashorn/test/script/basic/bitwise_and.js.EXPECTED
new file mode 100644
index 0000000..539196a
--- /dev/null
+++ b/nashorn/test/script/basic/bitwise_and.js.EXPECTED
@@ -0,0 +1,18 @@
+0
+286331153
+572662306
+858993459
+1145324612
+1431655765
+1717986918
+2004318071
+-2004318072
+-1717986919
+-1431655766
+-1145324613
+-858993460
+-572662307
+-286331154
+-1
+4294967040
+0
diff --git a/nashorn/test/script/basic/booleangetter.js b/nashorn/test/script/basic/booleangetter.js
new file mode 100644
index 0000000..3f16b74
--- /dev/null
+++ b/nashorn/test/script/basic/booleangetter.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * booleangetter : Make sure that the not gives us the correct object type
+ *
+ * @test
+ * @run
+ */
+
+function f() {
+    print('hello');
+}
+
+function g() {
+    var x = f;
+    var obj = {};
+    var key = 'field';
+    obj[key] = x;
+    print(!obj[key]);
+}
+
+g();
diff --git a/nashorn/test/script/basic/booleangetter.js.EXPECTED b/nashorn/test/script/basic/booleangetter.js.EXPECTED
new file mode 100644
index 0000000..c508d53
--- /dev/null
+++ b/nashorn/test/script/basic/booleangetter.js.EXPECTED
@@ -0,0 +1 @@
+false
diff --git a/nashorn/test/script/basic/builtin.js b/nashorn/test/script/basic/builtin.js
new file mode 100644
index 0000000..4d48bff
--- /dev/null
+++ b/nashorn/test/script/basic/builtin.js
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+/**
+ * Make sure that the builtin functions compile in all varieties and not crash
+ * or generate invalid bytecode
+ *
+ * @test
+ * @run
+ */
+
+function t1() {
+    var a = new Array();
+}
+
+function t2() {
+    var a = new Array(60);
+}
+
+function t3() {
+    eval("18 + 29");
+}
+
+function t4() {
+    var r = new RegExp();
+}
+
+function t5(p) {
+    var r = new RegExp(p);
+}
+
+function t6(p,m) {
+    var r = new RegExp(p,m);
+}
+
+function t7() {
+    var r = new RegExp("pattern");
+}
+
+function t8() {
+    var r = new RegExp("pattern", "gm");
+}
+
+t1();
+t2();
+t3();
+t4();
+t5();
+t6();
+t7();
+t8();
+
+print("done");
diff --git a/nashorn/test/script/basic/builtin.js.EXPECTED b/nashorn/test/script/basic/builtin.js.EXPECTED
new file mode 100644
index 0000000..19f86f4
--- /dev/null
+++ b/nashorn/test/script/basic/builtin.js.EXPECTED
@@ -0,0 +1 @@
+done
diff --git a/nashorn/test/script/basic/builtin_assign.js b/nashorn/test/script/basic/builtin_assign.js
new file mode 100644
index 0000000..7520cb7
--- /dev/null
+++ b/nashorn/test/script/basic/builtin_assign.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Verify that we can assign any value to (initially) function typed builtin properties.
+ *
+ * @test
+ * @run
+ */
+
+print(typeof(Math.sin));
+Math.sin(Math.PI);
+Math.sin = 4;
+print(typeof(Math.sin));
+print(Math.sin);
+
diff --git a/nashorn/test/script/basic/builtin_assign.js.EXPECTED b/nashorn/test/script/basic/builtin_assign.js.EXPECTED
new file mode 100644
index 0000000..51fb94a
--- /dev/null
+++ b/nashorn/test/script/basic/builtin_assign.js.EXPECTED
@@ -0,0 +1,3 @@
+function
+number
+4
diff --git a/nashorn/test/script/basic/builtinchain.js b/nashorn/test/script/basic/builtinchain.js
new file mode 100644
index 0000000..a5e672e
--- /dev/null
+++ b/nashorn/test/script/basic/builtinchain.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check important prototype chain properties of Function and Object.
+ *
+ * @test
+ * @run
+ */
+
+print(typeof(Object) == 'function');
+print(typeof(Object.prototype) == 'object');
+print(typeof(Function) == 'function');
+// Function's prototype is a function!
+print(typeof(Function.prototype) == 'function');
+
+print(Function.constructor === Function);
+print(Function.prototype === Object.getPrototypeOf(Function));
+print(Object.getPrototypeOf(Function.prototype) === Object.prototype);
+
+print(Object.constructor === Function);
+print(Object.getPrototypeOf(Object.prototype) === null);
+print(Object.getPrototypeOf(Object) === Function.prototype);
+
+// check one function from Function.prototype
+var applyFunc = Function.prototype.apply;
+print(applyFunc.constructor === Function);
+print(Object.getPrototypeOf(applyFunc) === Function.prototype);
+print(applyFunc.prototype === undefined);
+
+// check one function from Object.prototype
+var toStringFunc = Object.prototype.toString;
+print(toStringFunc.constructor === Function);
+print(Object.getPrototypeOf(toStringFunc) === Function.prototype);
+print(toStringFunc.prototype === undefined);
diff --git a/nashorn/test/script/basic/builtinchain.js.EXPECTED b/nashorn/test/script/basic/builtinchain.js.EXPECTED
new file mode 100644
index 0000000..9f79e86
--- /dev/null
+++ b/nashorn/test/script/basic/builtinchain.js.EXPECTED
@@ -0,0 +1,16 @@
+true
+true
+true
+true
+true
+true
+true
+true
+true
+true
+true
+true
+true
+true
+true
+true
diff --git a/nashorn/test/script/basic/calllink.js b/nashorn/test/script/basic/calllink.js
new file mode 100644
index 0000000..06e546c
--- /dev/null
+++ b/nashorn/test/script/basic/calllink.js
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/*
+ * Make sure that basic object method call re-linking works properly.
+ *
+ * @test
+ * @run
+ */
+
+var obj1 = {
+   func: function() { print("obj1.func called"); }
+};
+
+var obj2 = {
+   func: function() { print("obj2.func called"); }
+};
+
+var obj3 = {
+   __noSuchMethod__: function(name) {
+       print("no such method: " + name);
+   }
+};
+
+
+// have 'func' on prototype
+var obj4 = Object.create({
+    func: function() {
+        print("obj4's prototype func called");
+    }
+});
+
+function MyConstructor() {
+}
+
+MyConstructor.prototype.func = function() {
+    print("MyConstructor.prototype.func");
+}
+
+var obj5 = new MyConstructor();
+var obj6 = new MyConstructor();
+
+var arr = [ obj1, obj2, obj3, obj4, obj5, obj6, 
+            obj1, obj2, obj3, obj4, obj5, obj6 ];
+
+var myObj;
+for (i in arr) {
+    if (i == 8) {
+        obj3.func = function() {
+            print("new obj3.func called");
+        }
+        obj4.func = function() { 
+            print("new obj4.func called"); 
+        }
+        MyConstructor.prototype.func = function() {
+            print("all new MyConstructor.prototype.func");
+        }
+    }
+    myObj = arr[i];
+    myObj.func();
+}
diff --git a/nashorn/test/script/basic/calllink.js.EXPECTED b/nashorn/test/script/basic/calllink.js.EXPECTED
new file mode 100644
index 0000000..f83b0a1
--- /dev/null
+++ b/nashorn/test/script/basic/calllink.js.EXPECTED
@@ -0,0 +1,12 @@
+obj1.func called
+obj2.func called
+no such method: func
+obj4's prototype func called
+MyConstructor.prototype.func
+MyConstructor.prototype.func
+obj1.func called
+obj2.func called
+new obj3.func called
+new obj4.func called
+all new MyConstructor.prototype.func
+all new MyConstructor.prototype.func
diff --git a/nashorn/test/script/basic/closure.js b/nashorn/test/script/basic/closure.js
new file mode 100644
index 0000000..f601375
--- /dev/null
+++ b/nashorn/test/script/basic/closure.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Closure test.
+ *
+ * @test
+ * @run 
+ */
+ 
+(function test1(a, b){ print(a, b); })(10, 20);
+(function test2(a, b){ print(a, b); })(10);
+(function test3(a, b){ print(a, b); })(10, 20, 30);
+(function test4(a, b){ 
+    print(arguments[0] + "," + arguments[1]); 
+    print(arguments.callee);
+})(10, 20);
+
diff --git a/nashorn/test/script/basic/closure.js.EXPECTED b/nashorn/test/script/basic/closure.js.EXPECTED
new file mode 100644
index 0000000..d039115
--- /dev/null
+++ b/nashorn/test/script/basic/closure.js.EXPECTED
@@ -0,0 +1,8 @@
+10 20
+10 undefined
+10 20
+10,20
+function test4(a, b){ 
+    print(arguments[0] + "," + arguments[1]); 
+    print(arguments.callee);
+}
diff --git a/nashorn/test/script/basic/commandargs.js b/nashorn/test/script/basic/commandargs.js
new file mode 100644
index 0000000..733b679
--- /dev/null
+++ b/nashorn/test/script/basic/commandargs.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Simple test to check command line arguments for scripts.
+ *
+ * @test
+ * @argument hello 
+ * @argument world
+ * @run
+ */
+
+for (i in arguments) {
+    print(arguments[i]);
+}
+ 
diff --git a/nashorn/test/script/basic/commandargs.js.EXPECTED b/nashorn/test/script/basic/commandargs.js.EXPECTED
new file mode 100644
index 0000000..94954ab
--- /dev/null
+++ b/nashorn/test/script/basic/commandargs.js.EXPECTED
@@ -0,0 +1,2 @@
+hello
+world
diff --git a/nashorn/test/script/basic/compile-octane.js b/nashorn/test/script/basic/compile-octane.js
new file mode 100644
index 0000000..da40d5e
--- /dev/null
+++ b/nashorn/test/script/basic/compile-octane.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * @test
+ * @runif external.octane
+ */ 
+
+compile_only = true;
+load(__DIR__ + 'run-octane.js');
diff --git a/nashorn/test/script/basic/compile-octane.js.EXPECTED b/nashorn/test/script/basic/compile-octane.js.EXPECTED
new file mode 100644
index 0000000..dab419e
--- /dev/null
+++ b/nashorn/test/script/basic/compile-octane.js.EXPECTED
@@ -0,0 +1,36 @@
+Compiling... box2d.js
+Compiled OK: box2d.js
+
+Compiling... code-load.js
+Compiled OK: code-load.js
+
+Compiling... crypto.js
+Compiled OK: crypto.js
+
+Compiling... deltablue.js
+Compiled OK: deltablue.js
+
+Compiling... earley-boyer.js
+Compiled OK: earley-boyer.js
+
+Compiling... gbemu.js
+Compiled OK: gbemu.js
+
+Compiling... navier-stokes.js
+Compiled OK: navier-stokes.js
+
+Compiling... pdfjs.js
+Compiled OK: pdfjs.js
+
+Compiling... raytrace.js
+Compiled OK: raytrace.js
+
+Compiling... regexp.js
+Compiled OK: regexp.js
+
+Compiling... richards.js
+Compiled OK: richards.js
+
+Compiling... splay.js
+Compiled OK: splay.js
+
diff --git a/nashorn/test/script/basic/condassign.js b/nashorn/test/script/basic/condassign.js
new file mode 100644
index 0000000..a70f5a4
--- /dev/null
+++ b/nashorn/test/script/basic/condassign.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Used to result in error: "Expected : but found =".
+ * Assignment should be allowed in conditional expression arms.
+ *
+ * @test
+ * @run
+ */
+
+var x = 3;
+var y = x ? x = 55 : 5465;
+print(y);
+var y = x ? 6 : x += 3;
+print(x);
diff --git a/nashorn/test/script/basic/condassign.js.EXPECTED b/nashorn/test/script/basic/condassign.js.EXPECTED
new file mode 100644
index 0000000..7a165da
--- /dev/null
+++ b/nashorn/test/script/basic/condassign.js.EXPECTED
@@ -0,0 +1,2 @@
+55
+55
diff --git a/nashorn/test/script/basic/consstring.js b/nashorn/test/script/basic/consstring.js
new file mode 100644
index 0000000..b8dc51d
--- /dev/null
+++ b/nashorn/test/script/basic/consstring.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Conversion of ConsString to String
+ *
+ * @test
+ * @run
+ */
+
+var list = new java.util.ArrayList();
+var str = "foo";
+
+list.add(str);                               // plain string
+list.add(String(str + "1"));                 // String() called as function
+list.add(String(new String(str + "2")));     // String() called as function with String object
+list.add((str + "3").toString());            // toString() called on primitive string
+list.add(new String(str + "4").toString());  // toString() called on String object
+
+Packages.jdk.nashorn.internal.test.models.StringArgs.checkString(list);
diff --git a/nashorn/test/script/basic/construct.js b/nashorn/test/script/basic/construct.js
new file mode 100644
index 0000000..66e3d41
--- /dev/null
+++ b/nashorn/test/script/basic/construct.js
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * Constructor test.
+ *
+ * @test
+ * @run 
+ */
+
+function Test() {
+    this.A = "A big fat string";
+    this.B = 123;
+    
+    this.F = function(x) { return x; }
+   
+    var proto = Object.getPrototypeOf(this); 
+    proto.R = "A big fat string";
+    proto.S = 123;
+    
+    proto.T = function(x) { return x; }
+
+    return "monkey";
+}
+
+Test.prototype.G = "proto";
+
+var t = new Test();
+
+print(t);
+print(t.A);
+print(t.B);
+print(t.F);
+print(t.G);
+print(t.R);
+print(t.S);
+print(t.T);
+
+for (i in t) print(i, t[i]);
diff --git a/nashorn/test/script/basic/construct.js.EXPECTED b/nashorn/test/script/basic/construct.js.EXPECTED
new file mode 100644
index 0000000..4c422cb
--- /dev/null
+++ b/nashorn/test/script/basic/construct.js.EXPECTED
@@ -0,0 +1,15 @@
+[object Object]
+A big fat string
+123
+function(x) { return x; }
+proto
+A big fat string
+123
+function(x) { return x; }
+A A big fat string
+B 123
+F function(x) { return x; }
+G proto
+R A big fat string
+S 123
+T function(x) { return x; }
diff --git a/nashorn/test/script/basic/constructorname.js b/nashorn/test/script/basic/constructorname.js
new file mode 100644
index 0000000..16e3aec
--- /dev/null
+++ b/nashorn/test/script/basic/constructorname.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check obj.constructor property for user-defined constructor as well
+ * as built-in constructors.
+ *
+ * @test
+ * @run
+ */
+
+function MyConstructor() {}
+var myObj = new MyConstructor();
+print(myObj.constructor.name);
+
+myObj = {};
+print(myObj.constructor.name);
+
+myObj = new Boolean(true);
+print(myObj.constructor.name);
+
+myObj = new Number(3);
+print(myObj.constructor.name);
+
+myObj = new String("hello");
+print(myObj.constructor.name);
+
+myObj = new Array();
+print(myObj.constructor.name);
+
+myObj = /javascript/;
+print(myObj.constructor.name);
diff --git a/nashorn/test/script/basic/constructorname.js.EXPECTED b/nashorn/test/script/basic/constructorname.js.EXPECTED
new file mode 100644
index 0000000..2ca6607
--- /dev/null
+++ b/nashorn/test/script/basic/constructorname.js.EXPECTED
@@ -0,0 +1,7 @@
+MyConstructor
+Object
+Boolean
+Number
+String
+Array
+RegExp
diff --git a/nashorn/test/script/basic/date.js b/nashorn/test/script/basic/date.js
new file mode 100644
index 0000000..ea77089
--- /dev/null
+++ b/nashorn/test/script/basic/date.js
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic checks for Date constructor.
+ * FIXME: add more checks
+ *
+ * @test
+ * @option -timezone=Asia/Calcutta
+ * @run
+ */
+
+// check arity of tricky functions
+print("Date.length = " + Date.length);
+print("Date.UTC.length = " + Date.UTC.length);
+print("Date.prototype.setSeconds.length = " + Date.prototype.setSeconds.length);
+print("Date.prototype.setUTCSeconds.length = " + Date.prototype.setUTCSeconds.length);
+print("Date.prototype.setMinutes.length = " + Date.prototype.setMinutes.length);
+print("Date.prototype.setUTCMinutes.length = " + Date.prototype.setUTCMinutes.length);
+print("Date.prototype.setHours.length = " + Date.prototype.setHours.length);
+print("Date.prototype.setUTCHours.length = " + Date.prototype.setUTCHours.length);
+print("Date.prototype.setMonth.length = " + Date.prototype.setMonth.length);
+print("Date.prototype.setUTCMonth.length = " + Date.prototype.setUTCMonth.length);
+print("Date.prototype.setFullYear.length = " + Date.prototype.setFullYear.length);
+print("Date.prototype.setUTCFullYear.length = " + Date.prototype.setUTCFullYear.length);
+
+function printDate(d) {
+    print(d.getMinutes());
+    print(d.getSeconds());
+    print(d.getMilliseconds());
+    print(d.getUTCDate());
+    print(d.getUTCDay());
+    print(d.getUTCMonth());
+    print(d.getUTCFullYear());
+    print(d.getUTCHours());
+    print(d.getUTCMinutes());
+    print(d.getUTCSeconds());
+    print(d.getUTCMilliseconds());
+    print(d.toISOString());
+    print(d.toUTCString());
+    print(d.toString());
+    print(d.toLocaleString());
+    print(d.toLocaleDateString());
+    print(d.toLocaleTimeString());
+    print(d.toDateString());
+    print(d.toTimeString());
+    print(d.toJSON());
+}
+
+var d = new Date(2011, 4, 3, 17, 1, 1, 0);
+printDate(d);
+
+d.setUTCMinutes(40, 34);
+printDate(d);
+
+d = new Date(Date.UTC(2000, 10, 1, 1, 1, 1, 1));
+printDate(d);
+
+d = new Date(0);
+d.setFullYear(2012);
+d.setMonth(1);
+d.setDate(2);
+d.setHours(3);
+d.setMinutes(3);
+d.setSeconds(4);
+d.setMilliseconds(5);
+printDate(d);
+
+d = new Date(0);
+d.setUTCFullYear(2012);
+d.setUTCMonth(1);
+d.setUTCDate(2);
+d.setUTCHours(3);
+d.setUTCMinutes(4);
+d.setUTCSeconds(5);
+d.setUTCMilliseconds(6);
+printDate(d);
+
+d = new Date(0);
+d.setTime(1000);
+printDate(d);
diff --git a/nashorn/test/script/basic/date.js.EXPECTED b/nashorn/test/script/basic/date.js.EXPECTED
new file mode 100644
index 0000000..ddcff06
--- /dev/null
+++ b/nashorn/test/script/basic/date.js.EXPECTED
@@ -0,0 +1,132 @@
+Date.length = 7
+Date.UTC.length = 7
+Date.prototype.setSeconds.length = 2
+Date.prototype.setUTCSeconds.length = 2
+Date.prototype.setMinutes.length = 3
+Date.prototype.setUTCMinutes.length = 3
+Date.prototype.setHours.length = 4
+Date.prototype.setUTCHours.length = 4
+Date.prototype.setMonth.length = 2
+Date.prototype.setUTCMonth.length = 2
+Date.prototype.setFullYear.length = 3
+Date.prototype.setUTCFullYear.length = 3
+1
+1
+0
+3
+2
+4
+2011
+11
+31
+1
+0
+2011-05-03T11:31:01.000Z
+Tue, 03 May 2011 11:31:01 GMT
+Tue May 03 2011 17:01:01 GMT+0530 (IST)
+Tue May 03 2011 17:01:01 GMT+0530 (IST)
+2011-05-03
+17:01:01
+Tue May 03 2011
+17:01:01 GMT+0530 (IST)
+2011-05-03T11:31:01.000Z
+10
+34
+0
+3
+2
+4
+2011
+11
+40
+34
+0
+2011-05-03T11:40:34.000Z
+Tue, 03 May 2011 11:40:34 GMT
+Tue May 03 2011 17:10:34 GMT+0530 (IST)
+Tue May 03 2011 17:10:34 GMT+0530 (IST)
+2011-05-03
+17:10:34
+Tue May 03 2011
+17:10:34 GMT+0530 (IST)
+2011-05-03T11:40:34.000Z
+31
+1
+1
+1
+3
+10
+2000
+1
+1
+1
+1
+2000-11-01T01:01:01.001Z
+Wed, 01 Nov 2000 01:01:01 GMT
+Wed Nov 01 2000 06:31:01 GMT+0530 (IST)
+Wed Nov 01 2000 06:31:01 GMT+0530 (IST)
+2000-11-01
+06:31:01
+Wed Nov 01 2000
+06:31:01 GMT+0530 (IST)
+2000-11-01T01:01:01.001Z
+3
+4
+5
+1
+3
+1
+2012
+21
+33
+4
+5
+2012-02-01T21:33:04.005Z
+Wed, 01 Feb 2012 21:33:04 GMT
+Thu Feb 02 2012 03:03:04 GMT+0530 (IST)
+Thu Feb 02 2012 03:03:04 GMT+0530 (IST)
+2012-02-02
+03:03:04
+Thu Feb 02 2012
+03:03:04 GMT+0530 (IST)
+2012-02-01T21:33:04.005Z
+34
+5
+6
+2
+4
+1
+2012
+3
+4
+5
+6
+2012-02-02T03:04:05.006Z
+Thu, 02 Feb 2012 03:04:05 GMT
+Thu Feb 02 2012 08:34:05 GMT+0530 (IST)
+Thu Feb 02 2012 08:34:05 GMT+0530 (IST)
+2012-02-02
+08:34:05
+Thu Feb 02 2012
+08:34:05 GMT+0530 (IST)
+2012-02-02T03:04:05.006Z
+30
+1
+0
+1
+4
+0
+1970
+0
+0
+1
+0
+1970-01-01T00:00:01.000Z
+Thu, 01 Jan 1970 00:00:01 GMT
+Thu Jan 01 1970 05:30:01 GMT+0530 (IST)
+Thu Jan 01 1970 05:30:01 GMT+0530 (IST)
+1970-01-01
+05:30:01
+Thu Jan 01 1970
+05:30:01 GMT+0530 (IST)
+1970-01-01T00:00:01.000Z
diff --git a/nashorn/test/script/basic/dateparse.js b/nashorn/test/script/basic/dateparse.js
new file mode 100644
index 0000000..919a681
--- /dev/null
+++ b/nashorn/test/script/basic/dateparse.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic checks for Date.parse function.
+ *
+ * @test
+ * @option -timezone=Asia/Calcutta
+ * @run
+ */
+
+// ISO format
+var d = new Date(Date.parse("1972-06-16T00:00:00.000Z"));
+print(d.toString());
+print(d.toUTCString());
+
+// simple Date
+d = new Date(Date.parse("2009-01-01"));
+print(d.toString());
+print(d.toUTCString());
+
+// simple date and make sure we can parse back toString, toISOString
+// and toUTCString output ..
+d = new Date(2011, 4, 11);
+d = new Date(Date.parse(d.toString()));
+print(d.toString());
+print(d.toUTCString());
+
+d = new Date(Date.parse(d.toISOString()));
+print(d.toString());
+print(d.toUTCString());
+
+d = new Date(Date.parse(d.toUTCString()));
+print(d.toString());
+print(d.toUTCString());
diff --git a/nashorn/test/script/basic/dateparse.js.EXPECTED b/nashorn/test/script/basic/dateparse.js.EXPECTED
new file mode 100644
index 0000000..95e7d09
--- /dev/null
+++ b/nashorn/test/script/basic/dateparse.js.EXPECTED
@@ -0,0 +1,10 @@
+Fri Jun 16 1972 05:30:00 GMT+0530 (IST)
+Fri, 16 Jun 1972 00:00:00 GMT
+Thu Jan 01 2009 05:30:00 GMT+0530 (IST)
+Thu, 01 Jan 2009 00:00:00 GMT
+Wed May 11 2011 00:00:00 GMT+0530 (IST)
+Tue, 10 May 2011 18:30:00 GMT
+Wed May 11 2011 00:00:00 GMT+0530 (IST)
+Tue, 10 May 2011 18:30:00 GMT
+Wed May 11 2011 00:00:00 GMT+0530 (IST)
+Tue, 10 May 2011 18:30:00 GMT
diff --git a/nashorn/test/script/basic/debugger.js b/nashorn/test/script/basic/debugger.js
new file mode 100644
index 0000000..5e795a2
--- /dev/null
+++ b/nashorn/test/script/basic/debugger.js
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * Check that the debugger statement is parsed and does nothing as of now.
+ *
+ * @test
+ * @run
+ */
+
+debugger;
diff --git a/nashorn/test/script/basic/decinc.js b/nashorn/test/script/basic/decinc.js
new file mode 100644
index 0000000..3ee1ac1
--- /dev/null
+++ b/nashorn/test/script/basic/decinc.js
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test dec/inc
+ *
+ * @test
+ * @run
+ */
+
+
+function fpp(x) {
+    var y = x - 0;
+    return y++;
+}
+
+function fmm(x) {
+    var y = x - 0;
+    return y--;
+}
+
+function ppf(x) {
+    var y = x - 0;
+    return ++y;
+}
+
+function mmf(x) {
+    var y = x - 0;
+    return --y;
+}
+
+print(fpp(100));
+print(fmm(100));
+print(ppf(100));
+print(mmf(100));
+
+var o = { x: 200 };
+
+print(o.x++);
+print(o.x--);
+print(++o.x);
+print(--o.x);
+
+var a = [300];
+
+print(a[0]++);
+print(a[0]--);
+print(++a[0]);
+print(--a[0]);
+
diff --git a/nashorn/test/script/basic/decinc.js.EXPECTED b/nashorn/test/script/basic/decinc.js.EXPECTED
new file mode 100644
index 0000000..ce24b95
--- /dev/null
+++ b/nashorn/test/script/basic/decinc.js.EXPECTED
@@ -0,0 +1,12 @@
+100
+100
+101
+99
+200
+201
+201
+200
+300
+301
+301
+300
diff --git a/nashorn/test/script/basic/delete.js b/nashorn/test/script/basic/delete.js
new file mode 100644
index 0000000..6d7f884
--- /dev/null
+++ b/nashorn/test/script/basic/delete.js
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check delete operator.
+ *
+ * @test
+ * @run
+ */
+
+var obj = { foo: 3, bar: "hello" };
+
+print("foo" in obj);
+print(obj.foo);
+print(delete obj.foo);
+print("foo" in obj);
+
+print("bar" in obj);
+print(obj.bar);
+print(delete obj["bar"]);
+print("bar" in obj);
+
+print(delete obj.junk);
+print(delete obj["junk"]);
+print(delete obj[2]);
+
+x = 3;
+print(delete x);
+print("x" in this);
+
+// deleting literals
+print(delete 2);
+print(delete "hello");
+print(delete true);
+print(delete this);
+
+function func() {
+    print(delete this);
+}
+
+var o = {};
+o.func = func;
+o.func();
diff --git a/nashorn/test/script/basic/delete.js.EXPECTED b/nashorn/test/script/basic/delete.js.EXPECTED
new file mode 100644
index 0000000..4cea773
--- /dev/null
+++ b/nashorn/test/script/basic/delete.js.EXPECTED
@@ -0,0 +1,18 @@
+true
+3
+true
+false
+true
+hello
+true
+false
+true
+true
+true
+true
+false
+true
+true
+true
+true
+true
diff --git a/nashorn/test/script/basic/delete2.js b/nashorn/test/script/basic/delete2.js
new file mode 100644
index 0000000..3d14847
--- /dev/null
+++ b/nashorn/test/script/basic/delete2.js
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+/**
+ * delete second round test.
+ * throws VerifyError!!
+ *
+ * @test
+ * @run 
+ */
+
+var a = 10;
+
+var b = {w: 10, x: 20, y: 30, z: 40};
+
+function c() {}
+
+function d() { print("side effect"); }
+
+function e(g) {
+    var f = 10;
+    
+    print(delete f);
+    print(f);
+    print(delete g);
+    print(g);
+}
+
+function h(foo) {
+  var y = 33;
+  print(delete y);
+  print(y);
+  print(delete foo);
+  print(foo);
+  print(arguments[0]);
+  print(delete arguments[0]);
+  print(foo);
+  print(arguments[0]);
+}
+
+print(delete a);
+print(delete b.x);
+print(delete b["y"]);
+with (b) {
+    print(delete z);
+    print(delete b);
+}
+print(delete c);
+
+print(delete this.a);
+print(delete 10);
+print(delete d());
+
+print(typeof a);
+for(i in b) print(i, b[i]);
+print(typeof c);
+
+e(10);
+
+h(20);
diff --git a/nashorn/test/script/basic/delete2.js.EXPECTED b/nashorn/test/script/basic/delete2.js.EXPECTED
new file mode 100644
index 0000000..06f068b
--- /dev/null
+++ b/nashorn/test/script/basic/delete2.js.EXPECTED
@@ -0,0 +1,25 @@
+false
+true
+true
+true
+false
+false
+false
+true
+side effect
+true
+number
+w 10
+function
+false
+10
+false
+10
+false
+33
+false
+20
+20
+true
+20
+undefined
diff --git a/nashorn/test/script/basic/dotpropname.js b/nashorn/test/script/basic/dotpropname.js
new file mode 100644
index 0000000..03704ec
--- /dev/null
+++ b/nashorn/test/script/basic/dotpropname.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * "." is property name should be allowed.
+ *
+ * @test
+ * @run
+ */
+
+var obj = {};
+obj["abc.yyy"] =  function () {
+    print("abc.yyy called");
+};
+
+obj["abc.yyy"]();
+
+obj["abc.xyz"] = "hello";
+print(obj["abc.xyz"]);
+
diff --git a/nashorn/test/script/basic/dotpropname.js.EXPECTED b/nashorn/test/script/basic/dotpropname.js.EXPECTED
new file mode 100644
index 0000000..0baf117
--- /dev/null
+++ b/nashorn/test/script/basic/dotpropname.js.EXPECTED
@@ -0,0 +1,2 @@
+abc.yyy called
+hello
diff --git a/nashorn/test/script/basic/doublecache.js b/nashorn/test/script/basic/doublecache.js
new file mode 100644
index 0000000..91ac845
--- /dev/null
+++ b/nashorn/test/script/basic/doublecache.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Test double caching.
+ *
+ * @test
+ * @run
+ */
+
+var x = [
+        "number array spoiler",
+        -200,
+        -100,
+        -0.5,
+        -0.25,
+        0,
+        0.25,
+        0.5,
+        100,
+        200,
+        
+        -200,
+        -100,
+        -0.5,
+        -0.25,
+        0,
+        0.25,
+        0.5,
+        100,
+        200
+        ];
+        
+for (i in x) print(x[i]);
diff --git a/nashorn/test/script/basic/doublecache.js.EXPECTED b/nashorn/test/script/basic/doublecache.js.EXPECTED
new file mode 100644
index 0000000..c469337
--- /dev/null
+++ b/nashorn/test/script/basic/doublecache.js.EXPECTED
@@ -0,0 +1,19 @@
+number array spoiler
+-200
+-100
+-0.5
+-0.25
+0
+0.25
+0.5
+100
+200
+-200
+-100
+-0.5
+-0.25
+0
+0.25
+0.5
+100
+200
diff --git a/nashorn/test/script/basic/enumeration.js b/nashorn/test/script/basic/enumeration.js
new file mode 100644
index 0000000..3746dfe
--- /dev/null
+++ b/nashorn/test/script/basic/enumeration.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * Make sure that there are no-enumerable items on standard objects. 
+ *
+ * @test
+ * @run
+ */
+
+function enumerate(obj, name) {
+    var count = 0;
+    for (i in obj) {
+        print(i);
+        count++;
+    }
+    print("Enumerable items in " + name + " = " + count);
+}
+
+enumerate(Array.prototype, "Array.prototype");
+enumerate(Array, "Array");
+enumerate(Boolean.prototype, "Boolean.prototype");
+enumerate(Boolean, "Boolean");
+enumerate(Date.prototype, "Date.prototype");
+enumerate(Date, "Date");
+enumerate(Function.prototype, "Function.prototype");
+enumerate(Function, "Function");
+enumerate(JSON, "JSON");
+enumerate(Math, "Math");
+enumerate(Number.prototype, "Number.prototype");
+enumerate(Number, "Number");
+enumerate(Object.prototype, "Object.prototype");
+enumerate(Object, "Object");
+enumerate(String.prototype, "String.prototype");
+enumerate(String, "String");
diff --git a/nashorn/test/script/basic/enumeration.js.EXPECTED b/nashorn/test/script/basic/enumeration.js.EXPECTED
new file mode 100644
index 0000000..8cd73f3
--- /dev/null
+++ b/nashorn/test/script/basic/enumeration.js.EXPECTED
@@ -0,0 +1,16 @@
+Enumerable items in Array.prototype = 0
+Enumerable items in Array = 0
+Enumerable items in Boolean.prototype = 0
+Enumerable items in Boolean = 0
+Enumerable items in Date.prototype = 0
+Enumerable items in Date = 0
+Enumerable items in Function.prototype = 0
+Enumerable items in Function = 0
+Enumerable items in JSON = 0
+Enumerable items in Math = 0
+Enumerable items in Number.prototype = 0
+Enumerable items in Number = 0
+Enumerable items in Object.prototype = 0
+Enumerable items in Object = 0
+Enumerable items in String.prototype = 0
+Enumerable items in String = 0
diff --git a/nashorn/test/script/basic/errors.js b/nashorn/test/script/basic/errors.js
new file mode 100644
index 0000000..c698ef8
--- /dev/null
+++ b/nashorn/test/script/basic/errors.js
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic checks for Error constructors.
+ * 
+ * @test
+ * @run
+ */
+
+print(Error.name + " is a " + typeof(Error));
+print(EvalError.name + " is a " + typeof(EvalError));
+print(RangeError.name + " is a " + typeof(RangeError));
+print(ReferenceError.name + " is a " + typeof(ReferenceError));
+print(SyntaxError.name + " is a " + typeof(SyntaxError));
+print(TypeError.name + " is a " + typeof(TypeError));
+print(URIError.name + " is a " + typeof(URIError));
+
+print("Error.arity " + Error.length);
+print("EvalError.arity " + EvalError.length);
+print("RangeError.arity " + RangeError.length);
+print("ReferenceError.arity " + ReferenceError.length);
+print("SyntaxError.arity " + SyntaxError.length);
+print("TypeError.arity " + TypeError.length);
+print("URIError.arity " + URIError.length);
+
+var err = new Error("my error");
+try {
+    throw err;
+} catch (e) {
+    print(e instanceof Error);
+    print(e.message);
+    print(e.name);
+    var ne = e.nashornException;
+    if (ne != undefined) {
+        if (ne.fileName !== __FILE__) {
+            fail("incorrect filename in error");
+        }
+        print("thrown @ " + ne.lineNumber);
+    }
+}
+
+// try to print undefined global var..
+try {
+    print(foo);
+} catch (e) {
+    print(e instanceof ReferenceError);
+    print(e.name);
+    print(e.message);
+}
+
+// try to call something that is undefined
+try {
+    Object.foo_method();
+} catch (e) {
+    print(e instanceof TypeError);
+    print(e.name);
+    print(e.message);
+}
+
+// prototypes of Error constructors are not writable
+Error.prototype = {};
+print(Error.prototype.name);
+EvalError.prototype = {};
+print(EvalError.prototype.name);
+RangeError.prototype = {};
+print(RangeError.prototype.name);
+ReferenceError.prototype = {};
+print(ReferenceError.prototype.name);
+SyntaxError.prototype = {};
+print(SyntaxError.prototype.name);
+TypeError.prototype = {};
+print(TypeError.prototype.name);
+URIError.prototype = {};
+print(URIError.prototype.name);
diff --git a/nashorn/test/script/basic/errors.js.EXPECTED b/nashorn/test/script/basic/errors.js.EXPECTED
new file mode 100644
index 0000000..8fae2ca
--- /dev/null
+++ b/nashorn/test/script/basic/errors.js.EXPECTED
@@ -0,0 +1,31 @@
+Error is a function
+EvalError is a function
+RangeError is a function
+ReferenceError is a function
+SyntaxError is a function
+TypeError is a function
+URIError is a function
+Error.arity 1
+EvalError.arity 1
+RangeError.arity 1
+ReferenceError.arity 1
+SyntaxError.arity 1
+TypeError.arity 1
+URIError.arity 1
+true
+my error
+Error
+thrown @ 49
+true
+ReferenceError
+"foo" is not defined
+true
+TypeError
+Cannot call undefined
+Error
+EvalError
+RangeError
+ReferenceError
+SyntaxError
+TypeError
+URIError
diff --git a/nashorn/test/script/basic/errorstack.js b/nashorn/test/script/basic/errorstack.js
new file mode 100644
index 0000000..7db5314
--- /dev/null
+++ b/nashorn/test/script/basic/errorstack.js
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * "stack" property of Error objects. (nashorn extension).
+ *
+ * @test
+ * @run
+ */ 
+
+function func1() {
+   func2();
+}
+
+function func2() {
+   func3();
+}
+
+function func3() {
+   throw new Error("error");
+}
+
+try {
+    func1();
+} catch (e) {
+    // "stack" is java.lang.StackTraceElement object
+    for (i in e.stack) {
+        print(e.stack[i].methodName + " : " + e.stack[i].lineNumber);
+    }
+}
+
diff --git a/nashorn/test/script/basic/errorstack.js.EXPECTED b/nashorn/test/script/basic/errorstack.js.EXPECTED
new file mode 100644
index 0000000..bb85d4e
--- /dev/null
+++ b/nashorn/test/script/basic/errorstack.js.EXPECTED
@@ -0,0 +1,4 @@
+func3 : 40
+func2 : 36
+func1 : 32
+runScript : 44
diff --git a/nashorn/test/script/basic/eval.js b/nashorn/test/script/basic/eval.js
new file mode 100644
index 0000000..bd63068
--- /dev/null
+++ b/nashorn/test/script/basic/eval.js
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+/**
+ * eval test.
+ *
+ * @test
+ * @run 
+ */
+
+print("eval.length " + eval.length);
+
+function test1() {
+    var x = 200;
+    y = x + 2000;
+    
+    print(x);
+    print(y);
+}
+
+function test2() {
+    eval("var x = 300;");
+    eval("y = x + 3000;");
+    
+    print(x);
+    print(y);
+}
+
+
+eval("var x = 100;");
+eval("y = x + 1000;");
+
+print(x);
+print(y);
+
+test1();
+
+print(x);
+print(y);
+
+test2();
+
+print(x);
+print(y);
+
+// evaluate with syntax error and catch error
+try {
+    // missing end quote
+    eval("print('hello)");
+} catch (e) {
+    print("is syntax error? " + (e instanceof SyntaxError));
+    print(e.toString().replace(/\\/g, '/'));
+}
diff --git a/nashorn/test/script/basic/eval.js.EXPECTED b/nashorn/test/script/basic/eval.js.EXPECTED
new file mode 100644
index 0000000..3ab2f3d
--- /dev/null
+++ b/nashorn/test/script/basic/eval.js.EXPECTED
@@ -0,0 +1,15 @@
+eval.length 1
+100
+1100
+200
+2200
+100
+2200
+300
+3300
+100
+3300
+is syntax error? true
+SyntaxError: test/script/basic/eval.js#69<eval>:1:13 Missing close quote
+print('hello)
+             ^
diff --git a/nashorn/test/script/basic/evalreturn.js b/nashorn/test/script/basic/evalreturn.js
new file mode 100644
index 0000000..3f523cc
--- /dev/null
+++ b/nashorn/test/script/basic/evalreturn.js
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/**
+ * eval return values test.
+ *
+ * @test
+ * @run 
+ */
+
+var x = 0;
+print(eval("for(var x = 0; x < 100 ; x++) x;"));
+print(eval("if (x == 1) { 'hello' } else { 'world' }"));
+print(eval("do { x = 1 } while (false);"));
+print(eval("var x = 1"));
+print(eval("if (x == 0) { 'hello' }"));
+print(eval("if (x == 1) { 'hello' }"));
+
+var i;
+var j;
+str1 = '';
+str2 = '';
+x = 1;
+y = 2;
+
+for (i in this) {
+    str1 += i;
+}
+
+eval('for(j in this){\nstr2+=j;\n}');
+
+if (!(str1 === str2)){
+    print("scope chain is broken");
+    print("str1 = "+str1);
+    print("str2 = "+str2);
+    print("they should be the same");
+    throw "error";
+}
+
+print("Scoping OK");
+
+var f = eval("function cookie() { print('sweet and crunchy!'); } function cake() { print('moist and delicious!'); }");
+print(f);
+f();
+var g = eval("function cake() { print('moist and delicious!'); } function cookie() { print('sweet and crunchy!'); }");
+print(g);
+g();
+ 
+
+
+
diff --git a/nashorn/test/script/basic/evalreturn.js.EXPECTED b/nashorn/test/script/basic/evalreturn.js.EXPECTED
new file mode 100644
index 0000000..96d044d
--- /dev/null
+++ b/nashorn/test/script/basic/evalreturn.js.EXPECTED
@@ -0,0 +1,11 @@
+99
+world
+1
+undefined
+undefined
+hello
+Scoping OK
+function cake() { print('moist and delicious!'); }
+moist and delicious!
+function cookie() { print('sweet and crunchy!'); }
+sweet and crunchy!
diff --git a/nashorn/test/script/basic/exprclosure.js b/nashorn/test/script/basic/exprclosure.js
new file mode 100644
index 0000000..ad1c396
--- /dev/null
+++ b/nashorn/test/script/basic/exprclosure.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Expression closures.
+ *
+ * @test
+ * @run
+ */
+
+var f = function(x) x*x;
+print(f);
+print(f(25));
+
+function fun(x) x * (x + 1) / 2;
+print(fun);
+print(fun(10));
+
diff --git a/nashorn/test/script/basic/exprclosure.js.EXPECTED b/nashorn/test/script/basic/exprclosure.js.EXPECTED
new file mode 100644
index 0000000..ae80338
--- /dev/null
+++ b/nashorn/test/script/basic/exprclosure.js.EXPECTED
@@ -0,0 +1,4 @@
+function(x) x*x;
+625
+function fun(x) x * (x + 1) / 2;
+55
diff --git a/nashorn/test/script/basic/extensibility.js b/nashorn/test/script/basic/extensibility.js
new file mode 100644
index 0000000..0904466
--- /dev/null
+++ b/nashorn/test/script/basic/extensibility.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic checks for Object.preventExtensible.
+ *
+ * @test
+ * @run
+ */
+
+// after preventExtenssions, we can't add new properties but
+// can modifiy existing properties.
+var obj = { num: 45.0 };
+
+print("extensible? " + Object.isExtensible(obj));
+Object.preventExtensions(obj);
+print("extensible? " + Object.isExtensible(obj));
+
+obj['bar'] = "hello";
+print(obj.bar);
+obj.num = Math.PI;
+print(obj.num);
+
+obj.foo = 55;
+print(obj.foo);
+obj.num = Math.E;
+print(obj.num);
diff --git a/nashorn/test/script/basic/extensibility.js.EXPECTED b/nashorn/test/script/basic/extensibility.js.EXPECTED
new file mode 100644
index 0000000..bc726ed
--- /dev/null
+++ b/nashorn/test/script/basic/extensibility.js.EXPECTED
@@ -0,0 +1,6 @@
+extensible? true
+extensible? false
+undefined
+3.141592653589793
+undefined
+2.718281828459045
diff --git a/nashorn/test/script/basic/fileline.js b/nashorn/test/script/basic/fileline.js
new file mode 100644
index 0000000..3323a12
--- /dev/null
+++ b/nashorn/test/script/basic/fileline.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check __FILE__, __LINE__ and __DIR__ built-ins.
+ *
+ * @test
+ * @run
+ */
+
+print("hello world");
+var idx = __FILE__.lastIndexOf(java.io.File.separator);
+if (idx < 0) {
+    // separator is "/" when running under ant on windows
+    idx = __FILE__.lastIndexOf("/");
+}
+var file = (idx != -1)? __FILE__.substring(idx + 1) : __FILE__;
+print(file + " : " + __LINE__);
+
+// loaded file should see it's name in __FILE__
+load(__DIR__ + "loadedfile.js");
+
+// Add check for base part of a URL. We can't test __DIR__ inside
+// a script that is downloaded from a URL. check for Source.baseURL
+// which is exposed as __DIR__ for URL case.
+
+var url = new java.net.URL("http://www.acme.com:8080/foo/bar.js");
+print(Packages.jdk.nashorn.internal.runtime.Source.baseURL(url));
diff --git a/nashorn/test/script/basic/fileline.js.EXPECTED b/nashorn/test/script/basic/fileline.js.EXPECTED
new file mode 100644
index 0000000..ac75a2c
--- /dev/null
+++ b/nashorn/test/script/basic/fileline.js.EXPECTED
@@ -0,0 +1,4 @@
+hello world
+fileline.js : 38
+loadedfile.js : 36
+http://www.acme.com:8080/foo/
diff --git a/nashorn/test/script/basic/finally-catchalls.js b/nashorn/test/script/basic/finally-catchalls.js
new file mode 100644
index 0000000..dac9cee
--- /dev/null
+++ b/nashorn/test/script/basic/finally-catchalls.js
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+/**
+ * finally-catchalls: should not be able to read, write, call properties from null literal.
+ *
+ * @test
+ * @run
+ */
+
+function test1() {
+    try {
+	print("try");
+	throw "ex";
+    } finally {
+	print("finally");
+    }
+}
+
+function test2() {   
+    try {
+	print("try");
+    } finally {
+	print("finally");
+    }
+}
+
+function test3() {   
+    try {
+	print("try");
+	return;
+    } finally {
+	print("finally");
+    }
+}
+
+function test4() {   
+    var i = 0;
+    while (i<10) {
+	try {
+	    print("try "+i);
+	    i++;
+	    continue;
+	} finally {
+	    print("finally "+i);
+	}
+    }
+    print(i);
+}
+
+function test5() {   
+    var i = 0;
+    while (i<10) {
+	try {
+	    print("try "+i);
+	    i++;
+	    break;
+	} finally {
+	    print("finally "+i);
+	}
+    }
+    print(i);
+}
+
+function test6() {   
+    var i = 0;
+    while (i<10) {
+	try {
+	    print("try "+i);
+	    if (i == 5)
+		break;
+	    i++;
+	} finally {
+	    print("finally "+i);
+	}
+    }
+    print(i);
+}
+
+print("\ntest 1\n");
+try { 
+    test1();
+} catch (e) {
+    print("got e");
+}
+
+print("\ntest 2\n");
+test2();
+
+print("\ntest 3\n");
+test3();
+
+print("\ntest 4\n");
+test4();
+
+print("\ntest 5\n");
+test5();
+
+print("\ntest 6\n");
+test6();
+
diff --git a/nashorn/test/script/basic/finally-catchalls.js.EXPECTED b/nashorn/test/script/basic/finally-catchalls.js.EXPECTED
new file mode 100644
index 0000000..51e0664
--- /dev/null
+++ b/nashorn/test/script/basic/finally-catchalls.js.EXPECTED
@@ -0,0 +1,62 @@
+
+test 1
+
+try
+finally
+got e
+
+test 2
+
+try
+finally
+
+test 3
+
+try
+finally
+
+test 4
+
+try 0
+finally 1
+try 1
+finally 2
+try 2
+finally 3
+try 3
+finally 4
+try 4
+finally 5
+try 5
+finally 6
+try 6
+finally 7
+try 7
+finally 8
+try 8
+finally 9
+try 9
+finally 10
+10
+
+test 5
+
+try 0
+finally 1
+1
+
+test 6
+
+try 0
+finally 1
+try 1
+finally 2
+try 2
+finally 3
+try 3
+finally 4
+try 4
+finally 5
+try 5
+finally 5
+5
diff --git a/nashorn/test/script/basic/finallyreturn.js b/nashorn/test/script/basic/finallyreturn.js
new file mode 100644
index 0000000..79c9f71
--- /dev/null
+++ b/nashorn/test/script/basic/finallyreturn.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * This results in VerifyError: Control flow falls through code end.
+ *
+ * @test
+ * @run
+ */
+
+function func(){
+    try {
+        return 0;
+    } finally {
+        return 42;
+    }
+}
+
+print(func());
+
+
diff --git a/nashorn/test/script/basic/finallyreturn.js.EXPECTED b/nashorn/test/script/basic/finallyreturn.js.EXPECTED
new file mode 100644
index 0000000..d81cc07
--- /dev/null
+++ b/nashorn/test/script/basic/finallyreturn.js.EXPECTED
@@ -0,0 +1 @@
+42
diff --git a/nashorn/test/script/basic/forin.js b/nashorn/test/script/basic/forin.js
new file mode 100644
index 0000000..ee3fa89
--- /dev/null
+++ b/nashorn/test/script/basic/forin.js
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test for in
+ *
+ * @test
+ * @run
+ */
+
+var a = [10, 20, 30, 40];
+var o = {a: 100, b: 200, c: 300};
+var j = new java.util.ArrayList();
+j.add("apple");
+j.add("bear");
+j.add("car");
+var ja = j.toArray();
+var s = "apple,bear,car".split(",");
+
+for (i in a) print(i, a[i]);
+for each (i in a) print(i);
+for (i in o) print(i, o[i]);
+for each (i in j) print(i);
+for (i in ja) print(i, ja[i]);
+for each (i in ja) print(i);
+for (i in s) print(i, s[i]);
+for each (i in s) print(i);
+
+// 'each' is a contextual keyword. Ok to use as identifier elsewhere..
+var each = "This is each";
+print(each);
+
+// it is ok to use "each" is usual for loop. Ignored as noise word.
+for each (var i = 0; i < 10; i++) {
+    print(i);
+}
diff --git a/nashorn/test/script/basic/forin.js.EXPECTED b/nashorn/test/script/basic/forin.js.EXPECTED
new file mode 100644
index 0000000..159e43b
--- /dev/null
+++ b/nashorn/test/script/basic/forin.js.EXPECTED
@@ -0,0 +1,37 @@
+0 10
+1 20
+2 30
+3 40
+10
+20
+30
+40
+a 100
+b 200
+c 300
+apple
+bear
+car
+0 apple
+1 bear
+2 car
+apple
+bear
+car
+0 apple
+1 bear
+2 car
+apple
+bear
+car
+This is each
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
diff --git a/nashorn/test/script/basic/forin2.js b/nashorn/test/script/basic/forin2.js
new file mode 100644
index 0000000..be47bec
--- /dev/null
+++ b/nashorn/test/script/basic/forin2.js
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+/**
+ * Mostly for-in iterations through esoteric collections
+ *
+ * @test
+ * @run
+ */
+
+for (y in {}) {
+    y = 2;
+}
+
+try {
+    null['foo'];
+    print("error 1");
+} catch(e) {
+    if ((e instanceof TypeError) !== true) {
+	print(e);
+    }
+}
+
+try {
+    with(null) x = 2;
+    print("error 2");
+} catch(e) {
+    if((e instanceof TypeError) !== true) {
+	print(e);
+    }
+}
+
+try {  
+    for (var y in null) { 
+	y = 2;
+    }
+    print("this is ok 1");
+} catch(e) {
+    if ((e instanceof TypeError) !== true) {
+	print(e);
+    }
+}
+
+// CHECK#4
+try {
+    for (var z in 'bbb'.match(/aaa/)) { 
+	z = 2;
+    }
+    print("this is ok 2");
+} catch(e) {
+    if((e instanceof TypeError) !== true) {
+	print(e);
+    }
+}
+
+
+try {
+    undefined['foo'];
+    print("error 5");
+} catch(e) {
+    if ((e instanceof TypeError) !== true) {
+	print(e);
+    }
+}
+
+try {
+    with(undefined) x = 2;
+    print("error 6");
+} catch (e) {
+    if ((e instanceof TypeError) !== true) {
+	print(e);
+    }
+}
+
+// CHECK#3
+try {
+    for (var y in undefined) { 
+	y = 2;
+    }
+    print("this is ok 3");
+} catch (e) { 
+    if ((e instanceof TypeError) !== true) {
+	print(e);
+    }
+}
+
+try {
+    for (var z in this.foo) { 
+	z = 2;
+    }
+    print("this is ok 4");
+} catch (e) {
+    if ((e instanceof TypeError) !== true) {
+	print(e);
+    }
+}
diff --git a/nashorn/test/script/basic/forin2.js.EXPECTED b/nashorn/test/script/basic/forin2.js.EXPECTED
new file mode 100644
index 0000000..07e5681
--- /dev/null
+++ b/nashorn/test/script/basic/forin2.js.EXPECTED
@@ -0,0 +1,4 @@
+this is ok 1
+this is ok 2
+this is ok 3
+this is ok 4
diff --git a/nashorn/test/script/basic/funcarray.js b/nashorn/test/script/basic/funcarray.js
new file mode 100644
index 0000000..7ffd5f5
--- /dev/null
+++ b/nashorn/test/script/basic/funcarray.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * Function array test.
+ *
+ * @test
+ * @run 
+ */
+ 
+
+var funcs = [
+                function() { print("first"); },
+                function() { print("second"); },
+                function() { print("third"); },
+                function() { print("fourth"); }
+            ];
+            
+funcs[0]();
+funcs[1]();
+funcs[2]();
+funcs[3]();
diff --git a/nashorn/test/script/basic/funcarray.js.EXPECTED b/nashorn/test/script/basic/funcarray.js.EXPECTED
new file mode 100644
index 0000000..cf59613
--- /dev/null
+++ b/nashorn/test/script/basic/funcarray.js.EXPECTED
@@ -0,0 +1,4 @@
+first
+second
+third
+fourth
diff --git a/nashorn/test/script/basic/funcbind.js b/nashorn/test/script/basic/funcbind.js
new file mode 100644
index 0000000..2b97b0e
--- /dev/null
+++ b/nashorn/test/script/basic/funcbind.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test the functionality of Function.prototype.bind.
+ *
+ * @test
+ * @run
+ */
+
+var global = this;
+
+function foo() {
+    print("global foo");
+}
+
+function func(x, y) { 
+    print(this == global);
+    print(x); 
+    print(y); 
+    this.foo();
+}
+
+print("func.bind.length = " + func.bind.length);
+
+var f = func.bind(this, 434);
+print(f.length);
+f("hello");
+
+// bind with a different 'this' and different number of args
+f = func.bind({ foo: function() { print("foo member"); } });
+print(f.length);
+f("world", 42);
diff --git a/nashorn/test/script/basic/funcbind.js.EXPECTED b/nashorn/test/script/basic/funcbind.js.EXPECTED
new file mode 100644
index 0000000..e47253f
--- /dev/null
+++ b/nashorn/test/script/basic/funcbind.js.EXPECTED
@@ -0,0 +1,11 @@
+func.bind.length = 1
+1
+true
+434
+hello
+global foo
+2
+false
+world
+42
+foo member
diff --git a/nashorn/test/script/basic/funcbind2.js b/nashorn/test/script/basic/funcbind2.js
new file mode 100644
index 0000000..697ee52
--- /dev/null
+++ b/nashorn/test/script/basic/funcbind2.js
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test the functionality of Function.prototype.bind.
+ *
+ * @test
+ * @run
+ */
+
+function f(a, b) {
+    print("f: this=" + this + ", a=" + a + ", b=" + b);
+}
+function v(a, b) {
+    print("v: this=" + this + ", a=" + a + ", b=" + b + ", c=" + arguments[2]);
+}
+
+(f.bind(null))();
+(v.bind(null))();
+
+var boundThis = "boundThis";
+(f.bind(boundThis))();
+(v.bind(boundThis))();
+
+(f.bind(boundThis))("a0");
+(v.bind(boundThis))("a1");
+
+(f.bind(boundThis, "a2"))();
+(v.bind(boundThis, "a3"))();
+
+(f.bind(boundThis, "a4"))("b4");
+(v.bind(boundThis, "a5"))("b5");
+
+(f.bind(boundThis, "a6", "b6"))();
+(v.bind(boundThis, "a7", "b7"))();
+
+(f.bind(boundThis, "a8", "b8"))("c8"); // invoking with extra args after all were bound!
+(v.bind(boundThis, "a9", "b9"))("c9");
+
+(f.bind(boundThis, "a10", "b10", "c10"))(); // binding more args than it receives!
+(v.bind(boundThis, "a11", "b11", "c11"))();
+
+print("\nTest constructors\n");
+
+new (f.bind(boundThis))();
+new (v.bind(boundThis))();
+
+new (f.bind(boundThis))("a0");
+new (v.bind(boundThis))("a1");
+
+new (f.bind(boundThis, "a2"))();
+new (v.bind(boundThis, "a3"))();
+
+new (f.bind(boundThis, "a4"))("b4");
+new (v.bind(boundThis, "a5"))("b5");
+
+new (f.bind(boundThis, "a6", "b6"))();
+new (v.bind(boundThis, "a7", "b7"))();
+
+new (f.bind(boundThis, "a8", "b8"))("c8");
+new (v.bind(boundThis, "a9", "b9"))("c9");
+
+new (f.bind(boundThis, "a10", "b10", "c10"))();
+new (v.bind(boundThis, "a11", "b11", "c11"))();
+
+print("\nTest double binding\n");
+
+(f.bind(boundThis).bind("thisIsIgnored"))();
+new (f.bind("thisIsIgnored").bind("thisIsIgnoredToo"))();
+new (f.bind("thisIsIgnored", "a12").bind("thisIsIgnoredToo"))();
+
+(v.bind(boundThis).bind("thisIsIgnored"))();
+new (v.bind("thisIsIgnored").bind("thisIsIgnoredToo"))();
+new (v.bind("thisIsIgnored", "a13").bind("thisIsIgnoredToo"))();
diff --git a/nashorn/test/script/basic/funcbind2.js.EXPECTED b/nashorn/test/script/basic/funcbind2.js.EXPECTED
new file mode 100644
index 0000000..5b87453
--- /dev/null
+++ b/nashorn/test/script/basic/funcbind2.js.EXPECTED
@@ -0,0 +1,42 @@
+f: this=[object global], a=undefined, b=undefined
+v: this=[object global], a=undefined, b=undefined, c=undefined
+f: this=boundThis, a=undefined, b=undefined
+v: this=boundThis, a=undefined, b=undefined, c=undefined
+f: this=boundThis, a=a0, b=undefined
+v: this=boundThis, a=a1, b=undefined, c=undefined
+f: this=boundThis, a=a2, b=undefined
+v: this=boundThis, a=a3, b=undefined, c=undefined
+f: this=boundThis, a=a4, b=b4
+v: this=boundThis, a=a5, b=b5, c=undefined
+f: this=boundThis, a=a6, b=b6
+v: this=boundThis, a=a7, b=b7, c=undefined
+f: this=boundThis, a=a8, b=b8
+v: this=boundThis, a=a9, b=b9, c=c9
+f: this=boundThis, a=a10, b=b10
+v: this=boundThis, a=a11, b=b11, c=c11
+
+Test constructors
+
+f: this=[object Object], a=undefined, b=undefined
+v: this=[object Object], a=undefined, b=undefined, c=undefined
+f: this=[object Object], a=a0, b=undefined
+v: this=[object Object], a=a1, b=undefined, c=undefined
+f: this=[object Object], a=a2, b=undefined
+v: this=[object Object], a=a3, b=undefined, c=undefined
+f: this=[object Object], a=a4, b=b4
+v: this=[object Object], a=a5, b=b5, c=undefined
+f: this=[object Object], a=a6, b=b6
+v: this=[object Object], a=a7, b=b7, c=undefined
+f: this=[object Object], a=a8, b=b8
+v: this=[object Object], a=a9, b=b9, c=c9
+f: this=[object Object], a=a10, b=b10
+v: this=[object Object], a=a11, b=b11, c=c11
+
+Test double binding
+
+f: this=boundThis, a=undefined, b=undefined
+f: this=[object Object], a=undefined, b=undefined
+f: this=[object Object], a=a12, b=undefined
+v: this=boundThis, a=undefined, b=undefined, c=undefined
+v: this=[object Object], a=undefined, b=undefined, c=undefined
+v: this=[object Object], a=a13, b=undefined, c=undefined
diff --git a/nashorn/test/script/basic/funcbind3.js b/nashorn/test/script/basic/funcbind3.js
new file mode 100644
index 0000000..25f448d
--- /dev/null
+++ b/nashorn/test/script/basic/funcbind3.js
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test the assumptions about bound function prototypes
+ *
+ * @test
+ * @run
+ */
+
+function printAssumption(__x__) {
+  print(__x__ + ": " + eval(__x__));
+}
+
+function f() { }
+
+var b = f.bind(null)
+
+var x = new f()
+var y = new b()
+
+printAssumption("x instanceof f")
+printAssumption("x instanceof b")
+printAssumption("y instanceof f")
+printAssumption("y instanceof b")
+
+print("\nChanging prototype\n");
+
+f.prototype=new Object()
+
+printAssumption("x instanceof f")
+printAssumption("x instanceof b")
+printAssumption("y instanceof f")
+printAssumption("y instanceof b")
+
+print("\Bound function prototype\n");
+
+printAssumption("f.hasOwnProperty('prototype')")
+printAssumption("b.hasOwnProperty('prototype')")
diff --git a/nashorn/test/script/basic/funcbind3.js.EXPECTED b/nashorn/test/script/basic/funcbind3.js.EXPECTED
new file mode 100644
index 0000000..f69126d
--- /dev/null
+++ b/nashorn/test/script/basic/funcbind3.js.EXPECTED
@@ -0,0 +1,15 @@
+x instanceof f: true
+x instanceof b: true
+y instanceof f: true
+y instanceof b: true
+
+Changing prototype
+
+x instanceof f: false
+x instanceof b: false
+y instanceof f: false
+y instanceof b: false
+Bound function prototype
+
+f.hasOwnProperty('prototype'): true
+b.hasOwnProperty('prototype'): false
diff --git a/nashorn/test/script/basic/funcconstructor.js b/nashorn/test/script/basic/funcconstructor.js
new file mode 100644
index 0000000..038031c
--- /dev/null
+++ b/nashorn/test/script/basic/funcconstructor.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test Function constructor.
+ *
+ * @test
+ * @run
+ */
+
+var f = new Function("x", "print('anon func'); return x*x;");
+print(f(15));
+print(f.toSource());
+
+try {
+    // should throw SyntaxError for missing quote
+    var f = new Function("print('hello)");
+} catch (e) {
+    print("syntax error? " + (e instanceof SyntaxError));
+    print(e);
+}
+
+print("done");
diff --git a/nashorn/test/script/basic/funcconstructor.js.EXPECTED b/nashorn/test/script/basic/funcconstructor.js.EXPECTED
new file mode 100644
index 0000000..cf537d5
--- /dev/null
+++ b/nashorn/test/script/basic/funcconstructor.js.EXPECTED
@@ -0,0 +1,10 @@
+anon func
+225
+function (x) {
+print('anon func'); return x*x;
+}
+syntax error? true
+SyntaxError: <function>:2:13 Missing close quote
+print('hello)
+             ^
+done
diff --git a/nashorn/test/script/basic/getclassname.js b/nashorn/test/script/basic/getclassname.js
new file mode 100644
index 0000000..3e29bc6
--- /dev/null
+++ b/nashorn/test/script/basic/getclassname.js
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test to check [[Class]] internal property for various standard objects.
+ *
+ * @test
+ * @run
+ */
+
+function checkClass(obj, expected) {
+    var str = Object.prototype.toString.call(obj);
+    if (str != expected) {
+        fail("expected " + expected + ", got " + str);
+    }
+}
+
+// objects
+checkClass([2, 23], "[object Array]");
+checkClass(new Boolean(true), "[object Boolean]");
+checkClass(new Date(0), "[object Date]");
+checkClass(new Error(), "[object Error]");
+checkClass(new EvalError(), "[object Error]");
+if (typeof JSAdapter != 'undefined') {
+    checkClass(new JSAdapter({}), "[object JSAdapter]");
+}
+if (typeof JavaImporter != 'undefined') {
+    checkClass(new JavaImporter(java.io), "[object JavaImporter]");
+}
+checkClass(function() {}, "[object Function]");
+checkClass(new Number(42), "[object Number]");
+checkClass(new Object(), "[object Object]");
+checkClass(new RangeError(), "[object Error]");
+checkClass(new ReferenceError(), "[object Error]");
+checkClass(/nashorn/, "[object RegExp]");
+checkClass(new String('hello'), "[object String]");
+checkClass(new SyntaxError(), "[object Error]");
+checkClass(new TypeError(), "[object Error]");
+checkClass(new URIError(), "[object Error]");
+
+// constructors and prototypes
+checkClass(Array, "[object Function]");
+checkClass(Array.prototype, "[object Array]");
+checkClass(Boolean, "[object Function]");
+checkClass(Boolean.prototype, "[object Boolean]");
+checkClass(Date, "[object Function]");
+checkClass(Date.prototype, "[object Date]");
+checkClass(Error, "[object Function]");
+checkClass(Error.prototype, "[object Error]");
+checkClass(EvalError, "[object Function]");
+checkClass(EvalError.prototype, "[object Error]");
+checkClass(Function, "[object Function]");
+checkClass(Function.prototype, "[object Function]");
+if (typeof JSAdapter != 'undefined') {
+    checkClass(JSAdapter, "[object Function]");
+    checkClass(JSAdapter.prototype, "[object JSAdapter]");
+}
+if (typeof JavaImporter != 'undefined') {
+    checkClass(JavaImporter, "[object Function]");
+    checkClass(JavaImporter.prototype, "[object JavaImporter]");
+}
+checkClass(Number, "[object Function]");
+checkClass(Number.prototype, "[object Number]");
+checkClass(Object, "[object Function]");
+checkClass(Object.prototype, "[object Object]");
+checkClass(RangeError, "[object Function]");
+checkClass(RangeError.prototype, "[object Error]");
+checkClass(ReferenceError, "[object Function]");
+checkClass(ReferenceError.prototype, "[object Error]");
+checkClass(RegExp, "[object Function]");
+checkClass(RegExp.prototype, "[object RegExp]");
+checkClass(String, "[object Function]");
+checkClass(String.prototype, "[object String]");
+checkClass(SyntaxError, "[object Function]");
+checkClass(SyntaxError.prototype, "[object Error]");
+checkClass(TypeError, "[object Function]");
+checkClass(TypeError.prototype, "[object Error]");
+checkClass(URIError, "[object Function]");
+checkClass(URIError.prototype, "[object Error]");
+
+// misc. objects
+checkClass(this, "[object global]");
+checkClass(this.prototype, "[object Undefined]");
+
+if (typeof Packages != 'undefined') {
+    checkClass(Packages, "[object JavaPackage]");
+    checkClass(java, "[object JavaPackage]");
+    checkClass(javax, "[object JavaPackage]");
+}
+
+if (typeof Java != 'undefined') {
+    checkClass(Java, "[object Java]");
+    checkClass(Java.prototype, "[object Undefined]");
+}
+
+if (typeof Debug != 'undefined') {
+    checkClass(Debug, "[object Debug]");
+}
+
+checkClass((function() { return arguments; })(), "[object Arguments]");
+// strict arguments implementation is different.
+checkClass((function() { 'use strict'; return arguments; })(), "[object Arguments]");
+checkClass(JSON, "[object JSON]");
+checkClass(JSON.prototype, "[object Undefined]");
+checkClass(Math, "[object Math]");
+checkClass(Math.prototype, "[object Undefined]");
diff --git a/nashorn/test/script/basic/getter_callsite.js b/nashorn/test/script/basic/getter_callsite.js
new file mode 100644
index 0000000..1e0800f
--- /dev/null
+++ b/nashorn/test/script/basic/getter_callsite.js
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check that getter property is properly invoked by a callsite
+ * 
+ * @test
+ * @run
+ */
+
+function newObj(a) {
+  return { get foo() { return a }};
+}
+
+function printFoo(obj) { 
+    print("obj.foo is " + obj.foo);
+}
+
+var obj1 = newObj(42);
+var obj2 = newObj('hello');
+
+printFoo(obj1);
+printFoo(obj2);
+
+var obj3 = Object.create(newObj('world'));
+printFoo(obj3);
+
+Object.defineProperty(Object.getPrototypeOf(obj3),
+   "foo", { get: function() { return 3.1415; } });
+
+printFoo(obj3);
diff --git a/nashorn/test/script/basic/getter_callsite.js.EXPECTED b/nashorn/test/script/basic/getter_callsite.js.EXPECTED
new file mode 100644
index 0000000..2fabd75
--- /dev/null
+++ b/nashorn/test/script/basic/getter_callsite.js.EXPECTED
@@ -0,0 +1,4 @@
+obj.foo is 42
+obj.foo is hello
+obj.foo is world
+obj.foo is 3.1415
diff --git a/nashorn/test/script/basic/gettercalls.js b/nashorn/test/script/basic/gettercalls.js
new file mode 100644
index 0000000..200f1ce
--- /dev/null
+++ b/nashorn/test/script/basic/gettercalls.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * A getter method returns function typed value. When this property is called,
+ * we should call getter every time and then call the resulting function.
+ *
+ * @test
+ * @run
+ */
+
+var count = 0;
+
+var obj = {
+  get func() {
+     print("getter for func");
+     return function() {
+        return count++;
+     }
+  }
+};
+
+for (i = 0; i < 10; i++) {
+   print(obj.func());
+}
+
+print("count = " + count);
+
diff --git a/nashorn/test/script/basic/gettercalls.js.EXPECTED b/nashorn/test/script/basic/gettercalls.js.EXPECTED
new file mode 100644
index 0000000..cf8143e
--- /dev/null
+++ b/nashorn/test/script/basic/gettercalls.js.EXPECTED
@@ -0,0 +1,21 @@
+getter for func
+0
+getter for func
+1
+getter for func
+2
+getter for func
+3
+getter for func
+4
+getter for func
+5
+getter for func
+6
+getter for func
+7
+getter for func
+8
+getter for func
+9
+count = 10
diff --git a/nashorn/test/script/basic/getterfunc.js b/nashorn/test/script/basic/getterfunc.js
new file mode 100644
index 0000000..2c2cc4b
--- /dev/null
+++ b/nashorn/test/script/basic/getterfunc.js
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test getter with function.
+ *
+ * @test
+ * @run
+ */
+
+var a = {
+ get func() {
+    var aCount = 0;
+    return function() {
+       return aCount++;
+    }
+ }
+};
+
+for (i = 0; i < 10; i++) {
+  print(a.func());
+}
+
+var b = {
+ get func() {
+    var bCount = 0;
+    return function() {
+       return this.bCount++;
+    }
+ }
+};
+
+for (i = 0; i < 10; i++) {
+  print(b.func());
+}
+
+var cCount = 0;
+
+var c = {
+ get func() {
+    return function() {
+       return cCount++;
+    }
+ }
+};
+
+for (i = 0; i < 10; i++) {
+  print(c.func());
+}
diff --git a/nashorn/test/script/basic/getterfunc.js.EXPECTED b/nashorn/test/script/basic/getterfunc.js.EXPECTED
new file mode 100644
index 0000000..6f7769b
--- /dev/null
+++ b/nashorn/test/script/basic/getterfunc.js.EXPECTED
@@ -0,0 +1,30 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+NaN
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
diff --git a/nashorn/test/script/basic/gettersetter.js b/nashorn/test/script/basic/gettersetter.js
new file mode 100644
index 0000000..68106bc
--- /dev/null
+++ b/nashorn/test/script/basic/gettersetter.js
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+/**
+ * Getter/Setter test.
+ *
+ * @test
+ * @run 
+ */
+
+'use strict';
+
+var a = {
+            _x : "default",
+            get x() {
+                return this._x;
+            },
+            set x(x) {
+                this._x = x;
+            }
+        };
+        
+var b = {
+            _x : "default",
+            get x() {
+                return this._x;
+            }
+        };
+
+        
+var c = {
+            _x : "default",
+            set x(x) {
+                this._x = x;
+            }
+        };
+
+print(a._x);
+print(a.x);
+a.x = "new value";
+print(a._x);
+print(a.x);
+
+print(b._x);
+print(b.x);
+try {
+    b.x = "new value";
+} catch (e) {
+    print(e);
+}
+print(b._x);
+print(b.x);
+
+print(c._x);
+print(c.x);
+c.x = "new value";
+print(c._x);
+print(c.x);
diff --git a/nashorn/test/script/basic/gettersetter.js.EXPECTED b/nashorn/test/script/basic/gettersetter.js.EXPECTED
new file mode 100644
index 0000000..32f6657
--- /dev/null
+++ b/nashorn/test/script/basic/gettersetter.js.EXPECTED
@@ -0,0 +1,13 @@
+default
+default
+new value
+new value
+default
+default
+TypeError: Cannot set property "x" of [object Object] that has only a getter
+default
+default
+default
+undefined
+new value
+undefined
diff --git a/nashorn/test/script/basic/globalaccess.js b/nashorn/test/script/basic/globalaccess.js
new file mode 100644
index 0000000..6e18cfa
--- /dev/null
+++ b/nashorn/test/script/basic/globalaccess.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The following results in VerifyError. If foo is assigned with something
+ * other than number, it seems fine.
+ *
+ * @test
+ * @run
+ */
+
+foo = 3;
+
+func = function() {
+    this.bar = foo;
+};
+
+func();
+print(bar);
+
diff --git a/nashorn/test/script/basic/globalaccess.js.EXPECTED b/nashorn/test/script/basic/globalaccess.js.EXPECTED
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/nashorn/test/script/basic/globalaccess.js.EXPECTED
@@ -0,0 +1 @@
+3
diff --git a/nashorn/test/script/basic/globals.js b/nashorn/test/script/basic/globals.js
new file mode 100644
index 0000000..4e2b47f
--- /dev/null
+++ b/nashorn/test/script/basic/globals.js
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check global functions and properties.
+ *
+ * @test
+ * @run
+ */
+
+print(undefined);
+print(typeof(undefined));
+print(NaN);
+print(typeof(NaN));
+print(Infinity);
+print(typeof(Infinity));
+print(isNaN(NaN));
+print(isNaN(1.0));
+print(isNaN(0.0));
+print(isNaN(Infinity));
+print(isFinite(Math.PI));
+print(isFinite(Infinity));
+print(isFinite(NaN));
+print(parseInt("4345"));
+print(parseInt("100", 8));
+print(parseInt("ffff", 16));
+print(parseInt("0xffff"));
+print(parseInt("0xffff", 16));
+print(parseInt("0xffff", 8)); // should be NaN
+print(parseInt("")); // should be NaN
+print(parseInt("-")); // should be NaN
+print(parseInt("+")); // should be NaN
+print(parseInt("0x")); // should be NaN
+print(parseInt("0X")); // should be NaN
+print(parseInt("3.1415")); // should be "3" - ignore the not understood part
+print(parseInt("5654gjhkgjdfgk")); // should be "5654" - ignore invalid tail chars
+
+print(parseFloat("-Infinity"));
+print(parseFloat("+Infinity"));
+print(parseFloat("+3.14"));
+print(parseFloat("-3.14"));
+print(parseFloat("2.9e+8"));
+print(parseFloat("6.62E-34"));
+
+(function() {
+
+function checkProtoImmutable(obj) {
+    var attr = Object.getOwnPropertyDescriptor(this[obj], "prototype");
+    if (attr.writable) {
+        throw new Error(obj + ".prototype writable");
+    }
+    if (attr.enumerable) {
+        throw new Error(obj + ".prototype enumerable");
+    }
+    if (attr.configurable) {
+        throw new Error(obj + ".prototype configurable");
+    }
+}
+
+checkProtoImmutable("Array");
+checkProtoImmutable("Boolean");
+checkProtoImmutable("Date");
+checkProtoImmutable("Function");
+checkProtoImmutable("Number");
+checkProtoImmutable("Object");
+checkProtoImmutable("RegExp");
+checkProtoImmutable("String");
+
+})();
+
+// none of the built-in global properties are enumerable
+for (i in this) {
+    print(i);
+}
diff --git a/nashorn/test/script/basic/globals.js.EXPECTED b/nashorn/test/script/basic/globals.js.EXPECTED
new file mode 100644
index 0000000..33ed589
--- /dev/null
+++ b/nashorn/test/script/basic/globals.js.EXPECTED
@@ -0,0 +1,32 @@
+undefined
+undefined
+NaN
+number
+Infinity
+number
+true
+false
+false
+false
+true
+false
+false
+4345
+64
+65535
+65535
+65535
+0
+NaN
+NaN
+NaN
+NaN
+NaN
+3
+5654
+-Infinity
+Infinity
+3.14
+-3.14
+290000000
+6.62e-34
diff --git a/nashorn/test/script/basic/globalscope.js b/nashorn/test/script/basic/globalscope.js
new file mode 100644
index 0000000..7e87bdf
--- /dev/null
+++ b/nashorn/test/script/basic/globalscope.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * Global scope test.
+ *
+ * @test
+ * @run 
+ */
+
+var g = this;
+function func() {
+  var v = this;
+
+  function j() {
+    print(v === this);
+    print(g === this);
+  }
+
+  j();
+}
+
+func();
diff --git a/nashorn/test/script/basic/globalscope.js.EXPECTED b/nashorn/test/script/basic/globalscope.js.EXPECTED
new file mode 100644
index 0000000..bb101b6
--- /dev/null
+++ b/nashorn/test/script/basic/globalscope.js.EXPECTED
@@ -0,0 +1,2 @@
+true
+true
diff --git a/nashorn/test/script/basic/hello.js b/nashorn/test/script/basic/hello.js
new file mode 100644
index 0000000..19fca9f
--- /dev/null
+++ b/nashorn/test/script/basic/hello.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * Simple "hello world" test
+ *
+ * @test
+ * @run 
+ */
+
+print("hello world");
diff --git a/nashorn/test/script/basic/hello.js.EXPECTED b/nashorn/test/script/basic/hello.js.EXPECTED
new file mode 100644
index 0000000..3b18e51
--- /dev/null
+++ b/nashorn/test/script/basic/hello.js.EXPECTED
@@ -0,0 +1 @@
+hello world
diff --git a/nashorn/test/script/basic/herestr_operator.js b/nashorn/test/script/basic/herestr_operator.js
new file mode 100644
index 0000000..0e5b8af
--- /dev/null
+++ b/nashorn/test/script/basic/herestr_operator.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * << operator's operand can occur in new line.
+ *
+ * @test
+ * @run
+ */
+
+var
+x
+=
+100
+<<
+2
+;
+print(x);
+
diff --git a/nashorn/test/script/basic/herestr_operator.js.EXPECTED b/nashorn/test/script/basic/herestr_operator.js.EXPECTED
new file mode 100644
index 0000000..d411bb7
--- /dev/null
+++ b/nashorn/test/script/basic/herestr_operator.js.EXPECTED
@@ -0,0 +1 @@
+400
diff --git a/nashorn/test/script/basic/illegaljavaname.js b/nashorn/test/script/basic/illegaljavaname.js
new file mode 100644
index 0000000..20ccc5a
--- /dev/null
+++ b/nashorn/test/script/basic/illegaljavaname.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The following used to threw ClassFormatError -- "[foo]" is used as method name
+ * for a invokedynamic instruction and so resulted in ClassFormatError.
+ *
+ * @test
+ * @run
+ */
+
+var x = {};
+x["[foo]"] = 4;
+print(x["[foo]"]);
+
+x["foo.bar"] = "hello";
+print(x["foo.bar"]);
diff --git a/nashorn/test/script/basic/illegaljavaname.js.EXPECTED b/nashorn/test/script/basic/illegaljavaname.js.EXPECTED
new file mode 100644
index 0000000..cfb01bd
--- /dev/null
+++ b/nashorn/test/script/basic/illegaljavaname.js.EXPECTED
@@ -0,0 +1,2 @@
+4
+hello
diff --git a/nashorn/test/script/basic/importpackage.js b/nashorn/test/script/basic/importpackage.js
new file mode 100644
index 0000000..9a2b3a3
--- /dev/null
+++ b/nashorn/test/script/basic/importpackage.js
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test to check importPackage function.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    load("nashorn:mozilla_compat.js");
+} catch (e) {
+}
+
+importPackage(java.util);
+
+var m = new HashMap();
+if (!(m instanceof java.util.HashMap)) {
+    fail("expected 'm' to be a java.util.HashMap instance");
+}
+
+function checkJavaClass(cls) {
+    if (! Java.isType(cls)) {
+        fail(cls + " is not a Java class");
+    }
+}
+
+importPackage(java.lang.reflect, javax.script);
+checkJavaClass(Method);
+checkJavaClass(Field);
+checkJavaClass(Constructor);
+checkJavaClass(ScriptContext);
+checkJavaClass(ScriptEngine);
+
+var bindings = new SimpleBindings();
+if (!(bindings instanceof javax.script.SimpleBindings)) {
+    fail("expected 'bindings' to be a javax.script.SimpleBindings instance");
+}
diff --git a/nashorn/test/script/basic/incheck.js b/nashorn/test/script/basic/incheck.js
new file mode 100644
index 0000000..1571b62
--- /dev/null
+++ b/nashorn/test/script/basic/incheck.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Check that the expression ("property" in obj) works for own property as 
+ * well as properties 'inherited' from proto chain.
+ * 
+ * @test
+ * @run
+ */
+
+function MyCons() {
+    this.foo = "hello";
+}
+
+MyCons.prototype.func = function() { print("func " + this); }
+MyCons.prototype.num = 1729;
+
+var myObj = new MyCons();
+print("foo? " + ("foo" in myObj));
+print("func? " + ("func" in myObj));
+print("num? " + ("num" in myObj));
+// From Object.prototype
+print("toString?" + ("toString" in myObj));
+
+MyCons.prototype.sun = "a star";
+MyCons.prototype.earth = "a planet";
+
+print("foo? " + ("foo" in myObj));
+print("func? " + ("func" in myObj));
+print("num? " + ("num" in myObj));
+print("sun? " + ("sun" in myObj));
+print("earth? " + ("earth" in myObj));
+print("toString? " + ("toString" in myObj));
diff --git a/nashorn/test/script/basic/incheck.js.EXPECTED b/nashorn/test/script/basic/incheck.js.EXPECTED
new file mode 100644
index 0000000..479d647
--- /dev/null
+++ b/nashorn/test/script/basic/incheck.js.EXPECTED
@@ -0,0 +1,10 @@
+foo? true
+func? true
+num? true
+toString?true
+foo? true
+func? true
+num? true
+sun? true
+earth? true
+toString? true
diff --git a/nashorn/test/script/basic/indexedcall.js b/nashorn/test/script/basic/indexedcall.js
new file mode 100644
index 0000000..b3f651b
--- /dev/null
+++ b/nashorn/test/script/basic/indexedcall.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Convert func["name"]() to func.name() test
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    print("func");
+}
+
+this["func"]();
diff --git a/nashorn/test/script/basic/indexedcall.js.EXPECTED b/nashorn/test/script/basic/indexedcall.js.EXPECTED
new file mode 100644
index 0000000..415b9ac
--- /dev/null
+++ b/nashorn/test/script/basic/indexedcall.js.EXPECTED
@@ -0,0 +1 @@
+func
diff --git a/nashorn/test/script/basic/info.js b/nashorn/test/script/basic/info.js
new file mode 100644
index 0000000..958572c
--- /dev/null
+++ b/nashorn/test/script/basic/info.js
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Tests INFO access
+ *
+ * @test
+ * @run
+ */
+
+print(java.util.logging.Level.INFO);
+
diff --git a/nashorn/test/script/basic/info.js.EXPECTED b/nashorn/test/script/basic/info.js.EXPECTED
new file mode 100644
index 0000000..4924e23
--- /dev/null
+++ b/nashorn/test/script/basic/info.js.EXPECTED
@@ -0,0 +1 @@
+INFO
diff --git a/nashorn/test/script/basic/inherited_nonwritable.js b/nashorn/test/script/basic/inherited_nonwritable.js
new file mode 100644
index 0000000..c794332
--- /dev/null
+++ b/nashorn/test/script/basic/inherited_nonwritable.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Inherited non-writable properties can not be overridden.
+ *
+ * @test
+ * @run
+ */
+
+var p = {};
+Object.defineProperty(p, "foo", { writable: false, value: 12 });
+
+var o = Object.create(p);
+o.foo = 44;
+if (o.foo !== 12) {
+    fail("o.foo can be overridden");
+}
+
+
diff --git a/nashorn/test/script/basic/instanceof.js b/nashorn/test/script/basic/instanceof.js
new file mode 100644
index 0000000..31878b5
--- /dev/null
+++ b/nashorn/test/script/basic/instanceof.js
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+/**
+ * Verify instanceof operator.
+ *
+ * @test
+ * @run
+ */
+
+var b = new Boolean(true);
+var s = new String("hello");
+var r = /java/;
+
+function MyConstructor(fooval) {
+   this.foo = fooval;
+}
+
+var c = new MyConstructor("world");
+
+print(b instanceof Boolean);
+print(b instanceof String);
+print(b instanceof RegExp);
+print(b instanceof MyConstructor);
+print("------");
+
+print(s instanceof Boolean);
+print(s instanceof String);
+print(s instanceof RegExp);
+print(s instanceof MyConstructor);
+print("------");
+
+print(r instanceof Boolean);
+print(r instanceof String);
+print(r instanceof RegExp);
+print(r instanceof MyConstructor);
+print("------");
+
+print(c instanceof Boolean);
+print(c instanceof String);
+print(c instanceof RegExp);
+print(c instanceof MyConstructor);
+print("------");
+
+var b = new Boolean(true);
+print(b instanceof Boolean);
diff --git a/nashorn/test/script/basic/instanceof.js.EXPECTED b/nashorn/test/script/basic/instanceof.js.EXPECTED
new file mode 100644
index 0000000..7536578
--- /dev/null
+++ b/nashorn/test/script/basic/instanceof.js.EXPECTED
@@ -0,0 +1,21 @@
+true
+false
+false
+false
+------
+false
+true
+false
+false
+------
+false
+false
+true
+false
+------
+false
+false
+false
+true
+------
+true
diff --git a/nashorn/test/script/basic/instanceof2.js b/nashorn/test/script/basic/instanceof2.js
new file mode 100644
index 0000000..a6c07c2
--- /dev/null
+++ b/nashorn/test/script/basic/instanceof2.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * Instanceof test.
+ *
+ * @test
+ * @run 
+ */
+
+var x = { a: 1, b: "string", c: [1, 2, 3], d: function() {} };
+
+var MyObject = function() {
+    this.a = 10;
+}
+
+var y = new MyObject();
+
+print(x instanceof Object);
+print(x.a instanceof Object);
+print(x.b instanceof Object);
+print(x.c instanceof Object);
+print(x.c instanceof Array);
+print(x.d instanceof Object);
+print(x.d instanceof Function);
+print(y instanceof Object);
+
+
diff --git a/nashorn/test/script/basic/instanceof2.js.EXPECTED b/nashorn/test/script/basic/instanceof2.js.EXPECTED
new file mode 100644
index 0000000..8aba8cb
--- /dev/null
+++ b/nashorn/test/script/basic/instanceof2.js.EXPECTED
@@ -0,0 +1,8 @@
+true
+false
+false
+true
+true
+true
+true
+true
diff --git a/nashorn/test/script/basic/interfaces.js b/nashorn/test/script/basic/interfaces.js
new file mode 100644
index 0000000..1c42e9d
--- /dev/null
+++ b/nashorn/test/script/basic/interfaces.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Implement Java interface using script functions.
+ *
+ * @test
+ * @run
+ */
+
+// implement java.lang.Runnable interface 
+var runnable = new java.lang.Runnable({
+    run: function() {
+        print("Inside run function");
+    }
+});
+
+// now call 'run' method on interface
+runnable.run();
+
+// The following sytax sugar is also fine..
+
+var callable = new java.util.concurrent.Callable() {
+   call: function() {
+       print("This is Callable.call");
+       return "called";
+   }
+};
+
+print(callable.call());
diff --git a/nashorn/test/script/basic/interfaces.js.EXPECTED b/nashorn/test/script/basic/interfaces.js.EXPECTED
new file mode 100644
index 0000000..f916954
--- /dev/null
+++ b/nashorn/test/script/basic/interfaces.js.EXPECTED
@@ -0,0 +1,3 @@
+Inside run function
+This is Callable.call
+called
diff --git a/nashorn/test/script/basic/iterator.js b/nashorn/test/script/basic/iterator.js
new file mode 100644
index 0000000..0b70db4
--- /dev/null
+++ b/nashorn/test/script/basic/iterator.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * Verify that basic for..in works for objects, arrays.
+ * 
+ * @test
+ * @run
+ */
+
+var obj = { foo: 33, bar: "hello" };
+
+for (i in obj) {
+    print(i);
+    print(obj[i]);
+}
+
+var arr = [4, 55, 66, 2];
+for (i in arr) {
+    print(i);
+    print(arr[i]);
+}
diff --git a/nashorn/test/script/basic/iterator.js.EXPECTED b/nashorn/test/script/basic/iterator.js.EXPECTED
new file mode 100644
index 0000000..ca21e8c
--- /dev/null
+++ b/nashorn/test/script/basic/iterator.js.EXPECTED
@@ -0,0 +1,12 @@
+foo
+33
+bar
+hello
+0
+4
+1
+55
+2
+66
+3
+2
diff --git a/nashorn/test/script/basic/java.js b/nashorn/test/script/basic/java.js
new file mode 100644
index 0000000..b3aaea1
--- /dev/null
+++ b/nashorn/test/script/basic/java.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * Java object test
+ *
+ * @test
+ * @run
+ */
+
+print(Packages);
+print(Packages.java);
+print(java);
+print(java.lang);
+print(java.lang.String);
+var System = java.lang.System;
+print(System);
+print(123);
+print(java.lang.String.format("%4d %4d", 12, 1));
+var StringBuffer = java.lang.StringBuffer;
+print(StringBuffer);
+var stringBuffer = new StringBuffer();
+stringBuffer.append("abc");
+stringBuffer.append("def");
+print(stringBuffer.toString());
+print(java.lang.Double.toString(3.14));
+print(java.lang.Float.toString(23428.34));
diff --git a/nashorn/test/script/basic/java.js.EXPECTED b/nashorn/test/script/basic/java.js.EXPECTED
new file mode 100644
index 0000000..507d1da
--- /dev/null
+++ b/nashorn/test/script/basic/java.js.EXPECTED
@@ -0,0 +1,12 @@
+[JavaPackage ]
+[JavaPackage java]
+[JavaPackage java]
+[JavaPackage java.lang]
+[JavaClass java.lang.String]
+[JavaClass java.lang.System]
+123
+  12    1
+[JavaClass java.lang.StringBuffer]
+abcdef
+3.14
+23428.34
diff --git a/nashorn/test/script/basic/javaadapter.js b/nashorn/test/script/basic/javaadapter.js
new file mode 100644
index 0000000..484a5d2
--- /dev/null
+++ b/nashorn/test/script/basic/javaadapter.js
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test to check JavaAdapter constructor.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    load("nashorn:mozilla_compat.js");
+} catch (e) {
+}
+
+// try various JavaAdapter cases
+
+// Single interface
+var runReached = false;
+var r = new JavaAdapter(java.lang.Runnable) {
+    run: function() {
+        runReached = true;
+    }
+};
+
+r.run();
+if (! runReached) {
+    fail("run was not called");
+}
+
+if (! (r instanceof java.lang.Runnable)) {
+    fail("r is not a Runnable");
+}
+
+// Multiple intefaces
+var runReached = false;
+var actionPerformedReached = false;
+
+var obj = new JavaAdapter(java.awt.event.ActionListener, java.lang.Runnable) {
+    actionPerformed : function(e) {
+        actionPerformedReached = true;
+    },
+
+    run: function() {
+        runReached = true;
+    }
+};
+
+obj.actionPerformed(null);
+if (! actionPerformedReached) {
+    fail("actionPerformed was not called");
+}
+
+obj.run();
+if (! runReached) {
+    fail("run was not called");
+}
+
+if (! (obj instanceof java.lang.Runnable)) {
+    fail("obj is not a Runnable");
+}
+
+if (! (obj instanceof java.awt.event.ActionListener)) {
+    fail("obj is not an ActionListener");
+}
+
+// Single class
+var obj = new JavaAdapter(java.lang.Object) {
+    toString: function() { return "I am an Object"; }
+};
+
+if (! (obj instanceof java.lang.Object)) {
+    fail("obj is not an instance of java.lang.Object");
+}
+
+if (obj.toString() != "I am an Object") {
+    fail("Object.toString did not get called");
+}
+
+// Single class and single interface
+var runReached = false;
+var obj = new JavaAdapter(java.lang.Object, java.lang.Runnable) {
+    run: function() {
+        runReached = true;
+    },
+
+    hashCode: function() {
+        return 12;
+    }
+};
+
+obj.run();
+if (! runReached) {
+    fail("run was not called");
+}
+
+if (obj.hashCode() != 12) {
+    fail("hashCode does not return 12");
+}
diff --git a/nashorn/test/script/basic/javaarray.js b/nashorn/test/script/basic/javaarray.js
new file mode 100644
index 0000000..389b953
--- /dev/null
+++ b/nashorn/test/script/basic/javaarray.js
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/*
+ * Basic check for Java array element access and array element set.
+ *
+ * @test
+ * @run
+ */
+
+(function() {
+    var nargs = arguments.length;
+    var args = java.lang.reflect.Array.newInstance(java.lang.Object.class, nargs);
+    print(args.length);
+    for (var i = 0; i < nargs; i++) {
+        var arg = arguments[i];
+        args[i] = arg;
+        print(i + ' ' + arg + '/' + args[i]);
+    }
+})(13, 3.14, 'foo');
+
+var z; // undefined
+
+var intArray = java.lang.reflect.Array.newInstance(java.lang.Integer.TYPE, 1);
+intArray[0] = 10;
+print(intArray[0]);
+print(intArray.length);
+intArray[0] = z;
+print(intArray[0]);
+intArray[0] = 10.1;
+print(intArray[0]);
+
+var boolArray = java.lang.reflect.Array.newInstance(java.lang.Boolean.TYPE, 2);
+boolArray[0] = true;
+print(boolArray[0]);
+print(boolArray[1]);
+print(boolArray.length);
+
+var charArray = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1);
+charArray[0] = 'j';
+print(charArray[0]);
+print(charArray.length);
+
+
+var doubleArray = java.lang.reflect.Array.newInstance(java.lang.Double.TYPE, 1)
+doubleArray[0]=z
+print(doubleArray[0])
+doubleArray[0]=1
+print(doubleArray[0])
+doubleArray[0]=1.1
+print(doubleArray[0])
diff --git a/nashorn/test/script/basic/javaarray.js.EXPECTED b/nashorn/test/script/basic/javaarray.js.EXPECTED
new file mode 100644
index 0000000..b483acc
--- /dev/null
+++ b/nashorn/test/script/basic/javaarray.js.EXPECTED
@@ -0,0 +1,16 @@
+3
+0 13/13
+1 3.14/3.14
+2 foo/foo
+10
+1
+0
+10
+true
+false
+2
+j
+1
+NaN
+1
+1.1
\ No newline at end of file
diff --git a/nashorn/test/script/basic/javaarrayconversion.js b/nashorn/test/script/basic/javaarrayconversion.js
new file mode 100644
index 0000000..34e2f95
--- /dev/null
+++ b/nashorn/test/script/basic/javaarrayconversion.js
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Tests for conversion of JavaScript arrays to Java arrays and the other
+ * way round. Also generally useful as a JavaScript-to-Java type conversion 
+ * test.
+ *
+ * @test
+ * @run
+ */
+
+var x; // used for undefined
+var testCount = 0;
+
+function testF(inputValue, type, testFn) {
+  var x = Java.toJavaArray([inputValue], type)[0];
+  if(!testFn(x)) {
+    throw ("unexpected value: " + x)
+  }
+  ++testCount;
+}
+
+function test(inputValue, type, expectedValue) {
+  testF(inputValue, type, function(x) { return x === expectedValue })
+}
+
+function testNaN(inputValue, type) {
+  testF(inputValue, type, isNaN)
+}
+
+// Those labeled "Correct?" are not clearly correct conversions. Those 
+// labeled "TypeError maybe?" could actually throw a TypeError, or only 
+// throw a TypeError when in strict mode. 
+// The case of ("false", "boolean") => true is particularly amusing.
+
+test(x, "int", 0) // Correct? TypeError maybe?
+test(null, "int", 0) // Correct? TypeError maybe?
+test(1234, "int", 1234)
+test("1234", "int", 1234)
+test("1234.49", "int", 1234)
+test("1234.51", "int", 1234) // truncates, not rounds
+test(true, "int", 1)
+test(false, "int", 0)
+test("foo", "int", 0) // Correct? TypeError maybe?
+
+test(x, "boolean", false) // Correct? TypeError maybe?
+test(null, "boolean", false) // Correct? TypeError maybe?
+test(0, "boolean", false)
+test(1234, "boolean", true)
+test("foo", "boolean", true)
+test("", "boolean", false)
+test("false", "boolean", true) // Correct? false maybe?
+
+test(x, "java.lang.String", "undefined") // Correct? TypeError maybe?
+test(null, "java.lang.String", null)
+test(1234, "java.lang.String", "1234")
+test(1234.5, "java.lang.String", "1234.5")
+test(true, "java.lang.String", "true")
+test(false, "java.lang.String", "false")
+
+test(x, "java.lang.Integer", null) // Correct? TypeError maybe?
+test(null, "java.lang.Integer", null)
+test(1234, "java.lang.Integer", 1234)
+test("1234", "java.lang.Integer", 1234)
+test("1234.49", "java.lang.Integer", 1234)
+test("1234.51", "java.lang.Integer", 1234) // truncates, not rounds
+test(true, "java.lang.Integer", 1)
+test(false, "java.lang.Integer", 0)
+test("foo", "java.lang.Integer", 0) // Correct? TypeError maybe?
+
+test(x, "java.lang.Boolean", null) // Correct? TypeError maybe?
+test(null, "java.lang.Boolean", null)
+test(0, "java.lang.Boolean", false)
+test(1234, "java.lang.Boolean", true)
+test("foo", "java.lang.Boolean", true)
+test("", "java.lang.Boolean", false)
+test("false", "java.lang.Boolean", true) // Correct? false maybe?
+
+testNaN(x, "double")
+test(null, "double", 0)
+test(1234, "double", 1234)
+test("1234", "double", 1234)
+test("1234.5", "double", 1234.5)
+test(true, "double", 1)
+test(false, "double", 0)
+testNaN("foo", "double")
+
+testNaN(x, "java.lang.Double")
+test(null, "java.lang.Double", null)
+test(1234, "java.lang.Double", 1234)
+test("1234", "java.lang.Double", 1234)
+test("1234.5", "java.lang.Double", 1234.5)
+test(true, "java.lang.Double", 1)
+test(false, "java.lang.Double", 0)
+testNaN("foo", "java.lang.Double")
+
+test({ valueOf: function() { return 42; } }, "int", 42)
+test({ valueOf: function() { return "42"; } }, "int", 42)
+// If there's no valueOf, toString is used
+test({ toString: function() { return "42"; } }, "int", 42)
+// For numbers, valueOf takes precedence over toString
+test({ valueOf: function() { return "42"; },  toString: function() { return "43"; } }, "int", 42)
+
+test({ toString: function() { return "foo"; } }, "java.lang.String", "foo")
+// Yep, even if we have valueOf, toString from prototype takes precedence
+test({ valueOf: function() { return 42; } }, "java.lang.String", "[object Object]")
+// Converting to string, toString takes precedence over valueOf
+test({ valueOf: function() { return "42"; },  toString: function() { return "43"; } }, "java.lang.String", "43")
+
+function assertCantConvert(sourceType, targetType) {
+  try {
+    Java.toJavaArray([new Java.type(sourceType)()], targetType)
+    throw "no TypeError encountered"
+  } catch(e) {
+      if(!(e instanceof TypeError)) {
+        throw e;
+      }
+      ++testCount;
+  }
+}
+
+// Arbitrary POJOs can't be converted to Java values
+assertCantConvert("java.util.BitSet", "int")
+assertCantConvert("java.util.BitSet", "double")
+assertCantConvert("java.util.BitSet", "long")
+assertCantConvert("java.util.BitSet", "boolean")
+assertCantConvert("java.util.BitSet", "java.lang.String")
+assertCantConvert("java.util.BitSet", "java.lang.Double")
+assertCantConvert("java.util.BitSet", "java.lang.Long")
+
+/***************************************************************************
+ * Now testing the other way round - Java arrays & collections to JavaScript
+ **************************************************************************/
+
+function assert(x) {
+  if(!x) {
+    throw "Assertion failed"
+  }
+  ++testCount;
+}
+
+var intArray = new (Java.type("int[]"))(3)
+intArray[0] = 1234;
+intArray[1] = 42;
+intArray[2] = 5;
+var jsIntArray = Java.toJavaScriptArray(intArray)
+assert(jsIntArray instanceof Array);
+assert(jsIntArray[0] === 1234);
+assert(jsIntArray[1] === 42);
+assert(jsIntArray[2] === 5);
+
+// The arrays are copies, they don't reflect each other
+intArray[2] = 6;
+assert(jsIntArray[2] === 5);
+jsIntArray[2] = 7;
+assert(intArray[2] === 6);
+
+var byteArray = new (Java.type("byte[]"))(2)
+byteArray[0] = -128;
+byteArray[1] = 127;
+var jsByteArray = Java.toJavaScriptArray(byteArray)
+assert(jsByteArray instanceof Array);
+assert(jsByteArray[0] === -128);
+assert(jsByteArray[1] === 127);
+
+var shortArray = new (Java.type("short[]"))(2)
+shortArray[0] = -32768;
+shortArray[1] = 32767;
+var jsShortArray = Java.toJavaScriptArray(shortArray)
+assert(jsShortArray instanceof Array);
+assert(jsShortArray[0] === -32768);
+assert(jsShortArray[1] === 32767);
+
+var floatArray = new (Java.type("float[]"))(2)
+floatArray[0] = java.lang.Float.MIN_VALUE;
+floatArray[1] = java.lang.Float.MAX_VALUE;
+var jsFloatArray = Java.toJavaScriptArray(floatArray)
+assert(jsFloatArray instanceof Array);
+assert(jsFloatArray[0] == java.lang.Float.MIN_VALUE);
+assert(jsFloatArray[1] == java.lang.Float.MAX_VALUE);
+
+var charArray = new (Java.type("char[]"))(3)
+charArray[0] = "a";
+charArray[1] = "b";
+charArray[2] = "1";
+var jsCharArray = Java.toJavaScriptArray(charArray)
+assert(jsCharArray instanceof Array);
+assert(jsCharArray[0] === 97);
+assert(jsCharArray[1] === 98);
+assert(jsCharArray[2] === 49);
+
+var booleanArray = new (Java.type("boolean[]"))(2)
+booleanArray[0] = true;
+booleanArray[1] = false;
+var jsBooleanArray = Java.toJavaScriptArray(booleanArray)
+assert(jsBooleanArray instanceof Array);
+assert(jsBooleanArray[0] === true);
+assert(jsBooleanArray[1] === false);
+
+print(testCount + " tests completed ok")
diff --git a/nashorn/test/script/basic/javaarrayconversion.js.EXPECTED b/nashorn/test/script/basic/javaarrayconversion.js.EXPECTED
new file mode 100644
index 0000000..341bd11
--- /dev/null
+++ b/nashorn/test/script/basic/javaarrayconversion.js.EXPECTED
@@ -0,0 +1 @@
+90 tests completed ok
diff --git a/nashorn/test/script/basic/javaexceptions.js b/nashorn/test/script/basic/javaexceptions.js
new file mode 100644
index 0000000..3f81f69
--- /dev/null
+++ b/nashorn/test/script/basic/javaexceptions.js
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic checks for throwing and catching java exceptions from script.
+ * 
+ * @test
+ * @run
+ */
+
+try {
+    new java.io.FileInputStream("non_existent_file");
+} catch (e) {
+    print(e instanceof java.io.FileNotFoundException || e instanceof java.lang.SecurityException);
+}
+
+try {
+    new java.net.URL("invalid_url");
+} catch (e) {
+    print(e instanceof java.net.MalformedURLException);
+    print(e);
+}
+
+try {
+    var obj = new java.lang.Object();
+    obj.wait();
+} catch (e) {
+    print(e instanceof java.lang.IllegalMonitorStateException);
+    print(e);
+}
+
+// directly throw a Java exception
+try {
+    throw new java.io.IOException("I/O failed");
+} catch (e) {
+    print(e instanceof java.io.IOException);
+    print(e);
+}
diff --git a/nashorn/test/script/basic/javaexceptions.js.EXPECTED b/nashorn/test/script/basic/javaexceptions.js.EXPECTED
new file mode 100644
index 0000000..2494cdb
--- /dev/null
+++ b/nashorn/test/script/basic/javaexceptions.js.EXPECTED
@@ -0,0 +1,7 @@
+true
+true
+java.net.MalformedURLException: no protocol: invalid_url
+true
+java.lang.IllegalMonitorStateException
+true
+java.io.IOException: I/O failed
diff --git a/nashorn/test/script/basic/javaimporter.js b/nashorn/test/script/basic/javaimporter.js
new file mode 100644
index 0000000..42551d1
--- /dev/null
+++ b/nashorn/test/script/basic/javaimporter.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic checks for "JavaImporter" constructor.
+ *
+ * @test
+ * @run
+ */
+
+var imports = new JavaImporter(java.util);
+var map;
+
+with(imports) {
+    map = new HashMap();
+    map.put("js", "javascript");
+    map.put("java", "java");
+    map.put("cpp", "c++");
+}
+
+print("js=" + map.get("js"));
+print("java=" + map.get("java"));
+print("cpp=" + map.get("cpp"));
+
+var imports2 = new JavaImporter(java.io, java.util); 
+with (imports2) {
+   print(File);
+}
diff --git a/nashorn/test/script/basic/javaimporter.js.EXPECTED b/nashorn/test/script/basic/javaimporter.js.EXPECTED
new file mode 100644
index 0000000..a38a11a
--- /dev/null
+++ b/nashorn/test/script/basic/javaimporter.js.EXPECTED
@@ -0,0 +1,4 @@
+js=javascript
+java=java
+cpp=c++
+[JavaClass java.io.File]
diff --git a/nashorn/test/script/basic/javainnerclasses.js b/nashorn/test/script/basic/javainnerclasses.js
new file mode 100644
index 0000000..df1e74d
--- /dev/null
+++ b/nashorn/test/script/basic/javainnerclasses.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * Java inner classes access
+ *
+ * @test
+ * @run
+ */
+ 
+// Do it with Java.type()
+var outer = new (Java.type("jdk.nashorn.internal.test.models.OuterClass"))("apple")
+print(outer)
+var innerStatic = new (Java.type("jdk.nashorn.internal.test.models.OuterClass$InnerStaticClass"))("orange")
+print(innerStatic)
+var innerNonStatic = new (Java.type("jdk.nashorn.internal.test.models.OuterClass$InnerNonStaticClass"))(outer, "pear")
+print(innerNonStatic)
+
+// Now do it with Packages and explicit $ names
+var outer = new Packages.jdk.nashorn.internal.test.models.OuterClass("red")
+print(outer)
+var innerStatic = new Packages.jdk.nashorn.internal.test.models.OuterClass$InnerStaticClass("green")
+print(innerStatic)
+var innerNonStatic = new Packages.jdk.nashorn.internal.test.models.OuterClass$InnerNonStaticClass(outer, "blue")
+print(innerNonStatic)
+
+// Now do it with Packages and nested properties
+var outer = new Packages.jdk.nashorn.internal.test.models.OuterClass("sweet")
+print(outer)
+var innerStatic = new Packages.jdk.nashorn.internal.test.models.OuterClass.InnerStaticClass("sour")
+print(innerStatic)
+var innerNonStatic = new Packages.jdk.nashorn.internal.test.models.OuterClass.InnerNonStaticClass(outer, "bitter")
+print(innerNonStatic)
diff --git a/nashorn/test/script/basic/javainnerclasses.js.EXPECTED b/nashorn/test/script/basic/javainnerclasses.js.EXPECTED
new file mode 100644
index 0000000..491975d
--- /dev/null
+++ b/nashorn/test/script/basic/javainnerclasses.js.EXPECTED
@@ -0,0 +1,9 @@
+OuterClass[value=apple]
+InnerStaticClass[value=orange]
+InnerNonStaticClass[value=pear, outer=OuterClass[value=apple]]
+OuterClass[value=red]
+InnerStaticClass[value=green]
+InnerNonStaticClass[value=blue, outer=OuterClass[value=red]]
+OuterClass[value=sweet]
+InnerStaticClass[value=sour]
+InnerNonStaticClass[value=bitter, outer=OuterClass[value=sweet]]
diff --git a/nashorn/test/script/basic/javamethodcallerrors.js b/nashorn/test/script/basic/javamethodcallerrors.js
new file mode 100644
index 0000000..4610900
--- /dev/null
+++ b/nashorn/test/script/basic/javamethodcallerrors.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * Expect TypeError on wrong Java method invocations.
+ *
+ * @test
+ * @run
+ */
+
+var Exit = java.lang.System.exit;
+
+// Try to invoke it as constructor
+try {
+    new Exit();
+    fail("Should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("TypeError expected, got " + e);
+    }
+}
+
+// Try to invoke with wrong number of args
+
+try {
+    Exit(33, 44);
+    fail("Should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("TypeError expected, got " + e);
+    }
+}
diff --git a/nashorn/test/script/basic/javasigcall.js b/nashorn/test/script/basic/javasigcall.js
new file mode 100644
index 0000000..c1a2df7
--- /dev/null
+++ b/nashorn/test/script/basic/javasigcall.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * Exact java method call - user specifies full method signature.
+ *
+ * @test
+ * @run
+ */
+
+var map = new java.util.HashMap();
+
+map["put(java.lang.Object,java.lang.Object)"]("py", "python");
+map["put(java.lang.Object,java.lang.Object)"]("js", "javascript");
+
+// call without signature
+map["put"]("pl", "perl");
+print("py=" + map.get("py"));
+print("js=" + map.get("js"));
+print("pl=" + map.get("pl"));
+
+map["clear()"]();
+print(map);
+
+print(java.lang.Integer["valueOf(java.lang.String,int)"]("FF", 16));
+
diff --git a/nashorn/test/script/basic/javasigcall.js.EXPECTED b/nashorn/test/script/basic/javasigcall.js.EXPECTED
new file mode 100644
index 0000000..c58e18d
--- /dev/null
+++ b/nashorn/test/script/basic/javasigcall.js.EXPECTED
@@ -0,0 +1,5 @@
+py=python
+js=javascript
+pl=perl
+{}
+255
diff --git a/nashorn/test/script/basic/jquery.js b/nashorn/test/script/basic/jquery.js
new file mode 100644
index 0000000..f88d94b
--- /dev/null
+++ b/nashorn/test/script/basic/jquery.js
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/**
+ * jquery : parse and generate jQuery code / minimum version
+ *
+ * @test
+ * @runif external.jquery
+ */
+
+var urls = [
+	    'http://code.jquery.com/jquery-1.7.2.min.js',
+	    'http://code.jquery.com/jquery-1.7.2.js'
+	    ];
+	    
+function test_jquery(url) {
+    
+    //bug one repro - this should compile
+    function a() {
+	var c;
+	if (func1(zz) || (c = func2(zz)) ) {
+	    if (c) {
+	    } 
+	} 
+	return target;
+    }
+    
+    //bug two repro - this should compile
+    function b() {
+	return ((v ? i : "") + "str");
+    }
+    
+    function checkWindow(e) {
+	if (e instanceof ReferenceError && e.toString().indexOf('window') != -1) {
+	    return;
+	}
+	throw e;
+    }
+    
+    var name;
+    
+    try {    
+	var split = url.split('/');
+	name = split[split.length - 1];
+	var path  = __DIR__ + "../external/jquery/" + name;
+	try {
+	    load(path);
+	} catch (e) {
+	    checkWindow(e);
+	}
+    } catch (e) {
+	print("Unexpected exception " + e);
+    }
+    
+    print("done " + name);
+}
+
+for each (url in urls) {
+    test_jquery(url);
+}
+
diff --git a/nashorn/test/script/basic/jquery.js.EXPECTED b/nashorn/test/script/basic/jquery.js.EXPECTED
new file mode 100644
index 0000000..0df6ebf
--- /dev/null
+++ b/nashorn/test/script/basic/jquery.js.EXPECTED
@@ -0,0 +1,2 @@
+done jquery-1.7.2.min.js
+done jquery-1.7.2.js
diff --git a/nashorn/test/script/basic/jsadapter.js b/nashorn/test/script/basic/jsadapter.js
new file mode 100644
index 0000000..9fe80ad
--- /dev/null
+++ b/nashorn/test/script/basic/jsadapter.js
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * 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.
+ */
+
+/**
+ * Verify that JSAdapter works as expected.
+ *
+ * @test
+ * @run
+ */
+
+var obj = new JSAdapter() {
+    __get__: function(name) {
+        print("getter called for '" + name + "'"); return name;
+    },
+
+    __put__: function(name, value) {
+        print("setter called for '" + name + "' with " + value);
+    },
+
+    __call__: function(name, arg1, arg2) {
+        print("method '" + name + "' called with " + arg1 + ", " + arg2);
+    },
+
+    __new__: function(arg1, arg2) {
+        print("new with " + arg1 + ", " + arg2);
+    },
+
+    __getIds__: function() {
+        print("__getIds__ called");
+        return [ "foo", "bar" ];
+    },
+
+    __getValues__: function() {
+        print("__getValues__ called");
+        return [ "fooval", "barval" ];
+    },
+
+    __has__: function(name) {
+        print("__has__ called with '" + name + "'");
+        return name == "js";
+    },
+
+    __delete__: function(name) {
+        print("__delete__ called with '" + name + "'");
+        return true;
+    }
+};
+
+// calls __get__
+print(obj.foo);
+
+// calls __put__
+obj.foo = 33;
+
+// calls __call__
+obj.func("hello", "world");
+
+// calls __new__
+new obj("hey!", "it works!");
+
+for (i in obj) {
+    print(i);
+}
+
+for each (i in obj) {
+    print(i);
+}
+
+var x = "foo" in obj;
+print(x);
+
+var y = "js" in obj;
+print(y);
+
+print(delete obj.prop);
+
+print(obj["js"]);
+obj["js"] = "javascript";
+print(obj["javascript"]);
diff --git a/nashorn/test/script/basic/jsadapter.js.EXPECTED b/nashorn/test/script/basic/jsadapter.js.EXPECTED
new file mode 100644
index 0000000..a8cdd33
--- /dev/null
+++ b/nashorn/test/script/basic/jsadapter.js.EXPECTED
@@ -0,0 +1,22 @@
+getter called for 'foo'
+foo
+setter called for 'foo' with 33
+method 'func' called with hello, world
+new with hey!, it works!
+__getIds__ called
+foo
+bar
+__getValues__ called
+fooval
+barval
+__has__ called with 'foo'
+false
+__has__ called with 'js'
+true
+__delete__ called with 'prop'
+true
+getter called for 'js'
+js
+setter called for 'js' with javascript
+getter called for 'javascript'
+javascript
diff --git a/nashorn/test/script/basic/jsadapterlink.js b/nashorn/test/script/basic/jsadapterlink.js
new file mode 100644
index 0000000..15117b3
--- /dev/null
+++ b/nashorn/test/script/basic/jsadapterlink.js
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/*
+ * Test that JSAdapter linking works as expected under receiver and/or
+ * adaptee change.
+ *
+ * @test
+ * @run
+ */
+
+var js1 = new JSAdapter() {
+    __get__: function(name) {
+        return "js1->" + name;
+    }
+};
+
+var js2 = new JSAdapter() {
+    __get__: function(name) {
+        return "js2->" + name;
+    }
+};
+
+var js3 = new JSAdapter() {
+    __get__: function(name) {
+        return "js3->" + name;
+    }
+};
+
+var handler = {
+    __get__: function(name) {
+        return "handler->" + name;
+    }
+};
+
+var js4 = new JSAdapter(handler);
+
+var arr = [ js1, js2, js3, js4, js1, js2, js3, js4 ];
+for (i in arr) {
+    if (i == 7) {
+        handler.__get__ = function(name) {
+            return "all-new-handler->" + name;
+        }
+    }
+    print(arr[i].foo);
+}
+
diff --git a/nashorn/test/script/basic/jsadapterlink.js.EXPECTED b/nashorn/test/script/basic/jsadapterlink.js.EXPECTED
new file mode 100644
index 0000000..daa16f0
--- /dev/null
+++ b/nashorn/test/script/basic/jsadapterlink.js.EXPECTED
@@ -0,0 +1,8 @@
+js1->foo
+js2->foo
+js3->foo
+handler->foo
+js1->foo
+js2->foo
+js3->foo
+all-new-handler->foo
diff --git a/nashorn/test/script/basic/jsobject.js b/nashorn/test/script/basic/jsobject.js
new file mode 100644
index 0000000..fd544d9
--- /dev/null
+++ b/nashorn/test/script/basic/jsobject.js
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+/**
+ * JSObject tests
+ *
+ * @test
+ * @run
+ */
+
+var m = new javax.script.ScriptEngineManager();
+var e = m.getEngineByName("nashorn");
+
+e.eval("obj = { foo:'hello', 0: 'world', func: function(x) { return x.toUpperCase() } } ");
+var obj = e.get("obj");
+
+
+// try various getters
+if (obj.foo != 'hello') {
+    fail("obj.foo does have expected value");
+}
+
+function checkPropGetter(obj, prop, expected) {
+    if (obj[prop] != expected) {
+        fail(prop + " does not have value: " + expected);
+    }
+}
+
+checkPropGetter(obj, "foo", "hello");
+checkPropGetter(obj, 0, "world");
+checkPropGetter(obj, "0", "world");
+
+// try various setters
+
+obj.foo = "HELLO";
+if (obj.foo != "HELLO") {
+    fail("obj.foo set does not work as expected");
+}
+
+function checkPropSetter(obj, prop, newValue) {
+    obj[prop] = newValue;
+    checkPropGetter(obj, prop, newValue);
+}
+
+checkPropSetter(obj, "foo", "NASHORN");
+checkPropSetter(obj, 0, "ECMASCRIPT");
+checkPropSetter(obj, "0", "CHANGED");
+
+function callFunc(input, expected) {
+   if (obj.func(input) != expected) {
+       fail("obj.func(..) does not work as expected");
+   }
+}
+
+callFunc("nashorn", "NASHORN");
+callFunc("javascript", "JAVASCRIPT");
+callFunc("hello", "HELLO");
+
+var Func = obj.func;
+
+function callWithoutObject(input, expected) {
+   if (Func(input) != expected) {
+       fail("obj.func(..) does not work as expected");
+   }
+}
+
+callWithoutObject("nashorn", "NASHORN");
+callWithoutObject("javascript", "JAVASCRIPT");
+callWithoutObject("hello", "HELLO");
diff --git a/nashorn/test/script/basic/json.js b/nashorn/test/script/basic/json.js
new file mode 100644
index 0000000..72391ff
--- /dev/null
+++ b/nashorn/test/script/basic/json.js
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * Verify basic JSON parsing using JSON.parse method.
+ *
+ * @test
+ * @run
+ */
+
+var obj = JSON.parse('{ "foo" : 44, "bar": "hello",  "arr": [42, 56, 78], "address" : { "city" : "chennai", "country": "India" } }');
+print(obj.foo);
+print(obj.bar);
+print(obj.arr.length);
+for (i in obj.arr) {
+   print(obj.arr[i]);
+}
+print(obj.address.city);
+print(obj.address.country);
+
+function reviver(name, value) {
+   if (name == "") return value;
+   print(name + " = " + value);
+   return value;
+}
+
+var obj2 = JSON.parse('{ "foo" : 44, "bar" : "hello" }', reviver);
+print(obj2.foo);
+print(obj2.bar);
+
+print(JSON.stringify(obj));
+print(JSON.stringify(obj2));
+
+try { 
+    JSON.parse('{ "foo" /*comment */ : 44, "bar" : "hello" }', reviver);
+    print("Fail!");
+} catch (e) {
+    if (!(e instanceof SyntaxError)) {
+	print("Comments are illegal in JSON. Should throw SyntaxError, not " + e);
+    }
+}
+print("Success!");
diff --git a/nashorn/test/script/basic/json.js.EXPECTED b/nashorn/test/script/basic/json.js.EXPECTED
new file mode 100644
index 0000000..88b2a8e
--- /dev/null
+++ b/nashorn/test/script/basic/json.js.EXPECTED
@@ -0,0 +1,15 @@
+44
+hello
+3
+42
+56
+78
+chennai
+India
+foo = 44
+bar = hello
+44
+hello
+{"foo":44,"bar":"hello","arr":[42,56,78],"address":{"city":"chennai","country":"India"}}
+{"foo":44,"bar":"hello"}
+Success!
diff --git a/nashorn/test/script/basic/list.js b/nashorn/test/script/basic/list.js
new file mode 100644
index 0000000..12e4071
--- /dev/null
+++ b/nashorn/test/script/basic/list.js
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Tests for java.util.List behavior in Nashorn
+ *
+ * @test
+ * @run
+ */
+var l = new java.util.ArrayList();
+print("l.class.name=" + l.class.name) // Has "class" property like any POJO
+
+l.add("foo")
+l.add("bar")
+
+print("l.length=" + l.length) // doesn't work, returns undefined
+print("l.size()=" + l.size()) // this will work
+
+print("l[0]=" + l[0])
+print("l[1]=" + l[1])
+
+print("--for each begin--")
+for each (i in l) {
+  print(i)
+}
+print("--for each end--")
+
+l[1] = "a"
+print("l[0]=" + l[0])
+print("l[1]=" + l[1])
+
+print("l[0.9]=" + l[0.9]) // non-integer indices don't round up
+print("l['blah']=" + l['blah']) // non-number indices don't retrieve anything...
+var size_name = "size"
+print("l[size_name]()=" + l[size_name]()) // ... but existing methods can be accessed with []
+
+expectException(2) // Java lists don't auto-expand to accommodate new indices
+expectException(java.lang.Double.POSITIVE_INFINITY) // Dynalink will throw IOOBE
+expectException(java.lang.Double.NEGATIVE_INFINITY) // Dynalink will throw IOOBE
+
+function expectException(index) {
+    try {
+        l[index] = "x"
+        print("Not caught out-of-bounds assignment for " + index)
+    }  catch(e) {
+        print(e)
+    }
+}
diff --git a/nashorn/test/script/basic/list.js.EXPECTED b/nashorn/test/script/basic/list.js.EXPECTED
new file mode 100644
index 0000000..18feade
--- /dev/null
+++ b/nashorn/test/script/basic/list.js.EXPECTED
@@ -0,0 +1,17 @@
+l.class.name=java.util.ArrayList
+l.length=undefined
+l.size()=2
+l[0]=foo
+l[1]=bar
+--for each begin--
+foo
+bar
+--for each end--
+l[0]=foo
+l[1]=a
+l[0.9]=null
+l['blah']=null
+l[size_name]()=2
+java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
+java.lang.IndexOutOfBoundsException: Index: Infinity, Size: 2
+java.lang.IndexOutOfBoundsException: Index: -Infinity, Size: 2
diff --git a/nashorn/test/script/basic/literal.js b/nashorn/test/script/basic/literal.js
new file mode 100644
index 0000000..2003c34
--- /dev/null
+++ b/nashorn/test/script/basic/literal.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Object literal test.
+ *
+ * @test
+ * @run 
+ */
+
+
+var x = { a: "string", "foo": 4343, 12: 12000 };
+
+print(x.a);
+print(x["foo"]);
+print(x.foo);
+print(x[12]);
+
diff --git a/nashorn/test/script/basic/literal.js.EXPECTED b/nashorn/test/script/basic/literal.js.EXPECTED
new file mode 100644
index 0000000..ad354dd
--- /dev/null
+++ b/nashorn/test/script/basic/literal.js.EXPECTED
@@ -0,0 +1,4 @@
+string
+4343
+4343
+12000
diff --git a/nashorn/test/script/basic/load.js b/nashorn/test/script/basic/load.js
new file mode 100644
index 0000000..4c8f9be
--- /dev/null
+++ b/nashorn/test/script/basic/load.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * Simple "hello world" load test
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "hello.js");
diff --git a/nashorn/test/script/basic/load.js.EXPECTED b/nashorn/test/script/basic/load.js.EXPECTED
new file mode 100644
index 0000000..3b18e51
--- /dev/null
+++ b/nashorn/test/script/basic/load.js.EXPECTED
@@ -0,0 +1 @@
+hello world
diff --git a/nashorn/test/script/basic/loadedfile.js b/nashorn/test/script/basic/loadedfile.js
new file mode 100644
index 0000000..dfc09a3
--- /dev/null
+++ b/nashorn/test/script/basic/loadedfile.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * @subtest
+ *
+ * Loaded by fileline.js
+ */
+
+var idx = __FILE__.lastIndexOf(java.io.File.separator);
+if (idx < 0) {
+    // separator is "/" when running under ant on windows
+    idx = __FILE__.lastIndexOf("/");
+}
+var file = (idx != -1)? __FILE__.substring(idx + 1) : __FILE__;
+print(file + " : " + __LINE__);
diff --git a/nashorn/test/script/basic/localundef.js b/nashorn/test/script/basic/localundef.js
new file mode 100644
index 0000000..0548492
--- /dev/null
+++ b/nashorn/test/script/basic/localundef.js
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * This test used to result in VerifierError: get long/double overflows locals.
+ * But, now expected output does not much. Getting NaN instead of undefined.
+ *
+ * @test
+ * @run
+ */
+
+function func(arg){
+    // initializing "x" with something removes VerifyError!
+    var x;
+    if (arg == 1) { 
+        return x;
+    } else {
+        x = 0;
+        // removing this print call removes VerifyError!
+        print(arg);
+        return x;
+    }
+}
+
+print(func(1));
+print(func(2));
diff --git a/nashorn/test/script/basic/localundef.js.EXPECTED b/nashorn/test/script/basic/localundef.js.EXPECTED
new file mode 100644
index 0000000..18127d2
--- /dev/null
+++ b/nashorn/test/script/basic/localundef.js.EXPECTED
@@ -0,0 +1,3 @@
+undefined
+2
+0
diff --git a/nashorn/test/script/basic/map.js b/nashorn/test/script/basic/map.js
new file mode 100644
index 0000000..2ab27ab
--- /dev/null
+++ b/nashorn/test/script/basic/map.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Tests for java.util.Map behavior in Nashorn
+ *
+ * @test
+ * @run
+ */
+var m = new (Java.type("java.util.LinkedHashMap"));
+print("m.class.name=" + m.class.name) // Has "class" property like any POJO
+
+var empty_key = "empty"
+
+print("m = " + m)
+print("m.empty = " + m.empty) // prints "true"
+print("m['empty'] = " + m['empty']) // prints "true"; item not found, default to property
+print("m[empty_key] = " + m[empty_key]) // prints "true"; item not found, default to property
+
+m.put("empty", "foo")
+
+print("m = " + m)
+print("m.empty = " + m.empty) // prints "false"
+print("m['empty'] = " + m['empty']) 
+print("m[empty_key] = " + m[empty_key]) // prints "foo"
+
+print("m.bwah = " + m.bwah) // prints "null"
+print("m['bwah'] = " + m['bwah']) // prints "null"
+
+m.put("twonk", "ding")
+print("m.twonk = " + m.twonk) // prints "ding"
+print("m['twonk'] = " + m['twonk']) // prints "ding"
+
+print("m.size()=" + m.size())
+
+print("--for each begin--")
+for each (i in m.keySet()) {
+  print(i)
+}
+print("--for each end--")
diff --git a/nashorn/test/script/basic/map.js.EXPECTED b/nashorn/test/script/basic/map.js.EXPECTED
new file mode 100644
index 0000000..471e86e
--- /dev/null
+++ b/nashorn/test/script/basic/map.js.EXPECTED
@@ -0,0 +1,18 @@
+m.class.name=java.util.LinkedHashMap
+m = {}
+m.empty = true
+m['empty'] = true
+m[empty_key] = true
+m = {empty=foo}
+m.empty = false
+m['empty'] = foo
+m[empty_key] = foo
+m.bwah = null
+m['bwah'] = null
+m.twonk = ding
+m['twonk'] = ding
+m.size()=2
+--for each begin--
+empty
+twonk
+--for each end--
diff --git a/nashorn/test/script/basic/math.js b/nashorn/test/script/basic/math.js
new file mode 100644
index 0000000..d6b34c4
--- /dev/null
+++ b/nashorn/test/script/basic/math.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic Math object tests.
+ *
+ * @test
+ * @run
+ */
+
+print(Math.E);
+print(Math.PI);
+print(Math.sqrt(2));
+print(Math.cos(Math.PI));
+print(Math.log(Math.cos(0)));
+
+var undef;
+
+print(undef + 10);
+print(undef - 10);
+print(undef / 10);
+print(undef * 10);
diff --git a/nashorn/test/script/basic/math.js.EXPECTED b/nashorn/test/script/basic/math.js.EXPECTED
new file mode 100644
index 0000000..b62ebfc
--- /dev/null
+++ b/nashorn/test/script/basic/math.js.EXPECTED
@@ -0,0 +1,9 @@
+2.718281828459045
+3.141592653589793
+1.4142135623730951
+-1
+0
+NaN
+NaN
+NaN
+NaN
diff --git a/nashorn/test/script/basic/minuszero.js b/nashorn/test/script/basic/minuszero.js
new file mode 100644
index 0000000..21c1cdf
--- /dev/null
+++ b/nashorn/test/script/basic/minuszero.js
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Tests with -0
+ *
+ * @test
+ * @run
+ */
+
+var mz = -0;
+print(mz);
+print(mz === -0);
+print(1/mz);
+
+var obj = {};
+obj.length = -0;
+print(obj.length);
+print(obj.length === -0);
+print(1/obj.length);
+
diff --git a/nashorn/test/script/basic/minuszero.js.EXPECTED b/nashorn/test/script/basic/minuszero.js.EXPECTED
new file mode 100644
index 0000000..3db4694
--- /dev/null
+++ b/nashorn/test/script/basic/minuszero.js.EXPECTED
@@ -0,0 +1,6 @@
+0
+true
+-Infinity
+0
+true
+-Infinity
diff --git a/nashorn/test/script/basic/module.js b/nashorn/test/script/basic/module.js
new file mode 100644
index 0000000..665e362
--- /dev/null
+++ b/nashorn/test/script/basic/module.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * This file is used by "main.js".
+ *
+ * @subtest
+ */
+
+function (exports) {
+  exports.func = function() {
+     print("module.func called");
+  }
+} 
diff --git a/nashorn/test/script/basic/moduleload.js b/nashorn/test/script/basic/moduleload.js
new file mode 100644
index 0000000..628bfa2
--- /dev/null
+++ b/nashorn/test/script/basic/moduleload.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * This loads "module.js" and calls the anonymous top-level function from it.
+ *
+ * @test
+ * @option --anon-functions
+ * @run
+ */
+
+var exports = {};
+var f = load(__DIR__ + "module.js");
+print(f);
+f(exports);
+exports.func();
diff --git a/nashorn/test/script/basic/moduleload.js.EXPECTED b/nashorn/test/script/basic/moduleload.js.EXPECTED
new file mode 100644
index 0000000..eb01049
--- /dev/null
+++ b/nashorn/test/script/basic/moduleload.js.EXPECTED
@@ -0,0 +1,6 @@
+function (exports) {
+  exports.func = function() {
+     print("module.func called");
+  }
+}
+module.func called
diff --git a/nashorn/test/script/basic/nashorn2.js b/nashorn/test/script/basic/nashorn2.js
new file mode 100644
index 0000000..d509a01
--- /dev/null
+++ b/nashorn/test/script/basic/nashorn2.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Regression:  NAS2 - lhs of index has no symbol.
+ *
+ * @test
+ * @run 
+ */
+ 
+
+var obj = { prop: [3, 4] };
+print(obj.prop[0]);
+obj.prop[0] = 44;
+print(obj.prop[0]);
diff --git a/nashorn/test/script/basic/nashorn2.js.EXPECTED b/nashorn/test/script/basic/nashorn2.js.EXPECTED
new file mode 100644
index 0000000..3dc014a
--- /dev/null
+++ b/nashorn/test/script/basic/nashorn2.js.EXPECTED
@@ -0,0 +1,2 @@
+3
+44
diff --git a/nashorn/test/script/basic/natives.js b/nashorn/test/script/basic/natives.js
new file mode 100644
index 0000000..60f9610
--- /dev/null
+++ b/nashorn/test/script/basic/natives.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Native object tests.
+ *
+ * @test
+ * @run
+ */
+ 
+var s = "abcded";
+var n = 1289.90;
+var b = true;
+
+print(s.toUpperCase());
+print(n.POSITIVE_INFINITY);
+print(b.toString());
diff --git a/nashorn/test/script/basic/natives.js.EXPECTED b/nashorn/test/script/basic/natives.js.EXPECTED
new file mode 100644
index 0000000..58de311
--- /dev/null
+++ b/nashorn/test/script/basic/natives.js.EXPECTED
@@ -0,0 +1,3 @@
+ABCDED
+undefined
+true
diff --git a/nashorn/test/script/basic/new.js b/nashorn/test/script/basic/new.js
new file mode 100644
index 0000000..25904b1
--- /dev/null
+++ b/nashorn/test/script/basic/new.js
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * new Function test.
+ *
+ * @test
+ * @run 
+ */
+
+function MyObject() {
+    this.x = 10;
+    this.y = "string";
+    this.z = function() {
+        return true;
+    }
+};
+
+var a = new MyObject();
+
+print(a.x);
+print(a.y);
+print(a.z);
+
+var b = new MyObject;
+
+print(b.x);
+print(b.y);
+print(b.z);
+
+var obj = {
+  func: function() {
+     print("obj.func called");
+  }
+};
+
+var x = new obj.func;
+print(x);
+
+x = new function f1(){ print("in f1"); return 1;};
+print(typeof(x));
+
diff --git a/nashorn/test/script/basic/new.js.EXPECTED b/nashorn/test/script/basic/new.js.EXPECTED
new file mode 100644
index 0000000..d8cdffb
--- /dev/null
+++ b/nashorn/test/script/basic/new.js.EXPECTED
@@ -0,0 +1,14 @@
+10
+string
+function() {
+        return true;
+    }
+10
+string
+function() {
+        return true;
+    }
+obj.func called
+[object Object]
+in f1
+object
diff --git a/nashorn/test/script/basic/newexpr.js b/nashorn/test/script/basic/newexpr.js
new file mode 100644
index 0000000..d8d1b48
--- /dev/null
+++ b/nashorn/test/script/basic/newexpr.js
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+/**
+ * Various kinds of "new" usage.
+ *
+ * @test
+ * @run
+ */
+
+var File = java.io.File;
+print(! new File(".").toString().isEmpty());
+
+var obj = {
+   foo : function (x) {
+       this.bar = x;
+   }
+}
+
+print(new obj.foo(23).bar);
+
+function func() {
+    this.foo = 42;
+}
+
+print(new func().foo);
+ 
+print ((new function() { this.x = "hello" }).x); 
+
+var abc = {
+   bar: function() {
+      return { x : "hello world" };
+   }
+};
+
+print(new abc.bar().x);
+
+function func2() {
+    return { 
+        foo: function() {
+            print("foo");
+        } 
+    };
+};
+
+print(new func2().foo());
diff --git a/nashorn/test/script/basic/newexpr.js.EXPECTED b/nashorn/test/script/basic/newexpr.js.EXPECTED
new file mode 100644
index 0000000..8b6c82e
--- /dev/null
+++ b/nashorn/test/script/basic/newexpr.js.EXPECTED
@@ -0,0 +1,7 @@
+true
+23
+42
+hello
+hello world
+foo
+undefined
diff --git a/nashorn/test/script/basic/newnew.js b/nashorn/test/script/basic/newnew.js
new file mode 100644
index 0000000..98a8e4d
--- /dev/null
+++ b/nashorn/test/script/basic/newnew.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * New new function tests.
+ *
+ * @test
+ * @run
+ */
+ 
+function myObject() {
+    this.x = 10;
+    this.y = 20;
+    this.z = 30;
+}
+
+function proxyObject() {
+    return myObject;
+}
+
+var obj1 = new myObject();
+var obj2 = new new proxyObject();
+var obj3 = new proxyObject();
+
+for (i in obj1) print(i, obj1[i]);
+for (i in obj2) print(i, obj2[i]);
+for (i in obj3) print(i, obj3[i]);
+
diff --git a/nashorn/test/script/basic/newnew.js.EXPECTED b/nashorn/test/script/basic/newnew.js.EXPECTED
new file mode 100644
index 0000000..f10d8f9
--- /dev/null
+++ b/nashorn/test/script/basic/newnew.js.EXPECTED
@@ -0,0 +1,6 @@
+x 10
+y 20
+z 30
+x 10
+y 20
+z 30
diff --git a/nashorn/test/script/basic/nonconstructors.js b/nashorn/test/script/basic/nonconstructors.js
new file mode 100644
index 0000000..8fb0d36
--- /dev/null
+++ b/nashorn/test/script/basic/nonconstructors.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * Not all functions are constructors. That which are not have to throw TypeError on new.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    new eval();
+} catch (e) {
+    print(e);
+}
+
+try {
+    new Array.prototype.pop();
+} catch (e) {
+    print(e);
+}
+
+try {
+    new String.prototype.indexOf();
+} catch (e) {
+    print(e);
+}
+
+try {
+    new Boolean.prototype.valueOf();
+} catch (e) {
+    print(e);
+}
diff --git a/nashorn/test/script/basic/nonconstructors.js.EXPECTED b/nashorn/test/script/basic/nonconstructors.js.EXPECTED
new file mode 100644
index 0000000..d5f38f8
--- /dev/null
+++ b/nashorn/test/script/basic/nonconstructors.js.EXPECTED
@@ -0,0 +1,4 @@
+TypeError: function eval() { [native code] } is not a constructor function
+TypeError: function pop() { [native code] } is not a constructor function
+TypeError: function indexOf() { [native code] } is not a constructor function
+TypeError: function valueOf() { [native code] } is not a constructor function
diff --git a/nashorn/test/script/basic/nosuchmethod.js b/nashorn/test/script/basic/nosuchmethod.js
new file mode 100644
index 0000000..6ac03f2
--- /dev/null
+++ b/nashorn/test/script/basic/nosuchmethod.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Test noSuchMethod feature.
+ *
+ * @test
+ * @run 
+ */
+
+__noSuchProperty__ = function(a) { this[a] = "xxx"; return this[a]; }
+__noSuchMethod__ = function(a) { this[a] = function() { return "yyy"; }; return this[a]; }
+
+
+print(a);
+print(b());
+
+print(a);
+print(b());
+
diff --git a/nashorn/test/script/basic/nosuchmethod.js.EXPECTED b/nashorn/test/script/basic/nosuchmethod.js.EXPECTED
new file mode 100644
index 0000000..a5db059
--- /dev/null
+++ b/nashorn/test/script/basic/nosuchmethod.js.EXPECTED
@@ -0,0 +1,4 @@
+xxx
+function() { return "yyy"; }
+xxx
+yyy
diff --git a/nashorn/test/script/basic/nosuchproperty.js b/nashorn/test/script/basic/nosuchproperty.js
new file mode 100644
index 0000000..8797610
--- /dev/null
+++ b/nashorn/test/script/basic/nosuchproperty.js
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check __noSuchProperty__
+ *
+ * @test
+ * @run
+ */
+
+function func(o) {
+   return o.foo;
+}
+
+var obj = {
+    __noSuchProperty__: function(name) {
+        print("obj.__noSuchProperty__ for " + name);
+    }
+};
+
+func(obj);
+
+obj.__noSuchProperty__ = function(name) {
+    print("new obj.__noSuchProperty__ for " + name);
+}
+
+func(obj);
+
+// try inherited __noSuchProperty__ now.
+var proto = {
+    __noSuchProperty__ : function(name) {
+        print("proto.__noSuchProperty__ for " + name);
+    }
+};
+
+var obj2 = Object.create(proto);
+func(obj2);
+
+proto.__noSuchProperty__ = function(name) {
+   print("new proto.__noSuchProperty__ for " + name);
+}
+
+func(obj2);
diff --git a/nashorn/test/script/basic/nosuchproperty.js.EXPECTED b/nashorn/test/script/basic/nosuchproperty.js.EXPECTED
new file mode 100644
index 0000000..923d988
--- /dev/null
+++ b/nashorn/test/script/basic/nosuchproperty.js.EXPECTED
@@ -0,0 +1,4 @@
+obj.__noSuchProperty__ for foo
+new obj.__noSuchProperty__ for foo
+proto.__noSuchProperty__ for foo
+new proto.__noSuchProperty__ for foo
diff --git a/nashorn/test/script/basic/number.js b/nashorn/test/script/basic/number.js
new file mode 100644
index 0000000..9215615
--- /dev/null
+++ b/nashorn/test/script/basic/number.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic Number tests
+ *
+ * @test
+ * @run
+ */
+
+var x = 10;
+print("x = " + x.toString());
+print(x.valueOf());
+print(x.toLocaleString());
+
+var y = new Number(Math.PI);
+print("y = " + y.toString());
+print(y.valueOf());
+
+// we can call java.lang.Double methods on JS Numbers
+print(Infinity.isInfinite());
+print(343.434.isInfinite());
diff --git a/nashorn/test/script/basic/number.js.EXPECTED b/nashorn/test/script/basic/number.js.EXPECTED
new file mode 100644
index 0000000..0e4b336
--- /dev/null
+++ b/nashorn/test/script/basic/number.js.EXPECTED
@@ -0,0 +1,7 @@
+x = 10
+10
+10
+y = 3.141592653589793
+3.141592653589793
+true
+false
diff --git a/nashorn/test/script/basic/numberstring.js b/nashorn/test/script/basic/numberstring.js
new file mode 100644
index 0000000..7daddb0
--- /dev/null
+++ b/nashorn/test/script/basic/numberstring.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * Number to string test
+ *
+ * @test
+ * @run
+ */
+
+print(1.0/0.0);
+print(-1.0/0.0);
+print(0.0/0.0);
+print(12345678901234567890.0);
+print(0.12345678901234567890);
+
+for (d = 1; d < 1E30; d *= 10.0) {
+    print(123456.0 * d);
+}
+
+for (d = 1; d < 1E30; d *= 10.0) {
+    print(123456.0 / d);
+}
diff --git a/nashorn/test/script/basic/numberstring.js.EXPECTED b/nashorn/test/script/basic/numberstring.js.EXPECTED
new file mode 100644
index 0000000..47d658e
--- /dev/null
+++ b/nashorn/test/script/basic/numberstring.js.EXPECTED
@@ -0,0 +1,67 @@
+Infinity
+-Infinity
+NaN
+12345678901234567000
+0.12345678901234568
+123456
+1234560
+12345600
+123456000
+1234560000
+12345600000
+123456000000
+1234560000000
+12345600000000
+123456000000000
+1234560000000000
+12345600000000000
+123456000000000000
+1234560000000000000
+12345600000000000000
+123456000000000000000
+1.23456e+21
+1.23456e+22
+1.23456e+23
+1.23456e+24
+1.23456e+25
+1.23456e+26
+1.23456e+27
+1.23456e+28
+1.23456e+29
+1.2345599999999999e+30
+1.2345599999999998e+31
+1.2345599999999998e+32
+1.23456e+33
+1.23456e+34
+1.2345599999999999e+35
+123456
+12345.6
+1234.56
+123.456
+12.3456
+1.23456
+0.123456
+0.0123456
+0.00123456
+0.000123456
+0.0000123456
+0.00000123456
+1.23456e-7
+1.23456e-8
+1.23456e-9
+1.23456e-10
+1.23456e-11
+1.23456e-12
+1.23456e-13
+1.23456e-14
+1.23456e-15
+1.23456e-16
+1.23456e-17
+1.23456e-18
+1.2345600000000001e-19
+1.2345600000000002e-20
+1.2345600000000002e-21
+1.2345600000000001e-22
+1.23456e-23
+1.23456e-24
+1.23456e-25
diff --git a/nashorn/test/script/basic/objectprops.js b/nashorn/test/script/basic/objectprops.js
new file mode 100644
index 0000000..525e80c
--- /dev/null
+++ b/nashorn/test/script/basic/objectprops.js
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check Object.defineProperty, Object.defineProperties and Object.create.
+ * FIXME: yet to checks for property attribute create/modifications.
+ *
+ * @test
+ * @run
+ */
+
+// create an object
+var obj = {};
+// data property
+Object.defineProperty(obj, "foo", { value: "hello" });
+// accessor property
+Object.defineProperty(obj, "bar", { get: function() { return "bar" } });
+
+print("obj.foo = " + obj.foo);
+print("obj.bar = " + obj.bar);
+
+// define multiple properties at one go.
+Object.defineProperties(obj,
+  {
+     xyz: { value: 44 },
+     abc: { get: function() { print("get abc"); return "abc"; } }
+  }
+); 
+
+print("obj.xyz = " + obj.xyz);
+print("obj.abc = " + obj.abc);
+
+function MyConstructor() {}
+var obj2 = Object.create(MyConstructor.prototype);
+print("obj2 in MyConstructor instance? " + (obj2 instanceof MyConstructor));
+
+var obj3 = Object.create(Object.prototype, 
+  {
+     xyz: { value: 44 }
+  }
+);
+
+print("obj3 is an Object? " + (obj3 instanceof Object));
+print(obj3.xyz);
diff --git a/nashorn/test/script/basic/objectprops.js.EXPECTED b/nashorn/test/script/basic/objectprops.js.EXPECTED
new file mode 100644
index 0000000..613713b
--- /dev/null
+++ b/nashorn/test/script/basic/objectprops.js.EXPECTED
@@ -0,0 +1,8 @@
+obj.foo = hello
+obj.bar = bar
+obj.xyz = 44
+get abc
+obj.abc = abc
+obj2 in MyConstructor instance? true
+obj3 is an Object? true
+44
diff --git a/nashorn/test/script/basic/objects.js b/nashorn/test/script/basic/objects.js
new file mode 100644
index 0000000..9d91379
--- /dev/null
+++ b/nashorn/test/script/basic/objects.js
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic object literal tests. Also check few Object.prototype and Object
+ * constructor functions.
+ *
+ * @test
+ * @run
+ */
+var person = { name: "sundar" };
+print(person.name);
+person.name = "Sundararajan";
+print(person.name);
+
+var obj = { foo: 3, bar: 44 };
+
+print("own properties of 'obj':");
+var names = Object.getOwnPropertyNames(obj);
+// get only own property names
+for (i in names) {
+   print(i + " -> " + names[i]);
+}
+
+print("has own 'foo'? " + obj.hasOwnProperty('foo'));
+print("has own 'xyz'? " + obj.hasOwnProperty('xyz'));
+
+print("'foo' enumerable? " + obj.propertyIsEnumerable('foo'));
+print("'bar' enumerable? " + obj.propertyIsEnumerable('bar'));
+
+obj = {
+    foo: 44,
+    bar: "orcl",
+    func: function() { print("myfunc"); },
+    get abc() { return "abc"; },
+    set xyz(val) { print(val); },
+    get hey() { return "hey"; },
+    set hey(val) { print(val); }
+}
+
+// get property descriptor for each property and check it
+for (i in obj) {
+    var desc = Object.getOwnPropertyDescriptor(obj, i);
+    print(i + " is writable? " + desc.writable);
+    print(i + " is configurable? " + desc.configurable);
+    print(i + " is enumerable? " + desc.enumerable);
+    print(i + "'s value = " + desc.value);
+    print(i + "'s get = " + desc.get);
+    print(i + "'s set = " + desc.set);
+}
+
+print(Object.getOwnPropertyDescriptor(obj, "non-existent"));
diff --git a/nashorn/test/script/basic/objects.js.EXPECTED b/nashorn/test/script/basic/objects.js.EXPECTED
new file mode 100644
index 0000000..a6bedc0
--- /dev/null
+++ b/nashorn/test/script/basic/objects.js.EXPECTED
@@ -0,0 +1,46 @@
+sundar
+Sundararajan
+own properties of 'obj':
+0 -> foo
+1 -> bar
+has own 'foo'? true
+has own 'xyz'? false
+'foo' enumerable? true
+'bar' enumerable? true
+foo is writable? true
+foo is configurable? true
+foo is enumerable? true
+foo's value = 44
+foo's get = undefined
+foo's set = undefined
+bar is writable? true
+bar is configurable? true
+bar is enumerable? true
+bar's value = orcl
+bar's get = undefined
+bar's set = undefined
+func is writable? true
+func is configurable? true
+func is enumerable? true
+func's value = function() { print("myfunc"); }
+func's get = undefined
+func's set = undefined
+abc is writable? undefined
+abc is configurable? true
+abc is enumerable? true
+abc's value = undefined
+abc's get = abc() { return "abc"; }
+abc's set = undefined
+xyz is writable? undefined
+xyz is configurable? true
+xyz is enumerable? true
+xyz's value = undefined
+xyz's get = undefined
+xyz's set = xyz(val) { print(val); }
+hey is writable? undefined
+hey is configurable? true
+hey is enumerable? true
+hey's value = undefined
+hey's get = hey() { return "hey"; }
+hey's set = hey(val) { print(val); }
+undefined
diff --git a/nashorn/test/script/basic/options.js b/nashorn/test/script/basic/options.js
new file mode 100644
index 0000000..102bb5e
--- /dev/null
+++ b/nashorn/test/script/basic/options.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * Access nashorn command line options.
+ *
+ * @test
+ * @option -scripting
+ * @option -timezone=Asia/Calcutta
+ * @run
+ */
+print("-scripting = " + $OPTIONS._scripting);
+print("--compile-only = " + $OPTIONS._compile_only);
+print("-timezone = " + $OPTIONS._timezone.ID);
diff --git a/nashorn/test/script/basic/options.js.EXPECTED b/nashorn/test/script/basic/options.js.EXPECTED
new file mode 100644
index 0000000..dd5f155
--- /dev/null
+++ b/nashorn/test/script/basic/options.js.EXPECTED
@@ -0,0 +1,3 @@
+-scripting = true
+--compile-only = false
+-timezone = Asia/Calcutta
diff --git a/nashorn/test/script/basic/propchange.js b/nashorn/test/script/basic/propchange.js
new file mode 100644
index 0000000..b317032
--- /dev/null
+++ b/nashorn/test/script/basic/propchange.js
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/**
+ * Change attributes of an existing property
+ *
+ * @test
+ * @run
+ */ 
+
+var obj = { x: 343 };
+
+for(i in obj) {
+  print(i);
+}
+
+Object.defineProperty(obj, "x", {
+   enumerable: false });
+
+// not-enumerable anymore
+for(i in obj) {
+  print(i);
+}
+
+print(obj.x);
+obj.x = 42;
+print(obj.x);
+
+// make non-writable
+Object.defineProperty(obj, "x", {
+    writable: false
+});
+
+obj.x = "hello";
+print(obj.x);
+
+print("done");
+
diff --git a/nashorn/test/script/basic/propchange.js.EXPECTED b/nashorn/test/script/basic/propchange.js.EXPECTED
new file mode 100644
index 0000000..5f0b36b
--- /dev/null
+++ b/nashorn/test/script/basic/propchange.js.EXPECTED
@@ -0,0 +1,5 @@
+x
+343
+42
+42
+done
diff --git a/nashorn/test/script/basic/propertycheck.js b/nashorn/test/script/basic/propertycheck.js
new file mode 100644
index 0000000..8e35015
--- /dev/null
+++ b/nashorn/test/script/basic/propertycheck.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Check "prop" in obj syntax.
+ *
+ * @test
+ * @run
+ */
+
+var obj = { bar: 33 };
+
+// should print false
+print("foo" in obj);
+
+// should print true
+print("bar" in obj);
diff --git a/nashorn/test/script/basic/propertycheck.js.EXPECTED b/nashorn/test/script/basic/propertycheck.js.EXPECTED
new file mode 100644
index 0000000..1d474d5
--- /dev/null
+++ b/nashorn/test/script/basic/propertycheck.js.EXPECTED
@@ -0,0 +1,2 @@
+false
+true
diff --git a/nashorn/test/script/basic/proto.js.EXPECTED b/nashorn/test/script/basic/proto.js.EXPECTED
new file mode 100644
index 0000000..fded727
--- /dev/null
+++ b/nashorn/test/script/basic/proto.js.EXPECTED
@@ -0,0 +1,2 @@
+a string
+a string
diff --git a/nashorn/test/script/basic/prototype.js b/nashorn/test/script/basic/prototype.js
new file mode 100644
index 0000000..e85d3d4
--- /dev/null
+++ b/nashorn/test/script/basic/prototype.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-467 - check that prootype.js parses and compiles
+ *
+ * @test
+ * @runif external.prototype
+ */
+
+function check(url_) {
+    try {
+	load(url_);
+    } catch (e) {
+	if (e instanceof ReferenceError && e.toString().indexOf('navigator') != -1) {
+	    return;
+	}
+	throw e;
+    }
+}
+
+var file = __DIR__ + "../external/prototype/prototype.js";
+try {
+    try {
+        check(file);
+    } catch (e) { 
+        print(e);
+    }
+} catch (e) {
+    print("error: " + typeof e);
+}
+print("parsed and compiled ok prototype.js");
diff --git a/nashorn/test/script/basic/prototype.js.EXPECTED b/nashorn/test/script/basic/prototype.js.EXPECTED
new file mode 100644
index 0000000..e677550
--- /dev/null
+++ b/nashorn/test/script/basic/prototype.js.EXPECTED
@@ -0,0 +1 @@
+parsed and compiled ok prototype.js
diff --git a/nashorn/test/script/basic/pushpull.js b/nashorn/test/script/basic/pushpull.js
new file mode 100644
index 0000000..192ef9c
--- /dev/null
+++ b/nashorn/test/script/basic/pushpull.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test array push and pull.
+ *
+ * @test
+ * @run
+ */
+
+var a = [1, 2, 3, 4, 5];
+var b = ["a", "b", "c", "d"];
+
+print(a.push(10, 20, 30, 40));
+print(a.pop());
+print(a);
+print(a.push("rabbit"));
+print(a.pop());
+
+print(b.push("e", "f"));
+print(b.pop());
diff --git a/nashorn/test/script/basic/pushpull.js.EXPECTED b/nashorn/test/script/basic/pushpull.js.EXPECTED
new file mode 100644
index 0000000..d43da4b
--- /dev/null
+++ b/nashorn/test/script/basic/pushpull.js.EXPECTED
@@ -0,0 +1,7 @@
+9
+40
+1,2,3,4,5,10,20,30
+9
+rabbit
+6
+f
diff --git a/nashorn/test/script/basic/regex.js b/nashorn/test/script/basic/regex.js
new file mode 100644
index 0000000..49dd743
--- /dev/null
+++ b/nashorn/test/script/basic/regex.js
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+/**
+ * RegExp test.
+ *
+ * @test
+ * @run 
+ */
+ 
+var regexp;
+
+regexp = new RegExp("dog");
+print("is global? " + regexp.global);
+print(regexp.exec("One dog, two dogs in the yard."));
+regexp = new RegExp("dog", "g");
+print(regexp.exec("One dog, two dogs in the yard."));
+regexp = new RegExp("(d)(o)(g)");
+print(regexp.exec("One dog, two dogs in the yard."));
+regexp = new RegExp("cat");
+print(regexp.exec("One dog, two dogs in the yard."));
+
+regexp = new RegExp("dog");
+print(regexp.test("One dog, two dogs in the yard."));
+regexp = new RegExp("dog", "g");
+print(regexp.test("One dog, two dogs in the yard."));
+regexp = new RegExp("(d)(o)(g)");
+print(regexp.test("One dog, two dogs in the yard."));
+regexp = new RegExp("cat");
+print(regexp.test("One dog, two dogs in the yard."));
+
+regexp = new RegExp("dog");
+print("One dog, two dogs in the yard.".replace(regexp, "cat"));
+regexp = new RegExp("dog", "g");
+print("One dog, two dogs in the yard.".replace(regexp, "cat"));
+regexp = new RegExp("(d)(o)(g)");
+print("One dog, two dogs in the yard.".replace(regexp, "cat"));
+regexp = new RegExp("cat");
+print("One dog, two dogs in the yard.".replace(regexp, "cat"));
+print("One dog, two dogs in the yard.".replace("dog", "cat"));
+
+regexp = new RegExp("dog");
+print("One dog, two dogs in the yard.".search(regexp));
+regexp = new RegExp("dog", "g");
+print("One dog, two dogs in the yard.".search(regexp));
+regexp = new RegExp("(d)(o)(g)");
+print("One dog, two dogs in the yard.".search(regexp));
+regexp = new RegExp("cat");
+print("One dog, two dogs in the yard.".search(regexp));
+
+print(/dog/.exec("One dog, two dogs in the yard."));
+print(/dog/g.exec("One dog, two dogs in the yard."));
+print(/(d)(o)(g)/.exec("One dog, two dogs in the yard."));
+print(/cat/.exec("One dog, two dogs in the yard."));
+
+print(/dog/.test("One dog, two dogs in the yard."));
+print(/dog/g.test("One dog, two dogs in the yard."));
+print(/(d)(o)(g)/.test("One dog, two dogs in the yard."));
+print(/cat/.test("One dog, two dogs in the yard."));
+
+print("One dog, two dogs in the yard.".replace(/dog/, "cat"));
+print("One dog, two dogs in the yard.".replace(/dog/g, "cat"));
+print("One dog, two dogs in the yard.".replace(/(d)(o)(g)/, "cat"));
+print("One dog, two dogs in the yard.".replace(/cat/, "cat"));
+
+print("One dog, two dogs in the yard.".search(/dog/));
+print("One dog, two dogs in the yard.".search(/dog/g));
+print("One dog, two dogs in the yard.".search(/(d)(o)(g)/));
+print("One dog, two dogs in the yard.".search(/cat/));
+
+print("One dog, two dogs in the yard.".split(/dog/));
+print("One dog, two dogs in the yard.".split(/dog/g));
+print("One dog, two dogs in the yard.".split(/(d)(o)(g)/));
+print("One dog, two dogs in the yard.".split(/cat/));
+
+regexp = new RegExp("dog");
+print("One dog, two dogs in the yard.".split(regexp));
+regexp = new RegExp("dog", "g");
+print("One dog, two dogs in the yard.".split(regexp));
+regexp = new RegExp("(d)(o)(g)");
+print("One dog, two dogs in the yard.".split(regexp));
+regexp = new RegExp("cat");
+print("One dog, two dogs in the yard.".split(regexp));
+print("One dog, two dogs in the yard.".split("dog"));
+
+var str = 'shapgvba (){Cuk.Nccyvpngvba.Frghc.Pber();Cuk.Nccyvpngvba.Frghc.Nwnk();Cuk.Nccyvpngvba.Frghc.Synfu();Cuk.Nccyvpngvba.Frghc.Zbqhyrf()}';
+regex = /^[\s[]?shapgvba/;
+print(regex.exec('[bowrpg tybony]'));
+print(regex.exec(str));
+print(regex.exec('shapgvba sbphf() { [angvir pbqr] }'));
+regex = new RegExp("^[\\s[]?shapgvba");
+print(regex.exec('[bowrpg tybony]'));
+print(regex.exec(str));
+print(regex.exec('shapgvba sbphf() { [angvir pbqr] }'));
diff --git a/nashorn/test/script/basic/regex.js.EXPECTED b/nashorn/test/script/basic/regex.js.EXPECTED
new file mode 100644
index 0000000..76a7e67
--- /dev/null
+++ b/nashorn/test/script/basic/regex.js.EXPECTED
@@ -0,0 +1,49 @@
+is global? false
+dog
+dog
+dog,d,o,g
+null
+true
+true
+true
+false
+One cat, two dogs in the yard.
+One cat, two cats in the yard.
+One cat, two dogs in the yard.
+One dog, two dogs in the yard.
+One cat, two dogs in the yard.
+4
+4
+4
+-1
+dog
+dog
+dog,d,o,g
+null
+true
+true
+true
+false
+One cat, two dogs in the yard.
+One cat, two cats in the yard.
+One cat, two dogs in the yard.
+One dog, two dogs in the yard.
+4
+4
+4
+-1
+One ,, two ,s in the yard.
+One ,, two ,s in the yard.
+One ,d,o,g,, two ,d,o,g,s in the yard.
+One dog, two dogs in the yard.
+One ,, two ,s in the yard.
+One ,, two ,s in the yard.
+One ,d,o,g,, two ,d,o,g,s in the yard.
+One dog, two dogs in the yard.
+One ,, two ,s in the yard.
+null
+shapgvba
+shapgvba
+null
+shapgvba
+shapgvba
diff --git a/nashorn/test/script/basic/regexp_flags.js b/nashorn/test/script/basic/regexp_flags.js
new file mode 100644
index 0000000..9ff7543
--- /dev/null
+++ b/nashorn/test/script/basic/regexp_flags.js
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-154: Early error reporting.
+ *
+ * Errors in regular expression literals that are not implementation-defined 
+ * syntax extensions.
+ *
+ * @test
+ * @run
+ */
+
+// leave only 'g', 'i' and 'm'. All other flags are invalid
+var flags = "abcdefhjklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+// check all invalid flags
+for (var i = 0; i < flags.length; i++) {
+    try {
+        // because regexp literal errors are early errors, we should not see
+        // any output from print calls.
+        eval("print(__FILE__); var x = /nashorn/" + flags[i]);
+        fail("SyntaxError not thrown for regexp flag " + flags[i]);
+    } catch (e) {
+        if (! (e instanceof SyntaxError)) {
+            fail("SyntaxError not thrown for regexp flag " + flags[i]);
+        }
+    }
+}
diff --git a/nashorn/test/script/basic/run-octane.js b/nashorn/test/script/basic/run-octane.js
new file mode 100644
index 0000000..42bf77f
--- /dev/null
+++ b/nashorn/test/script/basic/run-octane.js
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+
+/**
+ * @subtest
+ */
+
+var tests = [
+    "box2d.js",
+    "code-load.js",
+    "crypto.js", 
+    "deltablue.js", 
+    "earley-boyer.js", 
+    "gbemu.js",	     
+    "navier-stokes.js", 
+    "pdfjs.js",
+    "raytrace.js",
+    "regexp.js", 
+    "richards.js", 
+    "splay.js" 
+];
+
+// hack, teardown breaks things defined in the global space, making it impossible
+// to do multiple consecutive benchmark runs with the same harness. I think it's a bug
+// that the setup and teardown aren't each others constructor and destructor but rather
+// that the benchmarks rely on partial global state. For shame, Octane! 
+var ignoreTeardown = [
+    { name: "box2d.js" },
+    { name: "gbemu.js" },
+];
+
+var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
+
+// TODO: why is this path hard coded when it's defined in project properties?
+var path = dir + "../external/octane/";
+
+var runtime = "";
+var verbose = false;
+
+var numberOfIterations = 5;
+
+function endsWith(str, suffix) {
+    return str.indexOf(suffix, str.length - suffix.length) !== -1;
+}
+
+function run_one_benchmark(arg, iters) {
+
+    var file_name;
+    var file = arg.split('/');
+    if (file.length == 1) {
+        file = arg.split('\\');
+    }    
+
+    //trim off trailing path separators
+    while (file[file.length - 1].indexOf(".js") == -1) {
+	file.pop();
+    }
+    file_name = file[file.length - 1];
+
+    if (typeof compile_only !== 'undefined') {
+	print("Compiling... " + file_name);
+    }
+
+    load(path + 'base.js');
+    load(arg);
+    
+    if (typeof compile_only !== 'undefined') {
+	print("Compiled OK: " + file_name);
+	print("");
+	return;
+    }
+    
+    var success = true;
+    var hiscore = 0;
+    var loscore = 10e8;
+    var current_name;
+    
+    function PrintResult(name, result) {
+	current_name = name;
+    }
+        
+    function PrintError(name, error) {
+	current_name = name;
+	PrintResult(name, error);
+	success = false;
+    }
+        
+    function PrintScore(score) {
+	if (success) {
+	    if (+score >= hiscore) {
+		hiscore = +score;
+	    }
+	    if (+score <= loscore) {
+		loscore = +score;
+	    }
+	}
+
+	if (verbose) {
+	    print("Score: " + score);
+	}
+    }
+    
+    if (iters == undefined) {
+	iters = numberOfIterations;
+    } else {
+	numberOfIterations = iters;
+    }
+
+    print(runtime + ": running " + file_name + "...");
+
+    for (var i = 0; i < numberOfIterations; i++) {
+	var callbacks =
+	    { NotifyResult: PrintResult,
+	      NotifyError: PrintError,
+	      NotifyScore: PrintScore };	
+
+	for (j in ignoreTeardown) {
+	    var ignore = ignoreTeardown[j];
+	    if (endsWith(arg, ignore.name)) {
+		var teardownOverride = ignore.teardown;
+		if (!teardownOverride) {
+		    teardownOverride = function() {};
+		}
+
+		for (k in BenchmarkSuite.suites) {
+		    var benchmarks = BenchmarkSuite.suites[k].benchmarks;
+		    for (l in benchmarks) {
+			benchmarks[l].TearDown = teardownOverride;
+		    }
+                }
+		break;
+	    }
+	}
+	
+	BenchmarkSuite.RunSuites(callbacks);
+    }
+    
+    var start = "Score: ";
+    if (runtime != "") {
+	start = runtime + ": ";
+    } 
+    print(start + current_name + ' (version ' + BenchmarkSuite.version + '): ' + loscore + '-' + hiscore);
+}
+
+function run_suite(tests, iters) {
+    for (var idx = 0; idx < tests.length; idx++) {
+	run_one_benchmark(tests[idx], iters, false);
+    }
+}
+
+runtime = "command line";
+
+var args = [];
+if (typeof $ARGS !== 'undefined') {
+    args = $ARGS;
+} else if (typeof arguments !== 'undefined' && arguments.length != 0) {
+    args = arguments;
+}  
+
+var new_args = [];
+for (i in args) {
+    if (args[i].toString().indexOf(' ') != -1) {
+	args[i] = args[i].replace(/\/$/, '');
+	var s = args[i].split(' ');
+	for (j in s) {
+	    new_args.push(s[j]);
+	}
+    } else {
+	new_args.push(args[i]);
+    }
+}
+
+if (new_args.length != 0) {
+    args = new_args;
+}
+
+var tests_found = [];
+var iters = undefined;
+
+for (var i = 0; i < args.length; i++) { 
+    arg = args[i];
+    if (arg == "--iterations") {
+	iters = +args[++i];
+    } else if (arg == "--runtime") {
+	runtime = args[++i];
+    } else if (arg == "--verbose") {
+	verbose = true;
+    } else if (arg == "") {
+	continue; //skip
+    } else {
+	tests_found.push(arg);
+    }
+}
+
+if (tests_found.length == 0) {    
+    for (i in tests) {
+	tests_found.push(path + tests[i]);
+    }
+} 
+
+tests_found.sort();
+
+run_suite(tests_found, iters);
+
+
+
diff --git a/nashorn/test/script/basic/runsunspider.js b/nashorn/test/script/basic/runsunspider.js
new file mode 100644
index 0000000..7b0d732
--- /dev/null
+++ b/nashorn/test/script/basic/runsunspider.js
@@ -0,0 +1,379 @@
+/*
+ * 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.
+ */
+
+/**
+ * runsunspider : runs the sunspider tests and checks for compliance
+ *
+ * @test
+ * @option -timezone=PST
+ * @runif external.sunspider
+ */
+
+/*
+ * Copyright (c) 2010-2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This is not a test, but a test "framework" for running sunspider tests.
+ *
+ */
+
+function assertEq(a, b) {
+    if (a !== b) {
+	throw "ASSERTION FAILED: " + a + " should be " + b;
+    }
+}
+
+var runs = 0;
+var iterations__ = 1;
+var total_time = 0;
+
+function runbench(name) {
+    var filename = name.split("/").pop();
+    if (verbose_run) {
+	print("Running " + filename);
+    }
+
+    var start = new Date;
+    for (var i = 0; i < iterations__; i++) {
+	load(name);    
+    }
+    var stop = new Date - start;
+    total_time += stop;
+    
+    if (verbose_run) {
+	print(filename + " done in " + stop + " ms"); 
+    } 
+    runs++;
+}
+
+var m_w = 4711;
+var m_z = 17;
+var MAXINT = 0x7fffffff;
+
+//produce deterministic random numbers for test suite
+function pseudorandom() {
+    m_z = 36969 * (m_z & 65535) + (m_z >> 16);
+    m_w = 18000 * (m_w & 65535) + (m_w >> 16);
+    return (Math.abs((m_z << 16) + m_w) & MAXINT) / MAXINT;
+}
+
+function runsuite(tests) {
+    var changed = false;
+    
+    var oldRandom = Math.random;
+    Math.random = pseudorandom;
+    
+    try {
+	for (var n = 0; n < tests.length; n++) {
+	    runbench(tests[n].name);
+	    if (typeof tests[n].actual !== 'undefined') {
+		assertEq(tests[n].actual(), tests[n].expected());
+	    }
+	    changed = true;
+	}
+    } catch (e) {
+	print("error: " + e);
+	if (e.toString().indexOf(tests) == 1) {
+	    throw e;
+	}
+	// no scripting or something, silently fail
+    } finally {
+	Math.random = oldRandom;
+    }
+
+    return changed;
+}
+
+function hash(str) {
+    var s = "" + str;
+    var h = 0;
+    var off = 0;
+    for (var i = 0; i < s.length; i++) {
+	h = 31 * h + s.charCodeAt(off++);
+	h &= 0x7fffffff;
+    }
+    return h ^ s.length;
+}
+
+var tests = [
+    { name: 'string-base64.js',
+      actual: function() {	  
+	  return hash(str);
+      },
+      expected: function() {
+	  return 1544571068;
+      }
+    },    
+    { name: 'string-validate-input.js',
+      actual: function() {	  
+	  return hash(endResult);
+      },
+      expected: function() {
+	  return 2016572373;
+      }
+    },    
+    { name: 'date-format-xparb.js',
+      actual: function() {	  
+	  return shortFormat + longFormat;
+      },
+      expected: function() {
+	  return "2017-09-05Tuesday, September 05, 2017 8:43:48 AM";
+      }
+    },    
+    { name: '3d-morph.js',
+      actual: function() {
+	  var acceptableDelta = 4e-15;
+	  return (testOutput - 6.394884621840902e-14) < acceptableDelta;
+      },
+      expected: function() {
+	  return true;
+      }
+    },    
+    { name: 'crypto-aes.js',
+      actual: function() {
+	  return plainText;
+      },
+      expected: function() {
+	  return decryptedText;
+      }
+    },    
+    { name: 'crypto-md5.js',
+      actual: function() {
+	  return md5Output;
+      },
+      expected: function() {
+	  return "a831e91e0f70eddcb70dc61c6f82f6cd";
+      }
+    },    
+    { name: 'crypto-sha1.js',
+      actual: function() {
+	  return sha1Output;
+      },
+      expected: function() {
+	  return "2524d264def74cce2498bf112bedf00e6c0b796d";
+      }
+    },    
+    { name: 'bitops-bitwise-and.js', 
+      actual: function() {
+	  return result;      
+      },
+      expected: function() {
+	  return 0;
+      }
+    },    
+    { name: 'bitops-bits-in-byte.js', 
+      actual: function() {
+	  return result;      
+      },
+      expected: function() {
+	  return 358400;
+      }
+    },    
+    { name: 'bitops-nsieve-bits.js', 
+      actual: function() {
+	  var ret = 0;
+	  for (var i = 0; i < result.length; ++i) {
+	      ret += result[i];
+	  }
+	  ret += result.length;
+	  return ret;	    
+      },
+      expected: function() {
+	  return -1286749539853;
+      }
+    },    
+    { name: 'bitops-3bit-bits-in-byte.js', 
+      actual: function() {
+	  return sum;      
+      },
+      expected: function() {
+	  return 512000;
+      }
+    },    
+    { name: 'access-nbody.js', 
+      actual: function() {
+	  return ret;  
+      },
+      expected: function() {
+	    return -0.16906933525822856;
+      }
+    },    
+    { name: 'access-binary-trees.js', 
+      actual: function() {
+	  return ret;  
+      },
+      expected: function() {
+	  return -1;
+      }
+    },    
+    { name: 'access-fannkuch.js',
+      actual: function() {
+	  return ret;  
+      },
+      expected: function() {
+	  return 22;
+      }
+    },
+    { name: 'math-spectral-norm.js',
+      actual: function() {	    
+	  var ret = '';
+	  for (var i = 6; i <= 48; i *= 2) {
+	      ret += spectralnorm(i) + ',';
+	  }
+	  return ret;
+      },
+      expected: function() {
+	  return "1.2657786149754053,1.2727355112619148,1.273989979775574,1.274190125290389,";
+      }
+    },    
+    { name: '3d-raytrace.js',
+      actual: function() {
+	  return hash(testOutput);
+      },
+      expected: function() {
+	  return 230692593;
+      }
+    },    
+    { name: 'regexp-dna.js',
+      actual: function() {
+	  return dnaOutputString;
+      },
+      expected: function() {
+	  return "undefinedagggtaaa|tttaccct 0\n[cgt]gggtaaa|tttaccc[acg] 9\na[act]ggtaaa|tttacc[agt]t 27\nag[act]gtaaa|tttac[agt]ct 24\nagg[act]taaa|ttta[agt]cct 30\naggg[acg]aaa|ttt[cgt]ccct 9\nagggt[cgt]aa|tt[acg]accct 12\nagggta[cgt]a|t[acg]taccct 9\nagggtaa[cgt]|[acg]ttaccct 15\n";
+      }
+    },    
+    { name: 'math-cordic.js',
+      actual: function() {
+	  return total;
+      },
+      expected: function() {
+	  return 10362.570468755888;
+      }
+    },
+    { name: 'controlflow-recursive.js',
+      actual: function() {
+	  var ret = 0;
+	  for (var i = 3; i <= 5; i++) {
+	      ret += ack(3,i);
+	      ret += fib(17.0+i);
+	      ret += tak(3*i+3,2*i+2,i+1);
+	  }
+	  return ret;
+      },
+      expected: function() {
+	  return 57775;
+      }
+    },    
+    { name: 'date-format-tofte.js',
+      actual: function() {
+	  return shortFormat + longFormat;
+      },
+      expected: function() {
+	  return "2008-05-01Thursday, May 01, 2008 6:31:22 PM";
+      }
+    },
+    { name: 'string-tagcloud.js',
+      actual: function() {
+	  // The result string embeds floating-point numbers, which can vary a bit on different platforms,
+	  // so we truncate them a bit before comparing.
+	  var tagcloud_norm = tagcloud.replace(/([0-9.]+)px/g, function(str, p1) { return p1.substr(0, 10) + 'px' })
+	  return tagcloud_norm.length;
+      },
+      expected: function() {
+	  return 295906;
+      }
+    },    
+    { name: 'string-unpack-code.js',
+      actual: function() {
+	  return decompressedMochiKit.length == 106415 &&
+	      decompressedMochiKit[2000] == '5' &&
+	      decompressedMochiKit[12000] == '_' &&
+	      decompressedMochiKit[82556] == '>';
+      },
+      expected: function() {
+	  return true;
+      }
+    },    
+    //TODO no easy way to sanity check result
+    { name: 'string-fasta.js' },
+    //TODO no easy way to sanity check result
+    { name: 'math-partial-sums.js' },
+    //TODO no easy way to sanity check result
+    { name: 'access-nsieve.js' },
+    //TODO no easy way to sanity check result
+    { name: '3d-cube.js' },    
+];
+
+// handle the case this script may be run by a JS engine that doesn't
+// support __DIR__ global variable.
+var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
+
+for (i in tests) {
+    tests[i].name = dir + '../external/sunspider/tests/sunspider-1.0/' + tests[i].name;
+}
+
+var verbose_run = false;
+
+var args = [];
+if (typeof $ARGS !== 'undefined') {
+    args = $ARGS;
+} else if (typeof arguments !== 'undefined' && arguments.length != 0) {
+    args = arguments;
+}  
+
+for (i in args) {
+    if (args[i] === '--verbose') {
+	verbose_run = true;
+	break;
+    }
+}
+
+runsuite(tests);
+
+if (verbose_run) {
+    print('\n' + runs + "/" + tests.length + " tests were successfully run in " + total_time + " ms ");
+}
+
+print("Sunspider finished!");
diff --git a/nashorn/test/script/basic/runsunspider.js.EXPECTED b/nashorn/test/script/basic/runsunspider.js.EXPECTED
new file mode 100644
index 0000000..dd36083
--- /dev/null
+++ b/nashorn/test/script/basic/runsunspider.js.EXPECTED
@@ -0,0 +1 @@
+Sunspider finished!
diff --git a/nashorn/test/script/basic/samfunc.js b/nashorn/test/script/basic/samfunc.js
new file mode 100644
index 0000000..7751bee0
--- /dev/null
+++ b/nashorn/test/script/basic/samfunc.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * SAM interface implemented by a script function.
+ *
+ * @test
+ * @run
+ */
+
+// we can pass a script function when an interface with single
+// abstract method is required. Here we pass script function for
+// a java.lang.Runnable.
+
+var t1 = new java.lang.Thread(function() {
+    print("thread t1.run");
+}); 
+
+// make sure that we can pass interface implementation as well.
+var t2 = new java.lang.Thread(new java.lang.Runnable() {
+   run: function() { print("thread t2.run"); }
+});
+
+t1.start();
+t1.join();
+
+t2.start();
+t2.join();
diff --git a/nashorn/test/script/basic/samfunc.js.EXPECTED b/nashorn/test/script/basic/samfunc.js.EXPECTED
new file mode 100644
index 0000000..43dea4a
--- /dev/null
+++ b/nashorn/test/script/basic/samfunc.js.EXPECTED
@@ -0,0 +1,2 @@
+thread t1.run
+thread t2.run
diff --git a/nashorn/test/script/basic/scripting.js b/nashorn/test/script/basic/scripting.js
new file mode 100644
index 0000000..8809636
--- /dev/null
+++ b/nashorn/test/script/basic/scripting.js
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/**
+ * Edit strings test
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+# scripting mode - shell style line comment works..
+
+var t = "normal";
+print("a ${t} string");
+
+// JavaScript style line comment works too..
+var i = 0;
+print("line ${i++}\nline ${i++}");
+
+var c = 3;
+print(<<EOD + "!!!!")
+Here is a long sentence
+that may extend over ${c}
+lines.
+EOD
+
+c = 4;
+print(<<<EOD + "!!!!")
+Here is a long sentence
+that may extend over ${c}
+lines.
+EOD
+
+eval(<<BRAINTEASER);
+print("This is executed how");
+BRAINTEASER
+
+print(<<HTML);
+    <html>
+        <head>
+            <title>Testing</title>
+        </head>
+        <body>
+            <p>This is a test.<p>
+        </body>
+    </html>
+HTML
+
+var x = 1
+<<
+3;
+print(x);
+
+var y = <<EOD;
+There we go
+EOD y = "No we don't";
+print(y);
+
+
+print(readFully(__FILE__));
diff --git a/nashorn/test/script/basic/scripting.js.EXPECTED b/nashorn/test/script/basic/scripting.js.EXPECTED
new file mode 100644
index 0000000..4f06475
--- /dev/null
+++ b/nashorn/test/script/basic/scripting.js.EXPECTED
@@ -0,0 +1,103 @@
+a normal string
+line 0
+line 1
+Here is a long sentence
+that may extend over 3
+lines.!!!!
+Here is a long sentence
+that may extend over 4
+lines.
+!!!!
+This is executed how
+    <html>
+        <head>
+            <title>Testing</title>
+        </head>
+        <body>
+            <p>This is a test.<p>
+        </body>
+    </html>
+8
+No we don't
+/*
+ * 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.
+ */
+
+/**
+ * Edit strings test
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+# scripting mode - shell style line comment works..
+
+var t = "normal";
+print("a ${t} string");
+
+// JavaScript style line comment works too..
+var i = 0;
+print("line ${i++}\nline ${i++}");
+
+var c = 3;
+print(<<EOD + "!!!!")
+Here is a long sentence
+that may extend over ${c}
+lines.
+EOD
+
+c = 4;
+print(<<<EOD + "!!!!")
+Here is a long sentence
+that may extend over ${c}
+lines.
+EOD
+
+eval(<<BRAINTEASER);
+print("This is executed how");
+BRAINTEASER
+
+print(<<HTML);
+    <html>
+        <head>
+            <title>Testing</title>
+        </head>
+        <body>
+            <p>This is a test.<p>
+        </body>
+    </html>
+HTML
+
+var x = 1
+<<
+3;
+print(x);
+
+var y = <<EOD;
+There we go
+EOD y = "No we don't";
+print(y);
+
+
+print(readFully(__FILE__));
+
diff --git a/nashorn/test/script/basic/sealfreeze.js b/nashorn/test/script/basic/sealfreeze.js
new file mode 100644
index 0000000..8b932f8
--- /dev/null
+++ b/nashorn/test/script/basic/sealfreeze.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic checks for Object.seal and Object.freeze.
+ *
+ * @test
+ * @run
+ */
+
+var obj = { num: Math.E };
+
+print("sealed? " + Object.isSealed(obj));
+print("frozen? " + Object.isFrozen(obj));
+
+Object.seal(obj);
+print("sealed? " + Object.isSealed(obj));
+
+// delete should fail - because we have sealed
+print("deleted num? " + (delete obj.num));
+print("num = " + obj.num);
+
+// assignment should succeed
+print("assign PI to num");
+obj.num = Math.PI;
+print("num = " + obj.num);
+
+// assignment should fail -- because we freeze
+Object.freeze(obj);
+print("frozen? " + Object.isFrozen(obj));
+
+print("assign 1729 to num");
+obj.num = 1729;
+print("num = " + obj.num);
+
diff --git a/nashorn/test/script/basic/sealfreeze.js.EXPECTED b/nashorn/test/script/basic/sealfreeze.js.EXPECTED
new file mode 100644
index 0000000..55da861
--- /dev/null
+++ b/nashorn/test/script/basic/sealfreeze.js.EXPECTED
@@ -0,0 +1,10 @@
+sealed? false
+frozen? false
+sealed? true
+deleted num? false
+num = 2.718281828459045
+assign PI to num
+num = 3.141592653589793
+frozen? true
+assign 1729 to num
+num = 3.141592653589793
diff --git a/nashorn/test/script/basic/setlength.js b/nashorn/test/script/basic/setlength.js
new file mode 100644
index 0000000..45f54e5
--- /dev/null
+++ b/nashorn/test/script/basic/setlength.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test set array length.
+ *
+ * @test
+ * @run
+ */
+ 
+var a = ["a", "b", "c", "d", "e"];
+print(a.length);
+print(a);
+a.length = 2;
+print(a.length);
+print(a);
+a.length = 10;
+print(a.length);
+print(a);
+a.length = 4;
+print(a.length);
+print(a);
+a.length = 8;
+print(a.length);
+print(a);
diff --git a/nashorn/test/script/basic/setlength.js.EXPECTED b/nashorn/test/script/basic/setlength.js.EXPECTED
new file mode 100644
index 0000000..a2d5851
--- /dev/null
+++ b/nashorn/test/script/basic/setlength.js.EXPECTED
@@ -0,0 +1,10 @@
+5
+a,b,c,d,e
+2
+a,b
+10
+a,b,,,,,,,,
+4
+a,b,,
+8
+a,b,,,,,,
diff --git a/nashorn/test/script/basic/stdin.js b/nashorn/test/script/basic/stdin.js
new file mode 100644
index 0000000..ba546d5
--- /dev/null
+++ b/nashorn/test/script/basic/stdin.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Tests access to System.in
+ *
+ * @test
+ * @run
+ */
+
+print(java.lang.System.in.class.name);
+var prop = "in";
+print(java.lang.System[prop].class.name);
+print(java.lang.System["in"].class.name);
+
diff --git a/nashorn/test/script/basic/stdin.js.EXPECTED b/nashorn/test/script/basic/stdin.js.EXPECTED
new file mode 100644
index 0000000..c6016a6
--- /dev/null
+++ b/nashorn/test/script/basic/stdin.js.EXPECTED
@@ -0,0 +1,3 @@
+java.io.BufferedInputStream
+java.io.BufferedInputStream
+java.io.BufferedInputStream
diff --git a/nashorn/test/script/basic/strings.js b/nashorn/test/script/basic/strings.js
new file mode 100644
index 0000000..87aff31
--- /dev/null
+++ b/nashorn/test/script/basic/strings.js
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+/**
+ * Basic String constructor tests.
+ *
+ * @test
+ * @run
+ */
+
+var s = new String("javascript");
+print(s.length);
+
+// construct from char codes
+print("fromCharCode.length = " + String.fromCharCode.length);
+var x = String.fromCharCode(65, 66, 67, 68);
+print(x);
+
+// print(String.prototype.concat);
+print("concat.length = " + String.prototype.concat.length);
+print(s.concat(" is great!"));
+
+print("slice.length = " + String.prototype.slice.length);
+print("hello world".slice(-6));
+print("hello world".slice(7, 10));
+
+print("substring.length = " + String.prototype.substring.length);
+print(s.substring(0, 4));
+print(s.substring(4));
+print(s.substring(10, 4));
+
+print("toLowerCase.length = " + String.prototype.toLowerCase.length);
+print("JAVA".toLowerCase());
+print("JAVA".toLocaleLowerCase());
+print("toUpperCase.length = " + String.prototype.toUpperCase.length);
+print("javascript".toUpperCase());
+print("javascript".toLocaleUpperCase());
+
+print("localeCompare.length = " + String.prototype.localeCompare.length);
+print("java".localeCompare("JAVA"));
+print("java".localeCompare("java"));
+
+print("trim.length = " + String.prototype.trim.length);
+print(" java ".trim());
+print("java".trim());
+
+print("hello".indexOf("l"));
+print("hello".lastIndexOf("l"));
+
+// we can call java.lang.String methods on JS Strings.
+
+print("hello".endsWith("lo"));
+print("hello".startsWith("hell"));
+print("hello".startsWith("lo"));
+print("hello".endsWith("hell"));
+
+// we can access string's characters with array-like indexing..
+
+print("hello"[0]);
+print("hello"[2]);
+print("hello"[100]);  // undefined
+
+print('foo' === 'foo');
+print('foo' !== 'foo');
+print('' === '');
+print('' !== '');
+
diff --git a/nashorn/test/script/basic/strings.js.EXPECTED b/nashorn/test/script/basic/strings.js.EXPECTED
new file mode 100644
index 0000000..f22d4ba
--- /dev/null
+++ b/nashorn/test/script/basic/strings.js.EXPECTED
@@ -0,0 +1,37 @@
+10
+fromCharCode.length = 1
+ABCD
+concat.length = 1
+javascript is great!
+slice.length = 2
+ world
+orl
+substring.length = 2
+java
+script
+script
+toLowerCase.length = 0
+java
+java
+toUpperCase.length = 0
+JAVASCRIPT
+JAVASCRIPT
+localeCompare.length = 1
+-1
+0
+trim.length = 0
+java
+java
+2
+3
+true
+true
+false
+false
+h
+l
+undefined
+true
+false
+true
+false
diff --git a/nashorn/test/script/basic/throws.js b/nashorn/test/script/basic/throws.js
new file mode 100644
index 0000000..30647e4
--- /dev/null
+++ b/nashorn/test/script/basic/throws.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * Verify that throws is not a reserved keyword
+ *
+ * @test
+ * @run
+ */
+
+var throws = function() { print('i throw'); }
+throws();
+
diff --git a/nashorn/test/script/basic/throws.js.EXPECTED b/nashorn/test/script/basic/throws.js.EXPECTED
new file mode 100644
index 0000000..634ee9f
--- /dev/null
+++ b/nashorn/test/script/basic/throws.js.EXPECTED
@@ -0,0 +1 @@
+i throw
diff --git a/nashorn/test/script/basic/tosource.js b/nashorn/test/script/basic/tosource.js
new file mode 100644
index 0000000..ad6cfcc
--- /dev/null
+++ b/nashorn/test/script/basic/tosource.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test Function.prototype.toSource.
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    print("hello world");
+}
+
+print(func.toSource());
+
+var obj = { run: function() { print("run"); } };
+print(obj.run.toSource());
diff --git a/nashorn/test/script/basic/tosource.js.EXPECTED b/nashorn/test/script/basic/tosource.js.EXPECTED
new file mode 100644
index 0000000..609305c
--- /dev/null
+++ b/nashorn/test/script/basic/tosource.js.EXPECTED
@@ -0,0 +1,4 @@
+function func() {
+    print("hello world");
+}
+function() { print("run"); }
diff --git a/nashorn/test/script/basic/tostring.js b/nashorn/test/script/basic/tostring.js
new file mode 100644
index 0000000..80e6b0f
--- /dev/null
+++ b/nashorn/test/script/basic/tostring.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * Make sure that then internal ToString procedure works as expected.
+ *
+ * @test
+ * @run
+ */
+
+function show(obj) {
+    print(typeof(obj) + ", " + obj);
+}
+
+var obj = {};
+show(obj);
+obj = new Boolean(false);
+show(obj);
+obj = new Number(Math.PI);
+show(obj);
+obj = new String("hello");
+show(obj);
+obj = java.util;
+show(obj);
+obj = java.util.Map;
+show(obj);
+// For java objects, java.lang.Object.toString is called.
+obj = new java.util.HashMap();
+// should print "{}" for empty map
+show(obj);
+// should print "[]" for empty list
+obj = new java.util.ArrayList();
+show(obj);
diff --git a/nashorn/test/script/basic/tostring.js.EXPECTED b/nashorn/test/script/basic/tostring.js.EXPECTED
new file mode 100644
index 0000000..9a11e6f
--- /dev/null
+++ b/nashorn/test/script/basic/tostring.js.EXPECTED
@@ -0,0 +1,8 @@
+object, [object Object]
+object, false
+object, 3.141592653589793
+object, hello
+object, [object JavaPackage]
+function, [JavaClass java.util.Map]
+object, {}
+object, []
diff --git a/nashorn/test/script/basic/try.js b/nashorn/test/script/basic/try.js
new file mode 100644
index 0000000..07ec43c
--- /dev/null
+++ b/nashorn/test/script/basic/try.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Try throw test.
+ *
+ * @test
+ * @run 
+ */
+
+function A() {
+    print("before try");
+    
+    try {
+        print("before throw");
+        throw "a string";
+    } catch (ex) {
+        print("catch");
+        print(ex);
+        return "correct";
+    } finally {
+        print("finally");
+    }
+    
+    return "incorrect";
+}
+
+print(A());
+
+print("done");
diff --git a/nashorn/test/script/basic/try.js.EXPECTED b/nashorn/test/script/basic/try.js.EXPECTED
new file mode 100644
index 0000000..9761ef6
--- /dev/null
+++ b/nashorn/test/script/basic/try.js.EXPECTED
@@ -0,0 +1,7 @@
+before try
+before throw
+catch
+a string
+finally
+correct
+done
diff --git a/nashorn/test/script/basic/trybreakcont.js b/nashorn/test/script/basic/trybreakcont.js
new file mode 100644
index 0000000..94bfdf1
--- /dev/null
+++ b/nashorn/test/script/basic/trybreakcont.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * This results VerifyError: Stack map does not match the one at exception handler.
+ *
+ * @test
+ * @run
+ */
+
+for (var i = 0; i < 3; i++) {
+    print(i);
+    i++;
+    try {
+        break;
+    } finally {
+        continue;
+    }
+}
diff --git a/nashorn/test/script/basic/trybreakcont.js.EXPECTED b/nashorn/test/script/basic/trybreakcont.js.EXPECTED
new file mode 100644
index 0000000..a9772a0
--- /dev/null
+++ b/nashorn/test/script/basic/trybreakcont.js.EXPECTED
@@ -0,0 +1,2 @@
+0
+2
diff --git a/nashorn/test/script/basic/trycatch.js b/nashorn/test/script/basic/trycatch.js
new file mode 100644
index 0000000..f5707e4
--- /dev/null
+++ b/nashorn/test/script/basic/trycatch.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * try catch test.
+ *
+ * @test
+ * @run 
+ */
+
+var actual = '';
+var expect = '';
+
+test();
+
+function test() {
+    expect = true;
+    
+    try {
+        actual = true;
+    }
+    catch(ex) {
+        actual = ex + '';
+    }
+    
+    print(actual);
+}
diff --git a/nashorn/test/script/basic/trycatch.js.EXPECTED b/nashorn/test/script/basic/trycatch.js.EXPECTED
new file mode 100644
index 0000000..27ba77d
--- /dev/null
+++ b/nashorn/test/script/basic/trycatch.js.EXPECTED
@@ -0,0 +1 @@
+true
diff --git a/nashorn/test/script/basic/trycatchfor.js b/nashorn/test/script/basic/trycatchfor.js
new file mode 100644
index 0000000..a8c2d09
--- /dev/null
+++ b/nashorn/test/script/basic/trycatchfor.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This crashes with VerifyError: Instruction type does not match stack map.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    for(var i =0; i < 10; i++) {
+    } 
+} catch (e) {
+}
+
+print("done");
diff --git a/nashorn/test/script/basic/trycatchfor.js.EXPECTED b/nashorn/test/script/basic/trycatchfor.js.EXPECTED
new file mode 100644
index 0000000..19f86f4
--- /dev/null
+++ b/nashorn/test/script/basic/trycatchfor.js.EXPECTED
@@ -0,0 +1 @@
+done
diff --git a/nashorn/test/script/basic/tryfinallyreturn.js b/nashorn/test/script/basic/tryfinallyreturn.js
new file mode 100644
index 0000000..bc79146
--- /dev/null
+++ b/nashorn/test/script/basic/tryfinallyreturn.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * This results in VerifierError: Bad local variable type.
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    var x = 1;
+    try {
+        return x;
+    } catch(e) {
+        print(e);
+    } finally {
+        return x;
+    }
+}
+
+print(func());
+print("done");
+
diff --git a/nashorn/test/script/basic/tryfinallyreturn.js.EXPECTED b/nashorn/test/script/basic/tryfinallyreturn.js.EXPECTED
new file mode 100644
index 0000000..3e50f7e
--- /dev/null
+++ b/nashorn/test/script/basic/tryfinallyreturn.js.EXPECTED
@@ -0,0 +1,2 @@
+1
+done
diff --git a/nashorn/test/script/basic/tryforbreak.js b/nashorn/test/script/basic/tryforbreak.js
new file mode 100644
index 0000000..04d8de3
--- /dev/null
+++ b/nashorn/test/script/basic/tryforbreak.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * This results in VerifyError: Inconsistent stackmap frames at branch target.
+ *
+ * @test
+ * @run
+ */
+
+try {
+    for(i = 0; i < 3; i++) {
+        break;
+    };	
+} catch (e) {	
+}
+
+print("done");
diff --git a/nashorn/test/script/basic/tryforbreak.js.EXPECTED b/nashorn/test/script/basic/tryforbreak.js.EXPECTED
new file mode 100644
index 0000000..19f86f4
--- /dev/null
+++ b/nashorn/test/script/basic/tryforbreak.js.EXPECTED
@@ -0,0 +1 @@
+done
diff --git a/nashorn/test/script/basic/typechange.js b/nashorn/test/script/basic/typechange.js
new file mode 100644
index 0000000..ff416f8
--- /dev/null
+++ b/nashorn/test/script/basic/typechange.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * This test crashes with VerifyError (bad type on stack).
+ * 
+ * @test
+ * @run
+ */
+
+x = 1;
+x = new Number(1);
+print(x);
diff --git a/nashorn/test/script/basic/typechange.js.EXPECTED b/nashorn/test/script/basic/typechange.js.EXPECTED
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nashorn/test/script/basic/typechange.js.EXPECTED
@@ -0,0 +1 @@
+1
diff --git a/nashorn/test/script/basic/typecoerce.js b/nashorn/test/script/basic/typecoerce.js
new file mode 100644
index 0000000..ba95e6a
--- /dev/null
+++ b/nashorn/test/script/basic/typecoerce.js
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/**
+ * There was a bug in the old Lower that didn't fully propagate type information
+ * by way of assignment. 'q' in the example below would have finished a double
+ * even though it can get an object value through the assignment 'q = l' 
+ * 
+ * Furthermore, this caused type coercion to be done at q = l, and not a q = q * 2, 
+ * which is a bug. This test ensures it happens in the correct order
+ *
+ * @test
+ * @run
+ */
+
+function createObject() {
+    var obj = { valueOf: function() { print("toNumber coercion"); return 17; }}
+    return obj;
+}
+
+function f() {
+    var l = 1.2; //number
+    var q = 2.3; //number
+    for (var i = 0; i < 2; i++) {
+	q = l; // q = toNumber(l), no coercion here
+	print("assignment done");
+	q = q * 2; // q = q * 2, coercion here
+	print("multiplication done");
+	l = createObject();
+    }
+}
+
+f();
diff --git a/nashorn/test/script/basic/typecoerce.js.EXPECTED b/nashorn/test/script/basic/typecoerce.js.EXPECTED
new file mode 100644
index 0000000..619fc74
--- /dev/null
+++ b/nashorn/test/script/basic/typecoerce.js.EXPECTED
@@ -0,0 +1,5 @@
+assignment done
+multiplication done
+assignment done
+toNumber coercion
+multiplication done
diff --git a/nashorn/test/script/basic/typeof.js b/nashorn/test/script/basic/typeof.js
new file mode 100644
index 0000000..15c9f81
--- /dev/null
+++ b/nashorn/test/script/basic/typeof.js
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * Typeof test.
+ *
+ * @test
+ * @run 
+ */
+
+var x = { a: 1, b: "string", c: [1, 2, 3], d: function() {} };
+
+var MyObject = function() {
+    this.a = 10;
+}
+
+var y = new MyObject();
+
+print(typeof x);
+print(typeof x.a);
+print(typeof x.b);
+print(typeof x.c);
+print(typeof x.d);
+print(typeof x.e);
+print(typeof y);
+
+
diff --git a/nashorn/test/script/basic/typeof.js.EXPECTED b/nashorn/test/script/basic/typeof.js.EXPECTED
new file mode 100644
index 0000000..2028137
--- /dev/null
+++ b/nashorn/test/script/basic/typeof.js.EXPECTED
@@ -0,0 +1,7 @@
+object
+number
+string
+object
+function
+undefined
+object
diff --git a/nashorn/test/script/basic/typeof2.js b/nashorn/test/script/basic/typeof2.js
new file mode 100644
index 0000000..248fabf
--- /dev/null
+++ b/nashorn/test/script/basic/typeof2.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * typeof second round.
+ *
+ * @test
+ * @run
+ */
+
+var o = {a: 10, b: 20, c: 30};
+var p = "string";
+
+print(typeof undefined);
+print(typeof true);
+print(typeof 10.0);
+print(typeof "string");
+print(typeof o);
+print(typeof [1, 2, 3]);
+print(typeof o.a);
+print(typeof p);
+print(typeof o.d);
+print(typeof o["d"]);
+print(typeof this["q"]);
+print(typeof this.q);
diff --git a/nashorn/test/script/basic/typeof2.js.EXPECTED b/nashorn/test/script/basic/typeof2.js.EXPECTED
new file mode 100644
index 0000000..3294b36
--- /dev/null
+++ b/nashorn/test/script/basic/typeof2.js.EXPECTED
@@ -0,0 +1,12 @@
+undefined
+boolean
+number
+string
+object
+object
+number
+string
+undefined
+undefined
+undefined
+undefined
diff --git a/nashorn/test/script/basic/undefined.js b/nashorn/test/script/basic/undefined.js
new file mode 100644
index 0000000..b949eec
--- /dev/null
+++ b/nashorn/test/script/basic/undefined.js
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check that trying to operate on results in exception.
+ *
+ * @test
+ * @run
+ */
+
+var x;
+
+print("x undefined? " + (x === undefined));
+
+try {
+    print(x.foo);
+} catch (e) {
+    print(e);
+}
+
+try {
+    x.bar = 34;
+} catch (e) {
+    print(e);
+}
+
+try {
+    print(x[1]);
+} catch (e) {
+    print(e);
+}
+
+try {
+    x[0] = 12;
+} catch (e) {
+    print(e);
+}
+
+try {
+    x.func();
+} catch(e) {
+    print(e);
+}
+
+try {
+    delete x[0];
+} catch (e) {
+    print(e);
+}
+
+try {
+    delete x.foo;
+} catch (e) {
+    print(e);
+}
+
+try {
+    print(Object.getPrototypeOf(x));
+} catch (e) {
+    print(e);
+}
+
+// iteration should be empty
+for (y in x) {
+    print(y);
+}
+
+try {
+    with (x) {
+        print(foo);
+    }
+} catch (e) {
+    print(e);
+}
diff --git a/nashorn/test/script/basic/undefined.js.EXPECTED b/nashorn/test/script/basic/undefined.js.EXPECTED
new file mode 100644
index 0000000..4bfd3e8
--- /dev/null
+++ b/nashorn/test/script/basic/undefined.js.EXPECTED
@@ -0,0 +1,10 @@
+x undefined? true
+TypeError: Cannot read property "foo" from undefined
+TypeError: Cannot set property "bar" of undefined
+TypeError: Cannot read property "1" from undefined
+TypeError: Cannot set property "0" of undefined
+TypeError: Cannot read property "func" from undefined
+TypeError: Cannot delete property "0" of undefined
+TypeError: Cannot delete property "foo" of undefined
+TypeError: undefined is not an Object
+TypeError: Cannot apply "with" to undefined
diff --git a/nashorn/test/script/basic/underscore.js b/nashorn/test/script/basic/underscore.js
new file mode 100644
index 0000000..064e525
--- /dev/null
+++ b/nashorn/test/script/basic/underscore.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-466 : corpus parse test for underscore
+ * 
+ * @test
+ * @runif external.underscore
+ */
+
+try {
+    var file = __DIR__ + '../external/underscore/underscore.js';
+    load(__DIR__ + '../external/underscore/underscore.js');
+    print("parsed and compiled ok");
+} catch (e) {
+    print("error: " + e);
+}
diff --git a/nashorn/test/script/basic/underscore.js.EXPECTED b/nashorn/test/script/basic/underscore.js.EXPECTED
new file mode 100644
index 0000000..9ae0d06
--- /dev/null
+++ b/nashorn/test/script/basic/underscore.js.EXPECTED
@@ -0,0 +1 @@
+parsed and compiled ok
diff --git a/nashorn/test/script/basic/varargs.js b/nashorn/test/script/basic/varargs.js
new file mode 100644
index 0000000..0284413
--- /dev/null
+++ b/nashorn/test/script/basic/varargs.js
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/**
+ * Var args test.
+ *
+ * @test
+ * @run 
+ */
+function varFunc(a, b, c) {
+    print(a, b, c);
+    print(Object.getPrototypeOf(arguments) === Object.prototype);
+    print(arguments[0], arguments[1], arguments[2]);
+
+    for (var i in arguments) {
+        print(arguments[i]);
+    }
+
+    print(arguments.callee);
+}
+
+function myFunc(a, b, c) {
+    print(a, b, c);
+}
+
+print("aaaa", "bbbb", "cccc");
+print("aaaa", "bbbb");
+print("aaaa", "bbbb", "cccc", "dddd");
+
+myFunc("aaaa", "bbbb", "cccc");
+myFunc("aaaa", "bbbb");
+myFunc("aaaa", "bbbb", "cccc", "dddd");
+
+varFunc("aaaa", "bbbb", "cccc");
+varFunc("aaaa", "bbbb");
+varFunc("aaaa", "bbbb", "cccc", "dddd");
diff --git a/nashorn/test/script/basic/varargs.js.EXPECTED b/nashorn/test/script/basic/varargs.js.EXPECTED
new file mode 100644
index 0000000..08c4fdc
--- /dev/null
+++ b/nashorn/test/script/basic/varargs.js.EXPECTED
@@ -0,0 +1,57 @@
+aaaa bbbb cccc
+aaaa bbbb
+aaaa bbbb cccc dddd
+aaaa bbbb cccc
+aaaa bbbb undefined
+aaaa bbbb cccc
+aaaa bbbb cccc
+true
+aaaa bbbb cccc
+aaaa
+bbbb
+cccc
+function varFunc(a, b, c) {
+    print(a, b, c);
+    print(Object.getPrototypeOf(arguments) === Object.prototype);
+    print(arguments[0], arguments[1], arguments[2]);
+
+    for (var i in arguments) {
+        print(arguments[i]);
+    }
+
+    print(arguments.callee);
+}
+aaaa bbbb undefined
+true
+aaaa bbbb undefined
+aaaa
+bbbb
+function varFunc(a, b, c) {
+    print(a, b, c);
+    print(Object.getPrototypeOf(arguments) === Object.prototype);
+    print(arguments[0], arguments[1], arguments[2]);
+
+    for (var i in arguments) {
+        print(arguments[i]);
+    }
+
+    print(arguments.callee);
+}
+aaaa bbbb cccc
+true
+aaaa bbbb cccc
+aaaa
+bbbb
+cccc
+dddd
+function varFunc(a, b, c) {
+    print(a, b, c);
+    print(Object.getPrototypeOf(arguments) === Object.prototype);
+    print(arguments[0], arguments[1], arguments[2]);
+
+    for (var i in arguments) {
+        print(arguments[i]);
+    }
+
+    print(arguments.callee);
+}
diff --git a/nashorn/test/script/basic/void.js b/nashorn/test/script/basic/void.js
new file mode 100644
index 0000000..957f954
--- /dev/null
+++ b/nashorn/test/script/basic/void.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * Checks with void.
+ *
+ * @test
+ * @run
+ */
+
+print(void 0);
+print(void 0/0);
+print(void 123);
+print(void "string");
+print(void null);
+
+print(typeof(void 0));
+print(3 == void 0);
+var x = (33 == void 0);
+print(x);
+
diff --git a/nashorn/test/script/basic/void.js.EXPECTED b/nashorn/test/script/basic/void.js.EXPECTED
new file mode 100644
index 0000000..bc27faf
--- /dev/null
+++ b/nashorn/test/script/basic/void.js.EXPECTED
@@ -0,0 +1,8 @@
+undefined
+NaN
+undefined
+undefined
+undefined
+undefined
+false
+false
\ No newline at end of file
diff --git a/nashorn/test/script/basic/with.js b/nashorn/test/script/basic/with.js
new file mode 100644
index 0000000..1ae8113
--- /dev/null
+++ b/nashorn/test/script/basic/with.js
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/**
+ * With test.
+ *
+ * @test
+ * @run 
+ */
+
+var x = {a: 10, b: 20, c: 30};
+
+var b = "here";
+
+print(b);
+print(x.b);
+
+with (x) {
+    print(b);
+    print(x.b);
+    
+    b = false;
+    
+    print(b);
+    print(x.b);
+    
+    y = 200;
+}
+
+print(b);
+print(x.b);
+
+for (i in x) print(i, x[i]);
+
+var obj = { 
+    __noSuchProperty__: function(name) {
+        return name.toUpperCase();
+    }   
+};
+
+with(obj) {
+  print(foo);
+  print(bar);
+}
diff --git a/nashorn/test/script/basic/with.js.EXPECTED b/nashorn/test/script/basic/with.js.EXPECTED
new file mode 100644
index 0000000..8f14f31
--- /dev/null
+++ b/nashorn/test/script/basic/with.js.EXPECTED
@@ -0,0 +1,13 @@
+here
+20
+20
+20
+false
+false
+here
+false
+a 10
+b false
+c 30
+FOO
+BAR
diff --git a/nashorn/test/script/basic/withprimitive.js b/nashorn/test/script/basic/withprimitive.js
new file mode 100644
index 0000000..a0ee021
--- /dev/null
+++ b/nashorn/test/script/basic/withprimitive.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Using "with" statement with primitive typed value as scope object.
+ * Results in VerifyError: Bad type on operand stack.
+ * 
+ * @test
+ * @run
+ */
+
+var obj = 2;
+
+with (obj) {
+   foo = 42;
+}
+
+print(foo);
diff --git a/nashorn/test/script/basic/withprimitive.js.EXPECTED b/nashorn/test/script/basic/withprimitive.js.EXPECTED
new file mode 100644
index 0000000..d81cc07
--- /dev/null
+++ b/nashorn/test/script/basic/withprimitive.js.EXPECTED
@@ -0,0 +1 @@
+42
diff --git a/nashorn/test/script/basic/writable_relink.js b/nashorn/test/script/basic/writable_relink.js
new file mode 100644
index 0000000..ebc8a3b
--- /dev/null
+++ b/nashorn/test/script/basic/writable_relink.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check relinking after making property to be non-writable.
+ *
+ * @test
+ * @run
+ */
+
+var obj = { namex: 120 };
+
+for (i=0; i < 4; i++) {
+    obj.namex = "xxx " + i;
+    // should print the same value -
+    // as subsequent writes are ignored.
+    print(obj.namex);
+    Object.defineProperty(obj, "namex",
+        { writable: false });
+}
+
diff --git a/nashorn/test/script/basic/writable_relink.js.EXPECTED b/nashorn/test/script/basic/writable_relink.js.EXPECTED
new file mode 100644
index 0000000..3f2afac
--- /dev/null
+++ b/nashorn/test/script/basic/writable_relink.js.EXPECTED
@@ -0,0 +1,4 @@
+xxx 0
+xxx 0
+xxx 0
+xxx 0
diff --git a/nashorn/test/script/basic/xmlStrings.js.EXPECTED b/nashorn/test/script/basic/xmlStrings.js.EXPECTED
new file mode 100644
index 0000000..b17b1da
--- /dev/null
+++ b/nashorn/test/script/basic/xmlStrings.js.EXPECTED
@@ -0,0 +1,23 @@
+<empty/>
+[#document: null]
+<empty/>
+true
+empty
+empty
+
+foo
+2
+v1
+v2
+some text
+true
+<foo a1="v1" a2="v2">some text</foo>
+
+namespace
+default.namespace
+ns:child
+ns
+other.namespace
+ns:type
+ns
+other.namespace
diff --git a/nashorn/test/script/basic/xorassign.js b/nashorn/test/script/basic/xorassign.js
new file mode 100644
index 0000000..1cb73b6
--- /dev/null
+++ b/nashorn/test/script/basic/xorassign.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The following crashes with VerifyError. 
+ *
+ * @test
+ * @run
+ */
+
+try {
+    var z = (x ^= 1);
+    print(z);
+} catch (e) {
+    print("x not defined, error expected");
+}
+
diff --git a/nashorn/test/script/basic/xorassign.js.EXPECTED b/nashorn/test/script/basic/xorassign.js.EXPECTED
new file mode 100644
index 0000000..1bd4571
--- /dev/null
+++ b/nashorn/test/script/basic/xorassign.js.EXPECTED
@@ -0,0 +1 @@
+x not defined, error expected
diff --git a/nashorn/test/script/basic/yield.js b/nashorn/test/script/basic/yield.js
new file mode 100644
index 0000000..935f640
--- /dev/null
+++ b/nashorn/test/script/basic/yield.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * Check yield keyword is parsed and yield statement does nothing (yet).
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    yield 2;
+}
diff --git a/nashorn/test/script/basic/yui.js b/nashorn/test/script/basic/yui.js
new file mode 100644
index 0000000..879fb57
--- /dev/null
+++ b/nashorn/test/script/basic/yui.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-469 : corpus parse test for yahoo ui library / yahoo ui library min
+ * 
+ * @test
+ * @runif external.yui
+ */
+
+var names = [ "yui-min.js", "yui.js" ];
+
+for each (name in names) { 
+    try {
+	try {
+            var file = __DIR__ + "../external/yui/" + name;
+	    load(__DIR__ + "../external/yui/" + name);
+	} catch (e) { 
+	    print(e);
+	}
+    } catch (e) {
+	print("error: " + e);
+    }
+    print("parsed and compiled ok " + name);
+}
diff --git a/nashorn/test/script/basic/yui.js.EXPECTED b/nashorn/test/script/basic/yui.js.EXPECTED
new file mode 100644
index 0000000..28dd1b9
--- /dev/null
+++ b/nashorn/test/script/basic/yui.js.EXPECTED
@@ -0,0 +1,2 @@
+parsed and compiled ok yui-min.js
+parsed and compiled ok yui.js
diff --git a/nashorn/test/script/currently-failing/JDK-8006191.js b/nashorn/test/script/currently-failing/JDK-8006191.js
new file mode 100644
index 0000000..b856c71
--- /dev/null
+++ b/nashorn/test/script/currently-failing/JDK-8006191.js
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+/**
+ * JDK-8006191 - `cmd` -> exec("cmd") in script mode
+ *
+ * @test
+ * @option -scripting
+ * @argument ArgumentFromCommandLine
+ * @run 
+ */
+
+#!/usr/bin/jjs
+
+$ENV.PWD = ".";
+print($ENV.PWD);
+
+var files = `ls`.trim().split("\n");
+for (var i in files) {
+    var file = files[i];
+    if (file.contains("README")) {
+        print(file);
+    }
+}
+
+var result = $EXEC("cat", <<EOD);
+This is a bunch of stuff
+that I want written out
+including ${$ARG[0]}
+EOD
+print(result);
+print($OUT);
+
+var arg = "-Q";
+`ls ${arg}`;
+print($ERR);
+print($EXIT);
diff --git a/nashorn/test/script/currently-failing/JDK-8006191.js.EXPECTED b/nashorn/test/script/currently-failing/JDK-8006191.js.EXPECTED
new file mode 100644
index 0000000..f025462
--- /dev/null
+++ b/nashorn/test/script/currently-failing/JDK-8006191.js.EXPECTED
@@ -0,0 +1,14 @@
+.
+README
+RELEASE_README
+THIRD_PARTY_README
+This is a bunch of stuff
+that I want written out
+including ArgumentFromCommandLine
+This is a bunch of stuff
+that I want written out
+including ArgumentFromCommandLine
+ls: illegal option -- Q
+usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1] [file ...]
+
+1
diff --git a/nashorn/test/script/currently-failing/JDK-8006529.js b/nashorn/test/script/currently-failing/JDK-8006529.js
new file mode 100644
index 0000000..da08d2b
--- /dev/null
+++ b/nashorn/test/script/currently-failing/JDK-8006529.js
@@ -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')
diff --git a/nashorn/test/script/error/NASHORN-154/README b/nashorn/test/script/error/NASHORN-154/README
new file mode 100644
index 0000000..06f503d
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/README
@@ -0,0 +1,6 @@
+Section 16 of ECMAScript 5.1 spec details a set of "early errors". Early
+errors should be reported before running any line of the script containing
+such error(s). Examples include syntax error, errors in regexp literals etc.
+This directory contains tests to check early errors are reported as early
+errors. Each test starts with a print call -- the output from print should 
+not be seen in expected output. If seen, early errors are reported late.
diff --git a/nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js b/nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js
new file mode 100644
index 0000000..12b1669
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Early error reporting.
+ *
+ * The occurrence of an Identifier value appearing more than once within a 
+ * FormalParameterList of an individual strict mode FunctionDeclaration or 
+ * FunctionExpression
+ *
+ * @test/compile-error
+ */
+
+'use strict';
+
+print(__FILE__ + " @" + __LINE__);
+
+function func(x, x) {}
diff --git a/nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js.EXPECTED b/nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js.EXPECTED
new file mode 100644
index 0000000..bda3808
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js.EXPECTED
@@ -0,0 +1,3 @@
+test/script/error/NASHORN-154/function_mult_params_in_strict.js:38:14 strict mode function cannot have duplicate parameter name "x"
+function func(x, x) {}
+              ^
diff --git a/nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js b/nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js
new file mode 100644
index 0000000..7496d77
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Early error reporting.
+ *
+ * Improper uses of return, break, and continue
+ *
+ * @test/compile-error
+ */
+
+print(__FILE__ + " @" + __LINE__);
+
+return 33;
+
+continue;
+break;
+
+continue nonExist;
+break nonExist;
diff --git a/nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js.EXPECTED b/nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js.EXPECTED
new file mode 100644
index 0000000..ffccb5d
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js.EXPECTED
@@ -0,0 +1,15 @@
+test/script/error/NASHORN-154/improper_return_break_continue.js:34:0 Invalid return statement
+return 33;
+^
+test/script/error/NASHORN-154/improper_return_break_continue.js:36:0 Illegal continue statement
+continue;
+^
+test/script/error/NASHORN-154/improper_return_break_continue.js:37:0 Illegal break statement
+break;
+^
+test/script/error/NASHORN-154/improper_return_break_continue.js:39:9 Undefined Label "nonExist"
+continue nonExist;
+         ^
+test/script/error/NASHORN-154/improper_return_break_continue.js:40:6 Undefined Label "nonExist"
+break nonExist;
+      ^
diff --git a/nashorn/test/script/error/NASHORN-154/invalid_lvalue.js b/nashorn/test/script/error/NASHORN-154/invalid_lvalue.js
new file mode 100644
index 0000000..ce28462
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/invalid_lvalue.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * Early error reporting.
+ *
+ * Attempts to call PutValue on any value for which an early determination can 
+ * be made that the value is not a Reference (for example, executing the 
+ * assignment statement 3=4).
+ *
+ * @test/compile-error
+ */
+
+print(__FILE__ + " @" + __LINE__);
+
+3 = 4;
+2 + 44 = 3;
+x * y = 33;
+x / y = 23;
+x++ /= 33
+--y *= 3;
+
diff --git a/nashorn/test/script/error/NASHORN-154/invalid_lvalue.js.EXPECTED b/nashorn/test/script/error/NASHORN-154/invalid_lvalue.js.EXPECTED
new file mode 100644
index 0000000..7532fe0
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/invalid_lvalue.js.EXPECTED
@@ -0,0 +1,15 @@
+test/script/error/NASHORN-154/invalid_lvalue.js:36:0 Invalid left hand side for assignment
+3 = 4;
+^
+test/script/error/NASHORN-154/invalid_lvalue.js:37:2 Invalid left hand side for assignment
+2 + 44 = 3;
+  ^
+test/script/error/NASHORN-154/invalid_lvalue.js:38:2 Invalid left hand side for assignment
+x * y = 33;
+  ^
+test/script/error/NASHORN-154/invalid_lvalue.js:39:2 Invalid left hand side for assignment
+x / y = 23;
+  ^
+test/script/error/NASHORN-154/invalid_lvalue.js:40:1 Invalid left hand side for assignment
+x++ /= 33
+ ^
diff --git a/nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js b/nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js
new file mode 100644
index 0000000..4a236f1
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Early error reporting.
+ *
+ * Attempts to define an ObjectLiteral that has both a data property assignment and a get or set property assignment with the same name.
+ *
+ * @test/compile-error
+ */
+
+print(__FILE__ + " @" + __LINE__);
+
+// should result in early error - foo as data and accessor property
+var obj = { foo: 42, get foo() { return 'hello' } };
+
+// should result in early error - foo as data and accessor property
+var obj2 = { foo: 42, set foo(x) { } };
diff --git a/nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js.EXPECTED b/nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js.EXPECTED
new file mode 100644
index 0000000..05585fb
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js.EXPECTED
@@ -0,0 +1,6 @@
+test/script/error/NASHORN-154/literal_data_and_accessor.js:35:21 Property "foo" already defined
+var obj = { foo: 42, get foo() { return 'hello' } };
+                     ^
+test/script/error/NASHORN-154/literal_data_and_accessor.js:38:22 Property "foo" already defined
+var obj2 = { foo: 42, set foo(x) { } };
+                      ^
diff --git a/nashorn/test/script/error/NASHORN-154/literal_mult_getters.js b/nashorn/test/script/error/NASHORN-154/literal_mult_getters.js
new file mode 100644
index 0000000..8777b61
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/literal_mult_getters.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Early error reporting.
+ *
+ * Attempts to define an ObjectLiteral that has multiple get property 
+ * assignments with the same name or multiple set property assignments with 
+ * the same name.
+ *
+ * @test/compile-error
+ */
+
+print(__FILE__ + " @" + __LINE__);
+
+var obj = { get foo() { return 2; }, get foo() { return 'hello'; } };
diff --git a/nashorn/test/script/error/NASHORN-154/literal_mult_getters.js.EXPECTED b/nashorn/test/script/error/NASHORN-154/literal_mult_getters.js.EXPECTED
new file mode 100644
index 0000000..7031c69
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/literal_mult_getters.js.EXPECTED
@@ -0,0 +1,3 @@
+test/script/error/NASHORN-154/literal_mult_getters.js:36:37 Property "foo" already defined
+var obj = { get foo() { return 2; }, get foo() { return 'hello'; } };
+                                     ^
diff --git a/nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js b/nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js
new file mode 100644
index 0000000..30d3fad
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Early error reporting.
+ *
+ * Attempts in strict mode code to define an ObjectLiteral that has multiple 
+ * data property assignments with the same name.
+ *
+ * @test/compile-error
+ */
+
+'use strict';
+
+print(__FILE__ + " @" + __LINE__);
+
+var obj = { foo: 42, foo: 'hello' };
diff --git a/nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js.EXPECTED b/nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js.EXPECTED
new file mode 100644
index 0000000..dfb2e7b
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js.EXPECTED
@@ -0,0 +1,3 @@
+test/script/error/NASHORN-154/literal_mult_prop_in_strict.js:37:21 Property "foo" already defined
+var obj = { foo: 42, foo: 'hello' };
+                     ^
diff --git a/nashorn/test/script/error/NASHORN-154/with_in_strict.js b/nashorn/test/script/error/NASHORN-154/with_in_strict.js
new file mode 100644
index 0000000..866c822
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/with_in_strict.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Early error reporting.
+ *
+ * The occurrence of a WithStatement in strict mode code.
+ *
+ * @test/compile-error
+ */
+
+'use strict';
+
+print(__FILE__ + " @" + __LINE__);
+
+with({}) {
+    print("hello world");
+}
diff --git a/nashorn/test/script/error/NASHORN-154/with_in_strict.js.EXPECTED b/nashorn/test/script/error/NASHORN-154/with_in_strict.js.EXPECTED
new file mode 100644
index 0000000..7e5103d
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-154/with_in_strict.js.EXPECTED
@@ -0,0 +1,9 @@
+test/script/error/NASHORN-154/with_in_strict.js:36:0 "with" statement cannot be used in strict mode
+with({}) {
+^
+test/script/error/NASHORN-154/with_in_strict.js:36:7 Expected ; but found )
+with({}) {
+       ^
+test/script/error/NASHORN-154/with_in_strict.js:38:0 Expected eof but found }
+}
+^
diff --git a/nashorn/test/script/error/NASHORN-214.js b/nashorn/test/script/error/NASHORN-214.js
new file mode 100644
index 0000000..afffec2
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-214.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-214 :  Syntax error thrown instead of ReferenceError when LHS is not assignable
+ *
+ * @test
+ * @option --early-lvalue-error=false
+ * @run
+ */
+
+print('hello');
+try {
+    true = 334; // ReferenceError thrown when control reaches here
+} catch (e) {
+    print(e);
+}
+
+x = 'hello';
+if (typeof x === 'number') {
+    true = 44; // not reached, so no error thrown
+} else {
+    print('x is not a number');
+}
diff --git a/nashorn/test/script/error/NASHORN-214.js.EXPECTED b/nashorn/test/script/error/NASHORN-214.js.EXPECTED
new file mode 100644
index 0000000..83503a2
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-214.js.EXPECTED
@@ -0,0 +1,3 @@
+hello
+ReferenceError: "true" can not be used as the left-hand side of assignment
+x is not a number
diff --git a/nashorn/test/script/error/NASHORN-35.js b/nashorn/test/script/error/NASHORN-35.js
new file mode 100644
index 0000000..314cd3a
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-35.js
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-35:  when 'new' keyword is used as LHS in an assignment, compiler crashes with NPE.
+ *
+ * @test/compile-error
+ */
+
+new = 1;
+
+
diff --git a/nashorn/test/script/error/NASHORN-35.js.EXPECTED b/nashorn/test/script/error/NASHORN-35.js.EXPECTED
new file mode 100644
index 0000000..dca745e
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-35.js.EXPECTED
@@ -0,0 +1,3 @@
+test/script/error/NASHORN-35.js:30:4 Expected an operand but found =
+new = 1;
+    ^
diff --git a/nashorn/test/script/error/NASHORN-39.js b/nashorn/test/script/error/NASHORN-39.js
new file mode 100644
index 0000000..59f4a4a
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-39.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-39 : Line terminator between throw keyword and throw expression crashes the compiler.
+ *
+ * @test/compile-error
+ */
+
+// line terminator here should result in compiler error.
+
+throw 
+  1;
diff --git a/nashorn/test/script/error/NASHORN-39.js.EXPECTED b/nashorn/test/script/error/NASHORN-39.js.EXPECTED
new file mode 100644
index 0000000..7d68bdd
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-39.js.EXPECTED
@@ -0,0 +1,3 @@
+test/script/error/NASHORN-39.js:33:0 Expected an operand but found eol
+  1;
+^
diff --git a/nashorn/test/script/error/NASHORN-568.js b/nashorn/test/script/error/NASHORN-568.js
new file mode 100644
index 0000000..1a8159e
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-568.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-568 :  Try statement without catch or finally should throw parser error
+ *
+ * @test/compile-error
+ */
+
+try { }
diff --git a/nashorn/test/script/error/NASHORN-568.js.EXPECTED b/nashorn/test/script/error/NASHORN-568.js.EXPECTED
new file mode 100644
index 0000000..12b0adf
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-568.js.EXPECTED
@@ -0,0 +1,3 @@
+test/script/error/NASHORN-568.js:30:0 Missing catch or finally after try
+try { }
+^
diff --git a/nashorn/test/script/error/NASHORN-57.js b/nashorn/test/script/error/NASHORN-57.js
new file mode 100644
index 0000000..2dc5b15
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-57.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-57 : newline between operand and post decrement/increment operator results in NullPointerException.
+ *
+ * @test/compile-error
+ */
+
+
+var x = 1;
+
+// line terminator here should result in compiler error.
+x
+++;
diff --git a/nashorn/test/script/error/NASHORN-57.js.EXPECTED b/nashorn/test/script/error/NASHORN-57.js.EXPECTED
new file mode 100644
index 0000000..5a93b59
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-57.js.EXPECTED
@@ -0,0 +1,3 @@
+test/script/error/NASHORN-57.js:35:2 Expected statement but found ;
+++;
+  ^
diff --git a/nashorn/test/script/error/NASHORN-668.js b/nashorn/test/script/error/NASHORN-668.js
new file mode 100644
index 0000000..f332856
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-668.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-668: RegExp literal errors are early errors and so should be reported before 'runtime'
+ *
+ * @test/compile-error
+ */
+
+// this should not be printed!!
+print("hello world!!");
+
+// repeated flag
+var x = /xxx/gg;
+// unsupported flag
+var y = /xxx/X;
+// dangling metachar
+var z = /2**/;
diff --git a/nashorn/test/script/error/NASHORN-668.js.EXPECTED b/nashorn/test/script/error/NASHORN-668.js.EXPECTED
new file mode 100644
index 0000000..5a95579
--- /dev/null
+++ b/nashorn/test/script/error/NASHORN-668.js.EXPECTED
@@ -0,0 +1,11 @@
+test/script/error/NASHORN-668.js:34:15 Repeated RegExp flag: g
+var x = /xxx/gg;
+               ^
+test/script/error/NASHORN-668.js:36:14 Unsupported RegExp flag: X
+var y = /xxx/X;
+              ^
+test/script/error/NASHORN-668.js:38:13 Dangling meta character '*' near index 2
+2**
+  ^
+var z = /2**/;
+             ^
diff --git a/nashorn/test/script/error/quotemissing.js b/nashorn/test/script/error/quotemissing.js
new file mode 100644
index 0000000..74d9a3e
--- /dev/null
+++ b/nashorn/test/script/error/quotemissing.js
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * @test/compile-error
+ */
+
+print("hello);
diff --git a/nashorn/test/script/error/quotemissing.js.EXPECTED b/nashorn/test/script/error/quotemissing.js.EXPECTED
new file mode 100644
index 0000000..a9d171a
--- /dev/null
+++ b/nashorn/test/script/error/quotemissing.js.EXPECTED
@@ -0,0 +1,3 @@
+test/script/error/quotemissing.js:28:14 Missing close quote
+print("hello);
+              ^
diff --git a/nashorn/test/script/error/strictmode.js b/nashorn/test/script/error/strictmode.js
new file mode 100644
index 0000000..abdf216
--- /dev/null
+++ b/nashorn/test/script/error/strictmode.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Check that basic strict-mode working.
+ *
+ * @test
+ * @run/fail --strict-mode
+ */
+
+function func() {}
+
+// should not be able to delete non-configurable property
+delete func.length;
+
diff --git a/nashorn/test/script/error/strictmode.js.EXPECTED b/nashorn/test/script/error/strictmode.js.EXPECTED
new file mode 100644
index 0000000..67e05c6
--- /dev/null
+++ b/nashorn/test/script/error/strictmode.js.EXPECTED
@@ -0,0 +1 @@
+TypeError: "length" is not a configurable property
diff --git a/nashorn/test/script/representations/NASHORN-592a.js b/nashorn/test/script/representations/NASHORN-592a.js
new file mode 100644
index 0000000..dd75f62
--- /dev/null
+++ b/nashorn/test/script/representations/NASHORN-592a.js
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-592a: test all combos of field types and getters and setters
+ * This time use dual field representation
+ *
+ * @test
+ * @option --dual-fields
+ * @run
+ */
+
+//fortype undefined
+var a;
+
+print(a & 0xff);
+print(a >>> 1);
+print(a * 2);
+print(a + "hej!");
+
+var b;
+b = 17;   //set undefined->int
+
+print(b & 0xff);
+print(b >>> 1);
+print(b * 2);
+print(b + "hej!");
+
+var c;
+c = 17.4711 //set undefined->double
+
+print(c & 0xff);
+print(c >>> 1);
+print(c * 2);
+print(c + "hej!");
+
+var d; // set undefined->double
+d = "Fame and fortune Salamander Yahoo!";
+
+print(d & 0xff);
+print(d >>> 1);
+print(d * 2);
+print(d + "hej!");
+
+// now we have exhausted all getters and undefined->everything setters.
+
+
+var e = 23; // int to everything setters,
+e = 24;     //int to int
+print(e);
+e = (22222 >>> 1); //int to long;
+print(e);
+e = 23.23;  //int to double
+print(e);
+e = 23;     //double to int - still double
+print(e);
+print(e & 0xff);
+e = "Have some pie!" //double to string
+print(e);
+e = 4711.17;
+print(e); //still an object not a double
+
+
+var f = (23222 >>> 1); // long to everything setters,
+f = 34344 >>> 1;     //long to long
+print(f);
+f = 23; //long to int - still long
+print(f);
+f = 23.23;  //long to double
+print(f);
+f = 23;     //double to int - still double
+print(f);
+print(f & 0xff);
+f = "Have some pie!" //double to string
+print(f);
+f = 4711.17;
+print(f); //still an object not a double
+
+var g = 4811.16;
+g = 23; //still double
+print(g);
+g = (222 >>> 1); //still double
+print(g);
+g = 4711.16; //double->double
+print(g);
+g = "I like cake!";
+print(g);  //object to various
+print(g & 0xff);
+print(g * 2);
+print(g >>> 2);
+print(g);
+
+var h = {x:17, y:17.4711, z:"salamander"};
+print(h.x);
+print(h.y);
+print(h.z);
+h.x = 4711.17;
+h.y = "axolotl";
+h.z = "lizard";
+print(h.x);
+print(h.y);
+print(h.z);
diff --git a/nashorn/test/script/sandbox/NASHORN-525.js b/nashorn/test/script/sandbox/NASHORN-525.js
new file mode 100644
index 0000000..c6a0d4f
--- /dev/null
+++ b/nashorn/test/script/sandbox/NASHORN-525.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * NASHORN-525 : nashorn misses security access checks 
+ *
+ * @test
+ * @run
+ */
+
+function check(code) {
+    try {
+        eval(code);
+        fail("SecurityException expected for : " + code);
+    } catch (e) {
+        if (! (e instanceof java.lang.SecurityException)) {
+            fail("SecurityException expected, but got " + e);
+        }
+    }
+}
+
+// if security manager is absent, pass the test vacuously.
+if (java.lang.System.getSecurityManager() != null) {
+    // try accessing class from 'sun.*' packages
+    check("Packages.sun.misc.Unsafe");
+    check("Java.type('sun.misc.Unsafe')");
+
+    // TODO this works in Java8 but not in Java8, disabling for now
+    check("java.lang.Class.forName('sun.misc.Unsafe')");
+
+    // try System.exit and System.loadLibrary
+    check("java.lang.System.exit(0)");
+    check("java.lang.System.loadLibrary('foo')");
+}
diff --git a/nashorn/test/script/sandbox/README b/nashorn/test/script/sandbox/README
new file mode 100644
index 0000000..4980665
--- /dev/null
+++ b/nashorn/test/script/sandbox/README
@@ -0,0 +1 @@
+This directory contains tests for sandbox security access checks.
diff --git a/nashorn/test/script/sandbox/classloader.js b/nashorn/test/script/sandbox/classloader.js
new file mode 100644
index 0000000..7676496
--- /dev/null
+++ b/nashorn/test/script/sandbox/classloader.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * Try to extend ClassLoader.
+ *
+ * @test
+ * @security
+ */
+
+try {
+    var l = new (Java.extend(java.lang.ClassLoader))({});
+    fail("should have thrown SecurityException");
+} catch (e) {
+    if (e instanceof java.lang.SecurityException) {
+        print(e);
+    } else {
+        fail("expected SecurityException, got " + e);
+    }
+}
+
diff --git a/nashorn/test/script/sandbox/classloader.js.EXPECTED b/nashorn/test/script/sandbox/classloader.js.EXPECTED
new file mode 100644
index 0000000..e08cc9f
--- /dev/null
+++ b/nashorn/test/script/sandbox/classloader.js.EXPECTED
@@ -0,0 +1 @@
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createClassLoader")
diff --git a/nashorn/test/script/sandbox/doprivileged.js b/nashorn/test/script/sandbox/doprivileged.js
new file mode 100644
index 0000000..d901347
--- /dev/null
+++ b/nashorn/test/script/sandbox/doprivileged.js
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/**
+ * doPrivileged checks.
+ *
+ * @test
+ * @security
+ */
+
+function check(e) {
+    if (e instanceof java.lang.SecurityException) {
+        print(e);
+    } else {
+        fail("expected SecurityException, got " + e);
+    }
+}
+
+var AccessController = java.security.AccessController;
+var PrivilegedAction = java.security.PrivilegedAction;
+
+AccessController.doPrivileged(new PrivilegedAction() {
+    run: function() {
+        // try something sensitive
+        try {
+            java.lang.System.exit(0);
+        } catch(e) {
+            check(e);
+        }
+
+	try {
+	    var prop = java.lang.System.getProperty("user.dir");
+            fail("can get user.dir " + prop);
+	} catch(e) {
+            print(e);
+	}
+    }
+});
diff --git a/nashorn/test/script/sandbox/doprivileged.js.EXPECTED b/nashorn/test/script/sandbox/doprivileged.js.EXPECTED
new file mode 100644
index 0000000..0730cdd
--- /dev/null
+++ b/nashorn/test/script/sandbox/doprivileged.js.EXPECTED
@@ -0,0 +1,2 @@
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "exitVM.0")
+java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.dir" "read")
diff --git a/nashorn/test/script/sandbox/engine.js b/nashorn/test/script/sandbox/engine.js
new file mode 100644
index 0000000..e1d87c7
--- /dev/null
+++ b/nashorn/test/script/sandbox/engine.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test that sandbox code can create script engine.
+ *
+ * @test
+ * @run
+ * @security
+ */
+
+var mgr = new javax.script.ScriptEngineManager();
+var engine = mgr.getEngineByName("nashorn");
+print(engine.eval("'hello' + ' world'"));
diff --git a/nashorn/test/script/sandbox/engine.js.EXPECTED b/nashorn/test/script/sandbox/engine.js.EXPECTED
new file mode 100644
index 0000000..3b18e51
--- /dev/null
+++ b/nashorn/test/script/sandbox/engine.js.EXPECTED
@@ -0,0 +1 @@
+hello world
diff --git a/nashorn/test/script/sandbox/env.js b/nashorn/test/script/sandbox/env.js
new file mode 100644
index 0000000..df80e6f
--- /dev/null
+++ b/nashorn/test/script/sandbox/env.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Try to get env object
+ *
+ * @test
+ * @security
+ * @option -scripting
+ */
+
+var env = $ENV;
+// should be empty!!
+for (i in env) {
+    print("FAILED: can get: " + i +  " = " + env[i]);
+}
diff --git a/nashorn/test/script/sandbox/exec.js b/nashorn/test/script/sandbox/exec.js
new file mode 100644
index 0000000..86d70b3
--- /dev/null
+++ b/nashorn/test/script/sandbox/exec.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * Try to get exec
+ *
+ * @test
+ * @security
+ * @option -scripting
+ */
+
+try {
+    var ans = `java -version`;
+    fail("should have thrown exception!");
+} catch (e) {
+    if (! (e instanceof java.lang.SecurityException)) {
+        fail("SecurityException expected, got " + e);
+    }
+}
diff --git a/nashorn/test/script/sandbox/exit.js b/nashorn/test/script/sandbox/exit.js
new file mode 100644
index 0000000..d77744f
--- /dev/null
+++ b/nashorn/test/script/sandbox/exit.js
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/**
+ * Try to call System.exit, quit and exit.
+ *
+ * @test
+ * @security
+ */
+
+function check(e) {
+    if (e instanceof java.lang.SecurityException) {
+        print(e);
+    } else {
+        fail("expected SecurityException, got " + e);
+    }
+}
+
+try {
+    java.lang.System.exit(0);
+    // will not reach here regardless of outcome..
+} catch (e) {
+    check(e);
+}
+
+try {
+    quit();
+    // will not reach here regardless of outcome..
+} catch (e) {
+    check(e);
+}
+
+try {
+    exit(0);
+    // will not reach here regardless of outcome..
+} catch (e) {
+    check(e);
+}
+
+print("Success, didn't exit!");
diff --git a/nashorn/test/script/sandbox/exit.js.EXPECTED b/nashorn/test/script/sandbox/exit.js.EXPECTED
new file mode 100644
index 0000000..c1411eb
--- /dev/null
+++ b/nashorn/test/script/sandbox/exit.js.EXPECTED
@@ -0,0 +1,4 @@
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "exitVM.0")
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "exitVM.0")
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "exitVM.0")
+Success, didn't exit!
diff --git a/nashorn/test/script/sandbox/file.js b/nashorn/test/script/sandbox/file.js
new file mode 100644
index 0000000..dce3afd
--- /dev/null
+++ b/nashorn/test/script/sandbox/file.js
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * try file system activities.
+ *
+ * @test
+ * @security
+ */
+
+function check(e) {
+    if (e instanceof java.lang.SecurityException) {
+        print(e);
+    } else {
+        fail("expected SecurityException, got " + e);
+    }
+}
+
+try {
+    new java.io.File(".").getCanonicalPath();
+} catch (e) {
+    check(e);
+}
+
+try {
+    new java.io.FileInputStream("foo");
+} catch (e) {
+    check(e);
+}
+
+try {
+    new java.io.FileOutputStream("foo");
+} catch (e) {
+    check(e);
+}
diff --git a/nashorn/test/script/sandbox/file.js.EXPECTED b/nashorn/test/script/sandbox/file.js.EXPECTED
new file mode 100644
index 0000000..5a1e0e4
--- /dev/null
+++ b/nashorn/test/script/sandbox/file.js.EXPECTED
@@ -0,0 +1,3 @@
+java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.dir" "read")
+java.security.AccessControlException: access denied ("java.io.FilePermission" "foo" "read")
+java.security.AccessControlException: access denied ("java.io.FilePermission" "foo" "write")
diff --git a/nashorn/test/script/sandbox/interfaceimpl.js b/nashorn/test/script/sandbox/interfaceimpl.js
new file mode 100644
index 0000000..b2ee86b
--- /dev/null
+++ b/nashorn/test/script/sandbox/interfaceimpl.js
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/**
+ * Check that user defined interface can be implemented.
+ *
+ * @test
+ * @run
+ * @security
+ */
+
+var Window = Java.type("jdk.nashorn.api.scripting.Window");
+var WindowEventHandler = Java.type("jdk.nashorn.api.scripting.WindowEventHandler");
+
+var w = new Window();
+
+var loadedFuncReached = false;
+// try function to SAM converter
+w.onload = function() {
+    loadedFuncReached = true;
+    return true;
+}
+
+w.onload.loaded();
+if (! loadedFuncReached) {
+    fail("Interface method impl. not called");
+}
+
+// reset
+loadedFuncReached = false;
+
+// try direct interface implementation
+w.onload = new WindowEventHandler() {
+    loaded: function() {
+        loadedFuncReached = true;
+        return true;
+    }
+};
+
+w.onload.loaded();
+if (! loadedFuncReached) {
+    fail("Interface method impl. not called");
+}
diff --git a/nashorn/test/script/sandbox/javaextend.js b/nashorn/test/script/sandbox/javaextend.js
new file mode 100644
index 0000000..318a679
--- /dev/null
+++ b/nashorn/test/script/sandbox/javaextend.js
@@ -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.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @run
+ */
+
+function model(n) {
+  return Java.type("jdk.nashorn.internal.test.models." + n)
+}
+
+// Can't extend a final class  
+try {
+    Java.extend(model("FinalClass"))
+} catch(e) {
+    print(e)
+}
+
+// Can't extend a class with no public or protected constructor
+try {
+    Java.extend(model("NoAccessibleConstructorClass"))
+} catch(e) {
+    print(e)
+}
+
+// Can't extend a non-public class
+try {
+    Java.extend(model("NonPublicClass"))
+} catch(e) {
+    print(e)
+}
+
+// Can't extend two classes
+try {
+    Java.extend(java.lang.Thread,java.lang.Number)
+} catch(e) {
+    print(e)
+}
+
+// Make sure we can implement interfaces from the unnamed package
+var c = new (Java.extend(Java.type("UnnamedPackageTestCallback")))() { call: function(s) { return s + s } }
+print(c.call("abcd"))
+
+// Basic Runnable from an object
+new (Java.extend(java.lang.Runnable))({ run: function() { print("run-object") } }).run()
+
+// Basic Runnable from a function
+new (Java.extend(java.lang.Runnable))(function() { print("run-fn") }).run()
+
+// Basic Runnable from an autoconverted function
+var t = new java.lang.Thread(function() { print("run-fn-autoconvert") })
+t.start()
+t.join()
+
+// SAM conversion should work on overloaded methods of same name
+var os = new (Java.extend(model("OverloadedSam")))(function(s1, s2) { print("overloaded-sam: " + s1 + ", " + s2) })
+os.sam("x")
+os.sam("x", "y")
+
+// Test overriding of hashCode, equals, and toString
+var oo = Java.extend(model("OverrideObject"))
+// First, see non-overridden values
+print("oo-plain-hashCode: " + (new oo({})).hashCode())
+print("oo-plain-toString: " + (new oo({})).toString())
+print("oo-plain-equals  : " + (new oo({})).equals({}))
+// Now, override them
+print("oo-overridden-hashCode: " + (new oo({ hashCode: function() { return 6 }})).hashCode())
+print("oo-overridden-toString: " + (new oo({ toString: function() { return "override-object-overriden" }})).toString())
+print("oo-overridden-equals  : " + (new oo({ equals: function() { return true }})).equals({}))
+// Finally, test that equals and hashCode can be overridden with functions from a prototype, but toString() can't:
+function Proto() {
+    return this;
+}
+Proto.prototype = {
+    toString: function() { return "this-will-never-be-seen" }, // toString only overridden when it's own property, never from prototype
+    equals: function() { return true },
+    hashCode: function() { return 7 }
+}
+print("oo-proto-overridden-hashCode: " + (new oo(new Proto())).hashCode())
+print("oo-proto-overridden-toString: " + (new oo(new Proto())).toString())
+print("oo-proto-overridden-equals  : " + (new oo(new Proto())).equals({}))
+
+// Subclass a class with a protected constructor, and one that takes
+// additional constructor arguments (a token). Also demonstrates how can
+// you access the Java adapter instance from the script (just store it in the
+// scope, in this example, "cwa") to retrieve the token later on.
+var cwa = new (Java.extend(model("ConstructorWithArgument")))("cwa-token", function() { print(cwa.token) })
+cwa.doSomething()
+
+// Do the same thing with proprietary syntax and object literal
+var cwa2 = new (model("ConstructorWithArgument"))("cwa2-token") { doSomething: function() { print("cwa2-" + cwa2.token ) } }
+cwa2.doSomething()
+
+// Implement two interfaces
+var desertToppingAndFloorWax = new (Java.extend(model("DessertTopping"), model("FloorWax"))) {
+    pourOnDessert: function() { print("Glop; IM IN UR DESSERT NOW") },
+    shineUpTheFloor: function() { print("The floor sure is shining!") }
+}
+var dtfwDriver = new (model("DessertToppingFloorWaxDriver"))
+dtfwDriver.decorateDessert(desertToppingAndFloorWax)
+dtfwDriver.waxFloor(desertToppingAndFloorWax)
+
+// Extend a class and implement two interfaces. For additional measure, put the class in between the two interfaces
+var desertToppingFloorWaxAndToothpaste = new (Java.extend(model("DessertTopping"), model("Toothpaste"), model("FloorWax"))) {
+    pourOnDessert: function() { print("Yum") },
+    shineUpTheFloor: function() { print("Scrub, scrub, scrub") },
+    applyToBrushImpl: function() { print("It's a dessert topping! It's a floor wax! It's a toothpaste!") }
+}
+dtfwDriver.decorateDessert(desertToppingFloorWaxAndToothpaste)
+dtfwDriver.waxFloor(desertToppingFloorWaxAndToothpaste)
+desertToppingFloorWaxAndToothpaste.applyToBrush();
diff --git a/nashorn/test/script/sandbox/javaextend.js.EXPECTED b/nashorn/test/script/sandbox/javaextend.js.EXPECTED
new file mode 100644
index 0000000..2a5ad63
--- /dev/null
+++ b/nashorn/test/script/sandbox/javaextend.js.EXPECTED
@@ -0,0 +1,26 @@
+TypeError: Can not extend final class jdk.nashorn.internal.test.models.FinalClass.
+TypeError: Can not extend class jdk.nashorn.internal.test.models.NoAccessibleConstructorClass as it has no public or protected constructors.
+TypeError: Can not extend/implement non-public class/interface jdk.nashorn.internal.test.models.NonPublicClass.
+TypeError: Can not extend multiple classes java.lang.Number and java.lang.Thread. At most one of the specified types can be a class, the rest must all be interfaces.
+abcdabcd
+run-object
+run-fn
+run-fn-autoconvert
+overloaded-sam: x, undefined
+overloaded-sam: x, y
+oo-plain-hashCode: 5
+oo-plain-toString: override-object
+oo-plain-equals  : false
+oo-overridden-hashCode: 6
+oo-overridden-toString: override-object-overriden
+oo-overridden-equals  : true
+oo-proto-overridden-hashCode: 7
+oo-proto-overridden-toString: override-object
+oo-proto-overridden-equals  : true
+cwa-token
+cwa2-cwa2-token
+Glop; IM IN UR DESSERT NOW
+The floor sure is shining!
+Yum
+Scrub, scrub, scrub
+It's a dessert topping! It's a floor wax! It's a toothpaste!
diff --git a/nashorn/test/script/sandbox/jsadapter.js b/nashorn/test/script/sandbox/jsadapter.js
new file mode 100644
index 0000000..32bedc8
--- /dev/null
+++ b/nashorn/test/script/sandbox/jsadapter.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test that sandbox code can access jsadapter
+ *
+ * @test
+ * @run
+ * @security
+ */
+
+var mgr = new javax.script.ScriptEngineManager();
+var engine = mgr.getEngineByName("nashorn");
+engine.eval("var v = new JSAdapter() {};");
diff --git a/nashorn/test/script/sandbox/loadLibrary.js b/nashorn/test/script/sandbox/loadLibrary.js
new file mode 100644
index 0000000..1e5151f
--- /dev/null
+++ b/nashorn/test/script/sandbox/loadLibrary.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * Try to call System.loadLibrary
+ *
+ * @test
+ * @security
+ */
+
+function check(e) {
+    if (! (e instanceof java.lang.SecurityException)) {
+        fail("expected SecurityException, got " + e);
+    }
+}
+
+try {
+    java.lang.System.loadLibrary("foo");
+    fail("should have thrown exception");
+} catch (e) {
+    check(e);
+}
+
diff --git a/nashorn/test/script/sandbox/loadcompat.js b/nashorn/test/script/sandbox/loadcompat.js
new file mode 100644
index 0000000..e99f67f
--- /dev/null
+++ b/nashorn/test/script/sandbox/loadcompat.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Check that nashorn mozilla compatibility script can be loaded in sandbox.
+ *
+ * @test
+ * @run
+ * @security
+ */
+
+load("nashorn:mozilla_compat.js");
+
+var obj = {};
+if (obj.__proto__ !== Object.prototype) {
+    fail("__proto__ does not work as expected");
+}
+
+var array = [];
+if (array.__proto__ !== Array.prototype) {
+    fail("__proto__ does not work as expected");
+}
+
+if (typeof JavaAdapter != 'function') {
+    fail("JavaAdapter constructor is missing in compatibility script");
+}
+
+if (typeof importPackage != 'function') {
+    fail("importPackage function is missing in compatibility script");
+}
diff --git a/nashorn/test/script/sandbox/nashorninternals.js b/nashorn/test/script/sandbox/nashorninternals.js
new file mode 100644
index 0000000..35e8e75
--- /dev/null
+++ b/nashorn/test/script/sandbox/nashorninternals.js
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/**
+ * Test to check that nashorn "internal" classes in codegen, parser, ir 
+ * packages cannot * be accessed from sandbox scripts.
+ *
+ * @test
+ * @run
+ * @security
+ */
+
+function checkClass(name) {
+    try {
+        Java.type(name);
+        fail("should have thrown exception for: " + name);
+    } catch (e) {
+        if (! (e instanceof java.lang.SecurityException)) {
+            fail("Expected SecurityException, but got " + e);
+        }
+    }
+}
+
+// Not exhaustive - but a representative list of classes
+checkClass("jdk.nashorn.internal.codegen.Compiler");
+checkClass("jdk.nashorn.internal.codegen.objects.MapCreator");
+checkClass("jdk.nashorn.internal.codegen.types.Type");
+checkClass("jdk.nashorn.internal.ir.Node");
+checkClass("jdk.nashorn.internal.ir.FunctionNode");
+checkClass("jdk.nashorn.internal.ir.debug.JSONWriter");
+checkClass("jdk.nashorn.internal.ir.visitor.NodeVisitor");
+checkClass("jdk.nashorn.internal.parser.AbstractParser");
+checkClass("jdk.nashorn.internal.parser.Parser");
+checkClass("jdk.nashorn.internal.parser.JSONParser");
+checkClass("jdk.nashorn.internal.parser.Lexer");
+checkClass("jdk.nashorn.internal.parser.Scanner");
+checkClass("jdk.internal.dynalink.CallSiteDescriptor");
+checkClass("jdk.internal.dynalink.beans.StaticClass");
+checkClass("jdk.internal.dynalink.linker.LinkRequest");
+checkClass("jdk.internal.dynalink.support.AbstractRelinkableCallSite");
diff --git a/nashorn/test/script/sandbox/net.js b/nashorn/test/script/sandbox/net.js
new file mode 100644
index 0000000..37aaf57
--- /dev/null
+++ b/nashorn/test/script/sandbox/net.js
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * Try network activity.
+ *
+ * @test
+ * @security
+ */
+
+function check(e) {
+    if (e instanceof java.lang.SecurityException) {
+        print(e);
+    } else {
+        fail("expected SecurityException, got " + e);
+    }
+}
+
+try {
+    new java.net.URL("http://www.acme.com").openStream();
+} catch (e) {
+    check(e);
+}
diff --git a/nashorn/test/script/sandbox/net.js.EXPECTED b/nashorn/test/script/sandbox/net.js.EXPECTED
new file mode 100644
index 0000000..dfa7334
--- /dev/null
+++ b/nashorn/test/script/sandbox/net.js.EXPECTED
@@ -0,0 +1 @@
+java.security.AccessControlException: access denied ("java.net.SocketPermission" "www.acme.com:80" "connect,resolve")
diff --git a/nashorn/test/script/sandbox/property.js b/nashorn/test/script/sandbox/property.js
new file mode 100644
index 0000000..685cf32
--- /dev/null
+++ b/nashorn/test/script/sandbox/property.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * Try to read sensitive System property.
+ *
+ * @test
+ * @security
+ */
+
+function check(e) {
+    if (e instanceof java.lang.SecurityException) {
+        print(e);
+    } else {
+        fail("expected SecurityException, got " + e);
+    }
+}
+
+try {
+    var prop = java.lang.System.getProperty("user.dir");
+    fail("can read user.dir " + prop);
+} catch (e) {
+    check(e);
+}
diff --git a/nashorn/test/script/sandbox/property.js.EXPECTED b/nashorn/test/script/sandbox/property.js.EXPECTED
new file mode 100644
index 0000000..73c67af
--- /dev/null
+++ b/nashorn/test/script/sandbox/property.js.EXPECTED
@@ -0,0 +1 @@
+java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.dir" "read")
diff --git a/nashorn/test/script/sandbox/reflection.js b/nashorn/test/script/sandbox/reflection.js
new file mode 100644
index 0000000..7364879
--- /dev/null
+++ b/nashorn/test/script/sandbox/reflection.js
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * reflection checks.
+ *
+ * @test
+ * @security
+ * @run
+ */
+
+function check(e) {
+    if (e instanceof java.lang.SecurityException) {
+        print(e);
+    } else {
+        fail("expected SecurityException, got " + e);
+    }
+}
+
+var cl = java.lang.Class.class;
+try {
+    cl.getDeclaredMethods();
+} catch(e) {
+    check(e); 
+}
diff --git a/nashorn/test/script/sandbox/reflection.js.EXPECTED b/nashorn/test/script/sandbox/reflection.js.EXPECTED
new file mode 100644
index 0000000..202333e
--- /dev/null
+++ b/nashorn/test/script/sandbox/reflection.js.EXPECTED
@@ -0,0 +1 @@
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")
diff --git a/nashorn/test/script/sandbox/runnable.js b/nashorn/test/script/sandbox/runnable.js
new file mode 100644
index 0000000..75f533b
--- /dev/null
+++ b/nashorn/test/script/sandbox/runnable.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implement runnable interface under security manager and try thread.
+ *
+ * @test
+ * @security
+ */
+
+var r = new java.lang.Runnable() {
+   run: function() {
+       print("I am runnable");
+   }
+};
+
+r.run();
+
+var t = new java.lang.Thread(r);
+t.start();
+t.join();
diff --git a/nashorn/test/script/sandbox/runnable.js.EXPECTED b/nashorn/test/script/sandbox/runnable.js.EXPECTED
new file mode 100644
index 0000000..3bc2881
--- /dev/null
+++ b/nashorn/test/script/sandbox/runnable.js.EXPECTED
@@ -0,0 +1,2 @@
+I am runnable
+I am runnable
diff --git a/nashorn/test/script/sandbox/unsafe.js b/nashorn/test/script/sandbox/unsafe.js
new file mode 100644
index 0000000..b273cd0
--- /dev/null
+++ b/nashorn/test/script/sandbox/unsafe.js
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+/**
+ * Try to access sensitive class like Unsafe.
+ *
+ * @test
+ * @security
+ * @run
+ */
+
+function check(e) {
+   if (e instanceof java.lang.SecurityException) {
+       print(e);
+   } else {
+       fail("expected SecurityException, got " + e);
+   }
+}
+
+try {
+    var unsafe = java.lang.Class.forName("sun.misc.Unsafe");
+    fail("No SecurityException for Class.forName sun.misc.Unsafe");
+} catch (e) {
+    check(e);
+}
+
+try {
+    var unsafe = Java.type("sun.misc.Unsafe"); 
+    fail("No SecurityException for Java.type sun.misc.Unsafe");
+} catch (e) {
+    check(e);
+}
+
+try {
+    var unsafe = Packages.sun.misc.Unsafe;
+    fail("No SecurityException for Packages.sun.misc.Unsafe");
+} catch (e) {
+    check(e);
+}
+
+try {
+    var cl = Packages.jdk.nashorn.internal.runtime.Context.class;
+    var unsafe = cl.getClassLoader().loadClass("sun.misc.Unsafe");
+} catch (e) {
+    check(e);
+}
diff --git a/nashorn/test/script/sandbox/unsafe.js.EXPECTED b/nashorn/test/script/sandbox/unsafe.js.EXPECTED
new file mode 100644
index 0000000..3f1cbec
--- /dev/null
+++ b/nashorn/test/script/sandbox/unsafe.js.EXPECTED
@@ -0,0 +1,4 @@
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.misc")
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.misc")
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun")
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getClassLoader")
diff --git a/nashorn/test/script/test262.js b/nashorn/test/script/test262.js
new file mode 100644
index 0000000..a03e612
--- /dev/null
+++ b/nashorn/test/script/test262.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * This is not a test, but a test "framework" for running test262 tests.
+ *
+ * @subtest
+ */
+
+$ERROR = function() {
+    throw new EvalError(Array.prototype.join.call(arguments));
+}
+
+$INCLUDE = function(filename) {
+    load("test/test262/test/harness/" + filename);
+}
+
+$FAIL = $ERROR;
+$PRINT = print;
diff --git a/nashorn/test/script/test262_single.js b/nashorn/test/script/test262_single.js
new file mode 100644
index 0000000..2cc905e
--- /dev/null
+++ b/nashorn/test/script/test262_single.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Handy wrapper for running just one 262 test, pass as arg
+ *
+ * @subtest
+ */
+
+function runTestCase(tc) {
+    print(tc() ? "success" : "failure");
+}
+
+function $ERROR(str) {
+    print("ERROR: " + str);
+}
+
+load(arguments[0]);
diff --git a/nashorn/test/script/trusted/JDK-8006424.js b/nashorn/test/script/trusted/JDK-8006424.js
new file mode 100644
index 0000000..88516e1
--- /dev/null
+++ b/nashorn/test/script/trusted/JDK-8006424.js
@@ -0,0 +1,45 @@
+/*
+ * 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-8006424 : Passing null or undefined to adapter class constructors results in NPE or ClassCastException
+ *
+ * @test
+ * @run
+ */
+
+function check(callback) {
+    try {
+        callback();
+        fail("should have thrown exception");
+    } catch (e) {
+        if (! (e instanceof TypeError)) {
+            fail("TypeError expected, but got " + e);
+        }
+    }
+}
+
+check(function() { new java.lang.ClassLoader(null) });
+check(function() { new java.lang.ClassLoader(undefined) });
+check(function() { new java.lang.Runnable(null) });
+check(function() { new java.lang.Runnable(undefined) });
diff --git a/nashorn/test/script/trusted/JDK-8008305.js b/nashorn/test/script/trusted/JDK-8008305.js
new file mode 100644
index 0000000..e4d052c
--- /dev/null
+++ b/nashorn/test/script/trusted/JDK-8008305.js
@@ -0,0 +1,59 @@
+/*
+ * 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-8008305: ScriptEngine.eval should offer the ability to provide a codebase *
+ * @test
+ * @run
+ */
+
+var URLReader = Java.type("jdk.nashorn.api.scripting.URLReader");
+var File = Java.type("java.io.File");
+var FileReader = Java.type("java.io.FileReader");
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+var SecurityException = Java.type("java.lang.SecurityException");
+
+var m = new ScriptEngineManager();
+var e = m.getEngineByName("nashorn");
+
+
+// subtest script file
+var scriptFile = new File(__DIR__ + "JDK-8008305_subtest.js");
+
+// evaluate the subtest via a URLReader
+var res = e.eval(new URLReader(scriptFile.toURI().toURL()));
+
+// subtest should execute with AllPermission and so return absolute path
+if (! res.equals(new File(".").getAbsolutePath())) {
+    fail("eval result is not equal to expected value");
+}
+
+// try same subtest without URLReader and so it runs with null code source
+try {
+    e.eval(new FileReader(scriptFile));
+    fail("Expected SecurityException from script!");
+} catch (e) {
+    if (! (e instanceof SecurityException)) {
+        faile("Expected SecurityException, but got " + e);
+    }
+}
diff --git a/nashorn/test/script/trusted/JDK-8008305_subtest.js b/nashorn/test/script/trusted/JDK-8008305_subtest.js
new file mode 100644
index 0000000..2485f39
--- /dev/null
+++ b/nashorn/test/script/trusted/JDK-8008305_subtest.js
@@ -0,0 +1,33 @@
+/*
+ * 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-8008305: ScriptEngine.eval should offer the ability to provide a codebase *
+ * @subtest
+ */
+
+// If this test runs with sandbox permissions, the following should
+// result in SecurityException or else it should succeed.
+
+new java.io.File(".").getAbsolutePath();
diff --git a/nashorn/test/script/trusted/NASHORN-638.js b/nashorn/test/script/trusted/NASHORN-638.js
new file mode 100644
index 0000000..9cb6d69
--- /dev/null
+++ b/nashorn/test/script/trusted/NASHORN-638.js
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-638 : Callsite tracing and profiling are broken
+ *
+ * @test
+ * @run
+ */
+
+/*
+ * creates new script engine initialized with given options and
+ * runs given code on it. Returns standard output captured.
+ */
+
+function runScriptEngine(opts, code) {
+    var imports = new JavaImporter(
+        Packages.jdk.nashorn.api.scripting,
+        java.io, java.lang, java.util);
+
+    with(imports) {
+        var fac = new NashornScriptEngineFactory();
+        // get current System.err
+        var oldErr = System.err;
+        var baos = new ByteArrayOutputStream();
+        var newErr = new PrintStream(baos);
+        try {
+            // set new standard err
+            System.setErr(newErr);
+            var strType = Java.type("java.lang.String");
+            var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
+            engine.eval(code);
+            newErr.flush();
+            return new java.lang.String(baos.toByteArray());
+        } finally {
+            // restore System.err to old value
+            System.setErr(oldErr);
+        }
+    }
+}
+
+var str = runScriptEngine([ "-tcs=all" ], "new Date");
+print("hello, world!");
+
+if (str.indexOf(" ENTER ") == -1) {
+    fail("expected 'ENTER' in trace mode output");
+}
+
+if (str.indexOf(" EXIT ") == -1) {
+    fail("expected 'EXIT' in trace mode output");
+}
+
diff --git a/nashorn/test/script/trusted/NASHORN-638.js.EXPECTED b/nashorn/test/script/trusted/NASHORN-638.js.EXPECTED
new file mode 100644
index 0000000..270c611
--- /dev/null
+++ b/nashorn/test/script/trusted/NASHORN-638.js.EXPECTED
@@ -0,0 +1 @@
+hello, world!
diff --git a/nashorn/test/script/trusted/NASHORN-653.js b/nashorn/test/script/trusted/NASHORN-653.js
new file mode 100644
index 0000000..2084bf7
--- /dev/null
+++ b/nashorn/test/script/trusted/NASHORN-653.js
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+/**
+ * NASHORN-653 : Various problems with isTerminal and dead code generation from ASM
+ *
+ * @test
+ * @run
+ */
+
+var script = "   \
+function a() {   \
+    return true; \
+}                \
+                 \
+function b() {   \
+    while (x) {      \
+	return true; \
+    }                \
+}                    \
+                     \
+function c() {       \
+    while (true) {   \
+	return true; \
+    }                \
+ }                   \
+                     \
+function d() {       \
+    do {             \
+	return true; \
+    } while (x);     \
+} \
+\
+function f() {       \
+    for (;;) {       \
+	return true; \
+    } \
+} \
+\
+function e() { \
+    for (;;) { \
+	return true; \
+    } \
+} \
+\
+function g() { \
+    for(;;) { \
+	print('goes on and on and on ... '); \
+    } \
+    print('x'); \
+} \
+";
+
+function runScriptEngine(opts, code) {
+    var imports = new JavaImporter(
+        Packages.jdk.nashorn.api.scripting,
+        java.io, java.lang, java.util);
+
+    with(imports) {
+        var fac = new NashornScriptEngineFactory();
+        // get current System.err
+        var oldErr = System.err;
+        var baos = new ByteArrayOutputStream();
+        var newErr = new PrintStream(baos);
+        try {
+            // set new standard err
+            System.setErr(newErr);
+            var strType = Java.type("java.lang.String");
+            var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
+            engine.eval(code);
+            newErr.flush();
+            return new java.lang.String(baos.toByteArray());
+        } finally {
+            // restore System.err to old value
+            System.setErr(oldErr);
+        }
+    }
+}
+
+var result = runScriptEngine([ "--print-code" ], script);
+
+if (result.indexOf("NOP") != -1) {
+    fail("ASM genenerates NOP*/ATHROW sequences - dead code is still in the script");
+}
diff --git a/nashorn/test/script/trusted/README b/nashorn/test/script/trusted/README
new file mode 100644
index 0000000..60260ed
--- /dev/null
+++ b/nashorn/test/script/trusted/README
@@ -0,0 +1,4 @@
+This directory contains tests that need AllPermission to run.
+
+Scripts that need to create classloaders, need to reflectively access
+declared members of other classes etc. should go here.
diff --git a/nashorn/test/script/trusted/getenv.js b/nashorn/test/script/trusted/getenv.js
new file mode 100644
index 0000000..9fb3a96
--- /dev/null
+++ b/nashorn/test/script/trusted/getenv.js
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * Verifies Map methods do not generate NPE
+ *
+ * @test
+ * @run
+ */
+
+print(java.lang.System.getenv().isEmpty());
diff --git a/nashorn/test/script/trusted/getenv.js.EXPECTED b/nashorn/test/script/trusted/getenv.js.EXPECTED
new file mode 100644
index 0000000..c508d53
--- /dev/null
+++ b/nashorn/test/script/trusted/getenv.js.EXPECTED
@@ -0,0 +1 @@
+false
diff --git a/nashorn/test/script/trusted/urlreader.js b/nashorn/test/script/trusted/urlreader.js
new file mode 100644
index 0000000..a5e06ee
--- /dev/null
+++ b/nashorn/test/script/trusted/urlreader.js
@@ -0,0 +1,27 @@
+/**
+ * JDK-8008305: ScriptEngine.eval should offer the ability to provide a codebase
+ *
+ * @test
+ * @run
+ */
+
+var URLReader = Java.type("jdk.nashorn.api.scripting.URLReader");
+var URL = Java.type("java.net.URL");
+var File = Java.type("java.io.File");
+var JString = Java.type("java.lang.String");
+var Source = Java.type("jdk.nashorn.internal.runtime.Source");
+
+var url = new File(__FILE__).toURI().toURL();
+var reader = new URLReader(url);
+
+// check URLReader.getURL() method
+//Assert.assertEquals(url, reader.getURL());
+
+// check URL read
+// read URL content by directly reading from URL
+var str = new Source(url.toString(), url).getString();
+// read URL content via URLReader
+var content = new JString(Source.readFully(reader));
+
+// assert that the content is same
+Assert.assertEquals(str, content);
diff --git a/nashorn/test/src/UnnamedPackageTestCallback.java b/nashorn/test/src/UnnamedPackageTestCallback.java
new file mode 100644
index 0000000..67ab36f
--- /dev/null
+++ b/nashorn/test/src/UnnamedPackageTestCallback.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+public interface UnnamedPackageTestCallback {
+    String call(String s);
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java
new file mode 100644
index 0000000..2cfdbf0
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.javaaccess;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+import java.util.Arrays;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import org.testng.TestNG;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.BooleanAccessTest
+ * @run testng jdk.nashorn.api.javaaccess.BooleanAccessTest
+ */
+public class BooleanAccessTest {
+
+    private static ScriptEngine e = null;
+    private static SharedObject o = new SharedObject();
+
+    public static void main(final String[] args) {
+        TestNG.main(args);
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        e = m.getEngineByName("nashorn");
+        e.put("o", o);
+        e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
+    }
+
+    @Test
+    public void accessFieldBoolean() throws ScriptException {
+        e.eval("var p_boolean = o.publicBoolean;");
+        assertEquals(o.publicBoolean, e.get("p_boolean"));
+        assertEquals("boolean", e.eval("typeof p_boolean;"));
+        e.eval("o.publicBoolean = false;");
+        assertEquals(false, o.publicBoolean);
+    }
+
+    @Test
+    public void accessFieldBooleanArray() throws ScriptException {
+        e.eval("var p_boolean_array = o.publicBooleanArray;");
+        assertEquals(o.publicBooleanArray[0], e.eval("o.publicBooleanArray[0]"));
+        assertTrue(Arrays.equals(o.publicBooleanArray, (boolean[])e.get("p_boolean_array")));
+        e.eval("var t_boolean_arr = java.lang.reflect.Array.newInstance(java.lang.Boolean.TYPE, 3);" +
+                "t_boolean_arr[0] = true;" +
+                "t_boolean_arr[1] = false;" +
+                "t_boolean_arr[2] = false;" +
+                "o.publicBooleanArray = t_boolean_arr;");
+        assertTrue(Arrays.equals(new boolean[] { true, false, false }, o.publicBooleanArray));
+        e.eval("o.publicBooleanArray[0] = false;");
+        assertEquals(false, o.publicBooleanArray[0]);
+    }
+
+    @Test
+    public void accessStaticFieldBoolean() throws ScriptException {
+        e.eval("var ps_boolean = SharedObject.publicStaticBoolean;");
+        assertEquals(SharedObject.publicStaticBoolean, e.get("ps_boolean"));
+        assertEquals("boolean", e.eval("typeof ps_boolean;"));
+        e.eval("SharedObject.publicStaticBoolean = false;");
+        assertEquals(false, SharedObject.publicStaticBoolean);
+    }
+
+    @Test
+    public void accessStaticFieldBooleanArray() throws ScriptException {
+        e.eval("var ps_boolean_array = SharedObject.publicStaticBooleanArray;");
+        assertEquals(SharedObject.publicStaticBooleanArray[0], e.eval("SharedObject.publicStaticBooleanArray[0]"));
+        assertTrue(Arrays.equals(SharedObject.publicStaticBooleanArray, (boolean[])e.get("ps_boolean_array")));
+        e.eval("var ts_boolean_arr = java.lang.reflect.Array.newInstance(java.lang.Boolean.TYPE, 3);" +
+                "ts_boolean_arr[0] = true;" +
+                "ts_boolean_arr[1] = false;" +
+                "ts_boolean_arr[2] = true;" +
+                "SharedObject.publicStaticBooleanArray = ts_boolean_arr;");
+        assertTrue(Arrays.equals(new boolean[] { true, false, true }, SharedObject.publicStaticBooleanArray));
+        e.eval("SharedObject.publicStaticBooleanArray[0] = false;");
+        assertEquals(false, SharedObject.publicStaticBooleanArray[0]);
+    }
+
+    @Test
+    public void accessFinalFieldBoolean() throws ScriptException {
+        e.eval("var pf_boolean = o.publicFinalBoolean;");
+        assertEquals(o.publicFinalBoolean, e.get("pf_boolean"));
+        assertEquals("boolean", e.eval("typeof pf_boolean;"));
+        e.eval("o.publicFinalBoolean = false;");
+        assertEquals(true, o.publicFinalBoolean);
+    }
+
+    @Test
+    public void accessFinalFieldBooleanArray() throws ScriptException {
+        e.eval("var pf_boolean_array = o.publicFinalBooleanArray;");
+        assertEquals(o.publicFinalBooleanArray[0], e.eval("o.publicFinalBooleanArray[0]"));
+        assertTrue(Arrays.equals(o.publicFinalBooleanArray, (boolean[])e.get("pf_boolean_array")));
+        e.eval("var tf_boolean_arr = java.lang.reflect.Array.newInstance(java.lang.Boolean.TYPE, 3);" +
+                "tf_boolean_arr[0] = false;" +
+                "tf_boolean_arr[1] = false;" +
+                "tf_boolean_arr[2] = true;" +
+                "o.publicOFinalbjectArray = tf_boolean_arr;");
+        assertTrue(Arrays.equals(new boolean[] { false, false, true, false }, o.publicFinalBooleanArray));
+        e.eval("o.publicFinalBooleanArray[0] = true;");
+        assertEquals(true, o.publicFinalBooleanArray[0]);
+    }
+
+    @Test
+    public void accessStaticFinalFieldBoolean() throws ScriptException {
+        e.eval("var psf_boolean = SharedObject.publicStaticFinalBoolean;");
+        assertEquals(SharedObject.publicStaticFinalBoolean, e.get("psf_boolean"));
+        assertEquals("boolean", e.eval("typeof psf_boolean;"));
+        e.eval("SharedObject.publicStaticFinalBoolean = false;");
+        assertEquals(true, SharedObject.publicStaticFinalBoolean);
+    }
+
+    @Test
+    public void accessStaticFinalFieldBooleanArray() throws ScriptException {
+        e.eval("var psf_boolean_array = SharedObject.publicStaticFinalBooleanArray;");
+        assertEquals(SharedObject.publicStaticFinalBooleanArray[0], e.eval("SharedObject.publicStaticFinalBooleanArray[0]"));
+        assertTrue(Arrays.equals(SharedObject.publicStaticFinalBooleanArray, (boolean[])e.get("psf_boolean_array")));
+        e.eval("var tsf_boolean_arr = java.lang.reflect.Array.newInstance(java.lang.Boolean.TYPE, 3);" +
+                "tsf_boolean_arr[0] = false;" +
+                "tsf_boolean_arr[1] = true;" +
+                "tsf_boolean_arr[2] = false;" +
+                "SharedObject.publicStaticFinalBooleanArray = tsf_boolean_arr;");
+        assertTrue(Arrays.equals(new boolean[] { false, true, false, false }, SharedObject.publicStaticFinalBooleanArray));
+        e.eval("SharedObject.publicStaticFinalBooleanArray[0] = true;");
+        assertEquals(true, SharedObject.publicStaticFinalBooleanArray[0]);
+    }
+
+    @Test
+    public void accessFieldBooleanBoxing() throws ScriptException {
+        e.eval("var p_boolean_box = o.publicBooleanBox;");
+        assertEquals(o.publicBooleanBox, e.get("p_boolean_box"));
+        assertEquals("boolean", e.eval("typeof p_boolean_box;"));
+        e.eval("o.publicBooleanBox = false;");
+        assertEquals(false, (boolean)o.publicBooleanBox);
+    }
+
+    @Test
+    public void accessStaticFieldBooleanBoxing() throws ScriptException {
+        e.eval("var ps_boolean_box = SharedObject.publicStaticBooleanBox;");
+        assertEquals(SharedObject.publicStaticBooleanBox, e.get("ps_boolean_box"));
+        assertEquals("boolean", e.eval("typeof ps_boolean_box;"));
+        e.eval("SharedObject.publicStaticBooleanBox = false;");
+        assertEquals(false, (boolean)SharedObject.publicStaticBooleanBox);
+    }
+
+    @Test
+    public void accessFinalFieldBooleanBoxing() throws ScriptException {
+        e.eval("var pf_boolean_box = o.publicFinalBooleanBox;");
+        assertEquals(o.publicFinalBooleanBox, e.get("pf_boolean_box"));
+        assertEquals("boolean", e.eval("typeof pf_boolean_box;"));
+        e.eval("o.publicFinalBooleanBox = false;");
+        assertEquals(true, (boolean)o.publicFinalBooleanBox);
+    }
+
+    @Test
+    public void accessStaticFinalFieldBooleanBoxing() throws ScriptException {
+        e.eval("var psf_boolean_box = SharedObject.publicStaticFinalBooleanBox;");
+        assertEquals(SharedObject.publicStaticFinalBooleanBox, e.get("psf_boolean_box"));
+        assertEquals("boolean", e.eval("typeof psf_boolean_box;"));
+        e.eval("SharedObject.publicStaticFinalBooleanBox = false;");
+        assertEquals(true, (boolean)SharedObject.publicStaticFinalBooleanBox);
+    }
+
+    @Test
+    public void accessVolatileField() throws ScriptException {
+        e.eval("var pv_boolean = o.volatileBoolean;");
+        assertEquals(o.volatileBoolean, e.get("pv_boolean"));
+        assertEquals("boolean", e.eval("typeof pv_boolean;"));
+        e.eval("o.volatileBoolean = false;");
+        assertEquals(false, o.volatileBoolean);
+    }
+
+    @Test
+    public void accessTransientField() throws ScriptException {
+        e.eval("var pt_boolean = o.transientBoolean;");
+        assertEquals(o.transientBoolean, e.get("pt_boolean"));
+        assertEquals("boolean", e.eval("typeof pt_boolean;"));
+        e.eval("o.transientBoolean = false;");
+        assertEquals(false, o.transientBoolean);
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java
new file mode 100644
index 0000000..69ca20c
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.javaaccess;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Locale;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import org.testng.TestNG;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.MethodAccessTest
+ * @run testng jdk.nashorn.api.javaaccess.MethodAccessTest
+ */
+public class MethodAccessTest {
+
+    private static ScriptEngine e = null;
+    private static SharedObject o = new SharedObject();
+
+    public static void main(final String[] args) {
+        TestNG.main(args);
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        e = m.getEngineByName("nashorn");
+        o.setEngine(e);
+        e.put("o", o);
+        e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
+        e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.Person;");
+    }
+
+    @Test
+    public void accessMethodthrowsCheckedException() throws ScriptException {
+        e.eval("try {" +
+                "    var a = java.lang.Long.parseLong('foo');" +
+                "} catch(e) {" +
+                "    var isThrown = true;" +
+                "    var isNumberException = e instanceof java.lang.NumberFormatException;" +
+                "} finally {" +
+                "    var isFinalized = true;" +
+                "}");
+        assertEquals("Exception thrown", true, e.get("isThrown"));
+        assertEquals("Finally called", true, e.get("isFinalized"));
+        assertEquals("Type is NumberFormatException", true, e.get("isNumberException"));
+    }
+
+    @Test
+    public void accessMethodthrowsUnCheckedException() throws ScriptException {
+        e.eval("try {" +
+                "    var a = java.lang.String.valueOf(null);" +
+                "} catch(e) {" +
+                "    var isThrown = true;" +
+                "    var isNumberException = e instanceof java.lang.NullPointerException;" +
+                "} finally {" +
+                "    var isFinalized = true;" +
+                "}");
+        assertEquals(true, e.get("isThrown"));
+        assertEquals(true, e.get("isFinalized"));
+        assertEquals(true, e.get("isNumberException"));
+    }
+
+    @Test
+    public void accessMethodStartsThread() throws ScriptException {
+        e.eval("o.methodStartsThread();");
+        assertEquals(false, o.isFinished);
+    }
+
+    @Test
+    public void accessStaticMethod() throws ScriptException {
+        assertEquals(10, e.eval("java.lang.Math.abs(-10);"));
+    }
+
+    @Test
+    public void accessSynchronousMethod() throws ScriptException {
+        e.eval("var v = new java.util.Vector();" + "v.add(10);" + "v.add(20);" + "v.add(30);");
+        assertEquals(10, e.eval("v[0]"));
+        assertEquals(20, e.eval("v[1]"));
+        assertEquals(30, e.eval("v[2]"));
+        assertEquals(3, e.eval("v.size()"));
+    }
+
+    @Test
+    public void accessStaticSynchronousMethod() throws ScriptException {
+        e.eval("var locales = java.util.Calendar.getAvailableLocales();");
+        final Locale[] locales = (Locale[])e.get("locales");
+        assertEquals(locales.length, Calendar.getAvailableLocales().length);
+    }
+
+    @Test
+    public void accessNativeMethod() throws ScriptException {
+        assertEquals(4.0, e.eval("java.lang.StrictMath.log10(10000);"));
+    }
+
+    @Test
+    public void accessConstructorOfAbstractClass() throws ScriptException {
+        e.eval("try {" +
+                "    var a = new java.util.AbstractList();" +
+                "    print('fail');" +
+                "} catch(e) {" +
+                "    var isThrown = true;" +
+                "}");
+        assertEquals(true, e.get("isThrown"));
+    }
+
+    @Test
+    public void accessMethodVoid() throws ScriptException {
+        o.isAccessed = false;
+        e.eval("o.voidMethod();");
+        assertTrue(o.isAccessed);
+    }
+
+    @Test
+    public void accessMethodBoolean() throws ScriptException {
+        assertEquals(true, e.eval("o.booleanMethod(false);"));
+        assertEquals(false, e.eval("o.booleanMethod(true);"));
+        assertEquals(false, e.eval("o.booleanMethod('false');"));
+        assertEquals(true, e.eval("o.booleanMethod('');"));
+        assertEquals(true, e.eval("o.booleanMethod(0);"));
+    }
+
+    @Test
+    public void accessMethodInt() throws ScriptException {
+        assertEquals(0, e.eval("o.intMethod(0);"));
+        assertEquals(-200, e.eval("o.intMethod(-100);"));
+        assertEquals(0, e.eval("o.intMethod('0');"));
+        assertEquals(-200, e.eval("o.intMethod('-100');"));
+    }
+
+    @Test
+    public void accessMethodLong() throws ScriptException {
+        assertEquals((long)0, e.eval("o.longMethod(0);"));
+        assertEquals((long)400, e.eval("o.longMethod(200);"));
+        assertEquals((long) 0, e.eval("o.longMethod('0');"));
+        assertEquals((long) 400, e.eval("o.longMethod('200');"));
+    }
+
+    @Test
+    public void accessMethodByte() throws ScriptException {
+        assertEquals((byte) 0, e.eval("o.byteMethod(0);"));
+        assertEquals((byte) 10, e.eval("o.byteMethod(5);"));
+        assertEquals((byte) 0, e.eval("o.byteMethod('0');"));
+        assertEquals((byte) 10, e.eval("o.byteMethod('5');"));
+    }
+
+    @Test
+    public void accessMethodShort() throws ScriptException {
+        assertEquals((short)0, e.eval("o.shortMethod(0);"));
+        assertEquals((short)8000, e.eval("o.shortMethod(4000);"));
+        assertEquals((short) 0, e.eval("o.shortMethod('0');"));
+        assertEquals((short) 8000, e.eval("o.shortMethod('4000');"));
+    }
+
+    @Test
+    public void accessMethodChar() throws ScriptException {
+        assertEquals('A', e.eval("o.charMethod('a');"));
+        assertEquals('Z', e.eval("o.charMethod('z');"));
+        assertEquals(o.charMethod((char)0), e.eval("o.charMethod(0);"));
+        assertEquals(o.charMethod((char)3150), e.eval("o.charMethod(3150);"));
+    }
+
+    @Test
+    public void accessMethodFloat() throws ScriptException {
+        assertEquals(0.0f, e.eval("o.floatMethod(0.0);"));
+        assertEquals(4.2f, e.eval("o.floatMethod(2.1);"));
+        assertEquals(0.0f, e.eval("o.floatMethod('0.0');"));
+        assertEquals(4.2f, e.eval("o.floatMethod('2.1');"));
+    }
+
+    @Test
+    public void accessMethodDouble() throws ScriptException {
+        assertEquals(0.0, e.eval("o.doubleMethod(0.0);"));
+        assertEquals(14.0, e.eval("o.doubleMethod(7.0);"));
+        assertEquals(0.0, e.eval("o.doubleMethod('0.0');"));
+        assertEquals(14.0, e.eval("o.doubleMethod('7.0');"));
+    }
+
+    @Test
+    public void accessMethodBooleanBoxing() throws ScriptException {
+        assertEquals(Boolean.TRUE, e.eval("o.booleanBoxingMethod(java.lang.Boolean.FALSE);"));
+        assertEquals(Boolean.FALSE, e.eval("o.booleanBoxingMethod(java.lang.Boolean.TRUE);"));
+        assertEquals(Boolean.TRUE, e.eval("o.booleanBoxingMethod('');"));
+        assertEquals(Boolean.FALSE, e.eval("o.booleanBoxingMethod('false');"));
+    }
+
+    @Test
+    public void accessMethodIntBoxing() throws ScriptException {
+        assertEquals(0, e.eval("o.intBoxingMethod(0);"));
+        assertEquals(-200, e.eval("o.intBoxingMethod(-100);"));
+        assertTrue((int)e.eval("(new java.lang.Integer(2)).compareTo(10.0)") < 0);
+    }
+
+    @Test
+    public void accessMethodLongBoxing() throws ScriptException {
+        assertEquals((long) 0, e.eval("o.longBoxingMethod(0);"));
+        assertEquals((long) 400, e.eval("o.longBoxingMethod(200);"));
+        assertTrue((int)e.eval("(new java.lang.Long(2)).compareTo(10.0)") < 0);
+    }
+
+    @Test
+    public void accessMethodByteBoxing() throws ScriptException {
+        assertEquals((byte) 0, e.eval("o.byteBoxingMethod(0);"));
+        assertEquals((byte) 10, e.eval("o.byteBoxingMethod(5);"));
+        assertTrue((int)e.eval("(new java.lang.Byte(2)).compareTo(10.0)") < 0);
+    }
+
+    @Test
+    public void accessMethodShortBoxing() throws ScriptException {
+        assertEquals((short) 0, e.eval("o.shortBoxingMethod(0);"));
+        assertEquals((short) 8000, e.eval("o.shortBoxingMethod(4000);"));
+        assertTrue((int)e.eval("(new java.lang.Short(2)).compareTo(10.0)") < 0);
+    }
+
+    @Test
+    public void accessMethodCharBoxing() throws ScriptException {
+        assertEquals('A', e.eval("o.charBoxingMethod('a');"));
+        assertEquals('Z', e.eval("o.charBoxingMethod('z');"));
+        assertTrue((int)e.eval("(new java.lang.Character(2)).compareTo(10)") < 0);
+    }
+
+    @Test
+    public void accessMethodFloatBoxing() throws ScriptException {
+        assertEquals(0.0f, e.eval("o.floatBoxingMethod(0.0);"));
+        assertEquals(4.2f, e.eval("o.floatBoxingMethod(2.1);"));
+        assertTrue((int)e.eval("(new java.lang.Float(2.0)).compareTo(10.0)") < 0);
+    }
+
+    @Test
+    public void accessMethodDoubleBoxing() throws ScriptException {
+        assertEquals(0.0, e.eval("o.doubleBoxingMethod(0.0);"));
+        assertEquals(14.0, e.eval("o.doubleBoxingMethod(7.0);"));
+        assertTrue((int)e.eval("(new java.lang.Double(2)).compareTo(10.0)") < 0);
+    }
+
+    @Test
+    public void accessMethodString() throws ScriptException {
+        assertEquals("", e.eval("o.stringMethod('');"));
+        assertEquals("abcabc", e.eval("o.stringMethod('abc');"));
+    }
+
+    @Test
+    public void accessMethodObject() throws ScriptException {
+        e.put("so", new Person(5));
+        e.eval("var rso = o.objectMethod(so);");
+        assertEquals(new Person(10), e.get("rso"));
+    }
+
+    @Test
+    public void accessMethodBooleanArray() throws ScriptException {
+        assertTrue(Arrays.equals(o.booleanArrayMethod(o.publicBooleanArray), (boolean[])e.eval("o.booleanArrayMethod(o.publicBooleanArray);")));
+    }
+
+    @Test
+    public void accessMethodIntArray() throws ScriptException {
+        assertArrayEquals(o.intArrayMethod(o.publicIntArray), (int[])e.eval("o.intArrayMethod(o.publicIntArray);"));
+    }
+
+    @Test
+    public void accessMethodLongArray() throws ScriptException {
+        assertArrayEquals(o.longArrayMethod(o.publicLongArray), (long[])e.eval("o.longArrayMethod(o.publicLongArray);"));
+    }
+
+    @Test
+    public void accessMethodByteArray() throws ScriptException {
+        assertArrayEquals(o.byteArrayMethod(o.publicByteArray), (byte[])e.eval("o.byteArrayMethod(o.publicByteArray);"));
+    }
+
+    @Test
+    public void accessMethodShortArray() throws ScriptException {
+        assertArrayEquals(o.shortArrayMethod(o.publicShortArray), (short[])e.eval("o.shortArrayMethod(o.publicShortArray);"));
+    }
+
+    @Test
+    public void accessMethodCharArray() throws ScriptException {
+        assertArrayEquals(o.charArrayMethod(o.publicCharArray), (char[])e.eval("o.charArrayMethod(o.publicCharArray);"));
+    }
+
+    @Test
+    public void accessMethodFloatArray() throws ScriptException {
+        assertArrayEquals(o.floatArrayMethod(o.publicFloatArray), (float[])e.eval("o.floatArrayMethod(o.publicFloatArray);"), 1e-10f);
+    }
+
+    @Test
+    public void accessMethodDoubleArray() throws ScriptException {
+        assertArrayEquals(o.doubleArrayMethod(o.publicDoubleArray), (double[])e.eval("o.doubleArrayMethod(o.publicDoubleArray);"), 1e-10);
+    }
+
+    @Test
+    public void accessMethodStringArray() throws ScriptException {
+        assertArrayEquals(o.stringArrayMethod(o.publicStringArray), (String[])e.eval("o.stringArrayMethod(o.publicStringArray);"));
+    }
+
+    @Test
+    public void accessMethodObjectArray() throws ScriptException {
+        assertArrayEquals(o.objectArrayMethod(o.publicObjectArray), (Person[])e.eval("o.objectArrayMethod(o.publicObjectArray);"));
+    }
+
+    @Test
+    public void accessDefaultConstructor() throws ScriptException {
+        e.eval("var dc = new Packages.jdk.nashorn.api.javaaccess.Person()");
+        assertEquals(new Person(), e.get("dc"));
+    }
+
+    @Test
+    public void accessCustomConstructor() throws ScriptException {
+        e.eval("var cc = new Packages.jdk.nashorn.api.javaaccess.Person(17)");
+        assertEquals(new Person(17), e.get("cc"));
+    }
+
+    @Test
+    public void accessMethod2PrimitiveParams() throws ScriptException {
+        assertEquals(o.twoParamMethod(50, 40.0), e.eval("o.twoParamMethod(50,40);"));
+    }
+
+    @Test
+    public void accessMethod3PrimitiveParams() throws ScriptException {
+        assertEquals(o.threeParamMethod((short)10, 20L, 'b'), e.eval("o.threeParamMethod(10,20,'b');"));
+    }
+
+    @Test
+    public void accessMethod2ObjectParams() throws ScriptException {
+        assertArrayEquals(new Person[] { new Person(200), new Person(300) }, (Person[])e.eval("o.twoObjectParamMethod(new Person(300),new Person(200));"));
+    }
+
+    @Test
+    public void accessMethod3ObjectParams() throws ScriptException {
+        assertArrayEquals(new Person[] { new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.threeObjectParamMethod(new Person(1),new Person(2),new Person(3));"));
+    }
+
+    @Test
+    public void accessMethod8ObjectParams() throws ScriptException {
+        assertArrayEquals(new Person[] { new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.eightObjectParamMethod(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6),new Person(7),new Person(8));"));
+    }
+
+    @Test
+    public void accessMethod9ObjectParams() throws ScriptException {
+        assertArrayEquals(new Person[] { new Person(9), new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.nineObjectParamMethod(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6)," + "new Person(7),new Person(8),new Person(9));"));
+    }
+
+    @Test
+    public void accessMethodObjectEllipsis() throws ScriptException {
+        assertArrayEquals(new Person[] { new Person(9), new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.methodObjectEllipsis(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6)," + "new Person(7),new Person(8),new Person(9));"));
+        assertArrayEquals(new Person[] {}, (Person[])e.eval("o.methodObjectEllipsis()"));
+        assertArrayEquals(new Person[] { new Person(9) }, (Person[])e.eval("o.methodObjectEllipsis(new Person(9))"));
+    }
+
+    @Test
+    public void accessMethodPrimitiveEllipsis() throws ScriptException {
+        assertArrayEquals(new Person[] { new Person(1), new Person(3), new Person(2) }, (Person[])e.eval("o.methodPrimitiveEllipsis(1,3,2);"));
+        assertArrayEquals(new Person[] {}, (Person[])e.eval("o.methodPrimitiveEllipsis();"));
+        assertArrayEquals(o.methodPrimitiveEllipsis(9, 8, 7, 6, 5, 4, 3, 2, 1), (Person[])e.eval("o.methodPrimitiveEllipsis(9,8,7,6,5,4,3,2,1);"));
+    }
+
+    @Test
+    public void accessMethodMixedEllipsis() throws ScriptException {
+        assertArrayEquals(new Object[] { new Person(1), 12, "hello", true }, (Object[])e.eval("o.methodMixedEllipsis(new Person(1),12,'hello',true);"));
+        assertArrayEquals(new Object[] {}, (Object[])e.eval("o.methodMixedEllipsis();"));
+    }
+
+    @Test
+    public void accessMethodObjectWithEllipsis() throws ScriptException {
+        assertArrayEquals(new Object[] { "hello", 12, 15, 16 }, (Object[])e.eval("o.methodObjectWithEllipsis('hello',12,15,16);"));
+        assertArrayEquals(new Object[] { "hello" }, (Object[])e.eval("o.methodObjectWithEllipsis('hello');"));
+    }
+
+    @Test
+    public void accessMethodPrimitiveWithEllipsis() throws ScriptException {
+        assertArrayEquals(new Object[] { 14, 12L, 15L, 16L }, (Object[])e.eval("o.methodPrimitiveWithEllipsis(14,12,15,16);"));
+        assertArrayEquals(new Object[] { 12 }, (Object[])e.eval("o.methodPrimitiveWithEllipsis(12);"));
+    }
+
+    @Test
+    public void accessMethodMixedWithEllipsis() throws ScriptException {
+        assertArrayEquals(new Object[] { "Hello", 10, true, -100500, 80 }, (Object[])e.eval("o.methodMixedWithEllipsis('Hello', 10, true, -100500,80.0);"));
+        assertArrayEquals(new Object[] { "Nashorn", 15 }, (Object[])e.eval("o.methodMixedWithEllipsis('Nashorn',15);"));
+    }
+
+    @Test
+    public void accessMethodOverloaded() throws ScriptException {
+        assertEquals(0, e.eval("o.overloadedMethod(0);"));
+        assertEquals(2000, e.eval("o.overloadedMethod(1000);"));
+        assertEquals(2, e.eval("o.overloadedMethod('10');"));
+        assertEquals(7, e.eval("o.overloadedMethod('Nashorn');"));
+        assertEquals(4, e.eval("o.overloadedMethod('true');"));
+        assertEquals(1, e.eval("o.overloadedMethod(true);"));
+        assertEquals(0, e.eval("o.overloadedMethod(false);"));
+        assertEquals(44, e.eval("o.overloadedMethod(new Person(22));"));
+        assertEquals(0, e.eval("o.overloadedMethod(new Person());"));
+    }
+
+    @Test
+    public void accessMethodDoubleVSintOverloaded() throws ScriptException {
+        assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(0.0);"));
+        assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(1000.0);"));
+        assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(0.01);"));
+        assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(100.02);"));
+        assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(0);"));
+        assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(1000);"));
+    }
+
+    @Test
+    public void accessJavaMethodIntFromJSFromJavaFromJS() throws ScriptException {
+        e.eval("function secondLevelMethodInt(a) {"
+                + "return o.thirdLevelMethodInt(a);"
+                + "}");
+        assertEquals(50, e.eval("o.firstLevelMethodInt(10);"));
+    }
+
+    @Test
+    public void accessJavaMethodIntegerFromJSFromJavaFromJS() throws ScriptException {
+        e.eval("function secondLevelMethodInteger(a) {"
+                + "return o.thirdLevelMethodInteger(a);"
+                + "}");
+        assertEquals(100, e.eval("o.firstLevelMethodInteger(10);"));
+    }
+
+    @Test
+    public void accessJavaMethodObjectFromJSFromJavaFromJS() throws ScriptException {
+        e.eval("function secondLevelMethodObject(p) {"
+                + "return o.thirdLevelMethodObject(p);"
+                + "}");
+        assertEquals(new Person(100), e.eval("o.firstLevelMethodObject(new Person(10));"));
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java
new file mode 100644
index 0000000..2199496
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java
@@ -0,0 +1,781 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.javaaccess;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import org.testng.TestNG;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.NumberAccessTest
+ * @run testng jdk.nashorn.api.javaaccess.NumberAccessTest
+ */
+public class NumberAccessTest {
+
+    private static ScriptEngine e = null;
+    private static SharedObject o = new SharedObject();
+
+    public static void main(final String[] args) {
+        TestNG.main(args);
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        e = m.getEngineByName("nashorn");
+        e.put("o", o);
+        e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
+    }
+
+    // --------------------------------long
+    // tests------------------------------------
+    @Test
+    public void accessFieldLong() throws ScriptException {
+        e.eval("var p_long = o.publicLong;");
+        assertEquals(o.publicLong, e.get("p_long"));
+        e.eval("o.publicLong = 12;");
+        assertEquals(12, o.publicLong);
+    }
+
+    @Test
+    public void accessFieldLongArray() throws ScriptException {
+        e.eval("var p_long_array = o.publicLongArray;");
+        assertEquals(o.publicLongArray[0], e.eval("o.publicLongArray[0];"));
+        assertArrayEquals(o.publicLongArray, (long[])e.get("p_long_array"));
+        e.eval("var t_long_arr = java.lang.reflect.Array.newInstance(java.lang.Long.TYPE, 3);" +
+                "t_long_arr[0] = -189009;" +
+                "t_long_arr[1] = 456;" +
+                "t_long_arr[2] = 600000001;" +
+                "o.publicLongArray = t_long_arr;");
+        // e.eval("o.publicIntArray = [-189009,456,600000001];");
+        assertArrayEquals(new long[] { -189009, 456, 600000001 }, o.publicLongArray);
+        e.eval("o.publicLongArray[0] = 10;");
+        assertEquals(10, o.publicLongArray[0]);
+    }
+
+    @Test
+    public void accessStaticFieldLong() throws ScriptException {
+        e.eval("var ps_long = SharedObject.publicStaticLong;");
+        assertEquals(SharedObject.publicStaticLong, e.get("ps_long"));
+        e.eval("SharedObject.publicStaticLong = 120;");
+        assertEquals(120, SharedObject.publicStaticLong);
+    }
+
+    @Test
+    public void accessStaticFieldLongArray() throws ScriptException {
+        e.eval("var ps_long_array = SharedObject.publicStaticLongArray;");
+        assertEquals(SharedObject.publicStaticLongArray[0], e.eval("SharedObject.publicStaticLongArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticLongArray, (long[])e.get("ps_long_array"));
+        e.eval("var ts_long_arr = java.lang.reflect.Array.newInstance(java.lang.Long.TYPE, 3);" +
+                "ts_long_arr[0] = -189009;" +
+                "ts_long_arr[1] = 456;" +
+                "ts_long_arr[2] = 600000001;" +
+                "SharedObject.publicStaticLongArray = ts_long_arr;");
+        // e.eval("o.publicIntArray = [-189009,456,600000001];");
+        assertArrayEquals(new long[] { -189009, 456, 600000001 }, SharedObject.publicStaticLongArray);
+        e.eval("SharedObject.publicStaticLongArray[0] = 10;");
+        assertEquals(10, SharedObject.publicStaticLongArray[0]);
+    }
+
+    @Test
+    public void accessFinalFieldLong() throws ScriptException {
+        e.eval("var pf_long = o.publicFinalLong;");
+        assertEquals(o.publicFinalLong, e.get("pf_long"));
+        e.eval("o.publicFinalLong = 120;");
+        assertEquals(13353333333333333L, o.publicFinalLong);
+    }
+
+    @Test
+    public void accessFinalFieldLongArray() throws ScriptException {
+        e.eval("var pf_long_array = o.publicFinalLongArray;");
+        assertEquals(o.publicFinalLongArray[0], e.eval("o.publicFinalLongArray[0];"));
+        assertArrayEquals(o.publicFinalLongArray, (long[])e.get("pf_long_array"));
+        e.eval("var tf_long_arr = java.lang.reflect.Array.newInstance(java.lang.Long.TYPE, 3);" +
+                "tf_long_arr[0] = -189009;" +
+                "tf_long_arr[1] = 456;" +
+                "tf_long_arr[2] = 600000001;" +
+                "o.publicFinalLongArray = tf_long_arr;");
+        // e.eval("o.publicIntArray = [-189009,456,600000001];");
+        assertArrayEquals(new long[] { 1901733333333L, -2247355555L, 3977377777L }, o.publicFinalLongArray);
+        e.eval("o.publicFinalLongArray[0] = 10;");
+        assertEquals(10, o.publicFinalLongArray[0]);
+    }
+
+    @Test
+    public void accessStaticFinalFieldLong() throws ScriptException {
+        e.eval("var psf_long = SharedObject.publicStaticFinalLong;");
+        assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long"));
+        e.eval("SharedObject.publicStaticFinalLong = 120;");
+        assertEquals(8333333333333L, SharedObject.publicStaticFinalLong);
+    }
+
+    @Test
+    public void accessStaticFinalFieldLongArray() throws ScriptException {
+        e.eval("var psf_long_array = SharedObject.publicStaticFinalLongArray;");
+        assertEquals(SharedObject.publicStaticFinalLongArray[0], e.eval("SharedObject.publicStaticFinalLongArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticFinalLongArray, (long[])e.get("psf_long_array"));
+        e.eval("var tsf_long_arr = java.lang.reflect.Array.newInstance(java.lang.Long.TYPE, 3);" +
+                "tsf_long_arr[0] = -189009;" +
+                "tsf_long_arr[1] = 456;" +
+                "tsf_long_arr[2] = 600000001;" +
+                "SharedObject.publicStaticFinalLongArray = tsf_long_arr;");
+        // e.eval("o.publicIntArray = [-189009,456,600000001];");
+        assertArrayEquals(new long[] { 19017383333L, -2247358L, 39773787L }, SharedObject.publicStaticFinalLongArray);
+        e.eval("SharedObject.publicStaticFinalLongArray[0] = 10;");
+        assertEquals(10, SharedObject.publicStaticFinalLongArray[0]);
+    }
+
+    // --------------------------------int
+    // tests------------------------------------
+    @Test
+    public void accessFieldInt() throws ScriptException {
+        e.eval("var p_int = o.publicInt;");
+        assertEquals(o.publicInt, e.get("p_int"));
+        e.eval("o.publicInt = 14;");
+        assertEquals(14, o.publicInt);
+    }
+
+    @Test
+    public void accessFieldIntArray() throws ScriptException {
+        e.eval("var p_int_array = o.publicIntArray;");
+        assertEquals(o.publicIntArray[0], e.eval("o.publicIntArray[0];"));
+        assertArrayEquals(o.publicIntArray, (int[])e.get("p_int_array"));
+        e.eval("var t_int_arr = java.lang.reflect.Array.newInstance(java.lang.Integer.TYPE, 3);" +
+                "t_int_arr[0] = 4;" +
+                "t_int_arr[1] = 5;" +
+                "t_int_arr[2] = 6;" +
+                "o.publicIntArray = t_int_arr;");
+        assertArrayEquals(new int[] { 4, 5, 6 }, o.publicIntArray);
+        e.eval("o.publicIntArray[0] = 100;");
+        assertEquals(100, o.publicIntArray[0]);
+    }
+
+    @Test
+    public void accessStaticFieldInt() throws ScriptException {
+        e.eval("var ps_int = SharedObject.publicStaticInt;");
+        assertEquals(SharedObject.publicStaticInt, e.get("ps_int"));
+        e.eval("SharedObject.publicStaticInt = 140;");
+        assertEquals(140, SharedObject.publicStaticInt);
+    }
+
+    @Test
+    public void accessStaticFieldIntArray() throws ScriptException {
+        e.eval("var ps_int_array = SharedObject.publicStaticIntArray;");
+        assertEquals(SharedObject.publicStaticIntArray[0], e.eval("SharedObject.publicStaticIntArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticIntArray, (int[])e.get("ps_int_array"));
+        e.eval("var ts_int_arr = java.lang.reflect.Array.newInstance(java.lang.Integer.TYPE, 3);" +
+                "ts_int_arr[0] = 4;" +
+                "ts_int_arr[1] = 5;" +
+                "ts_int_arr[2] = 6;" +
+                "SharedObject.publicStaticIntArray = ts_int_arr;");
+        assertArrayEquals(new int[] { 4, 5, 6 }, SharedObject.publicStaticIntArray);
+        e.eval("SharedObject.publicStaticIntArray[0] = 100;");
+        assertEquals(100, SharedObject.publicStaticIntArray[0]);
+    }
+
+    @Test
+    public void accessFinalFieldInt() throws ScriptException {
+        e.eval("var pf_int = o.publicFinalInt;");
+        assertEquals(o.publicFinalInt, e.get("pf_int"));
+
+        e.eval("o.publicFinalInt = 10;");
+        assertEquals(20712023, o.publicFinalInt);
+    }
+
+    @Test
+    public void accessFinalFieldIntArray() throws ScriptException {
+        e.eval("var pf_int_array = o.publicFinalIntArray;");
+        assertEquals(o.publicFinalIntArray[0], e.eval("o.publicFinalIntArray[0];"));
+        assertArrayEquals(o.publicFinalIntArray, (int[])e.get("pf_int_array"));
+        e.eval("var tf_int_arr = java.lang.reflect.Array.newInstance(java.lang.Integer.TYPE, 3);" +
+                "tf_int_arr[0] = 4;" +
+                "tf_int_arr[1] = 5;" +
+                "tf_int_arr[2] = 6;" +
+                "o.publicFinalIntArray = tf_int_arr;");
+        assertArrayEquals(new int[] { 50, 80, 130, 210, 340 }, o.publicFinalIntArray);
+        e.eval("o.publicFinalIntArray[0] = 100;");
+        assertEquals(100, o.publicFinalIntArray[0]);
+    }
+
+    @Test
+    public void accessStaticFinalFieldInt() throws ScriptException {
+        e.eval("var psf_int = SharedObject.publicStaticFinalInt;");
+        assertEquals(SharedObject.publicStaticFinalInt, e.get("psf_int"));
+        e.eval("SharedObject.publicStaticFinalInt = 140;");
+        assertEquals(207182023, SharedObject.publicStaticFinalInt);
+    }
+
+    @Test
+    public void accessStaticFinalFieldIntArray() throws ScriptException {
+        e.eval("var psf_int_array = SharedObject.publicStaticFinalIntArray;");
+        assertEquals(SharedObject.publicStaticFinalIntArray[0], e.eval("SharedObject.publicStaticFinalIntArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticFinalIntArray, (int[])e.get("psf_int_array"));
+        e.eval("var tsf_int_arr = java.lang.reflect.Array.newInstance(java.lang.Integer.TYPE, 3);" +
+                "tsf_int_arr[0] = 4;" +
+                "tsf_int_arr[1] = 5;" +
+                "tsf_int_arr[2] = 6;" +
+                "SharedObject.publicStaticFinalIntArray = tsf_int_arr;");
+        assertArrayEquals(new int[] { 1308, 210, 340 }, SharedObject.publicStaticFinalIntArray);
+        e.eval("SharedObject.publicStaticFinalIntArray[0] = 100;");
+        assertEquals(100, SharedObject.publicStaticFinalIntArray[0]);
+    }
+
+    // --------------------------------byte
+    // tests------------------------------------
+    @Test
+    public void accessFieldByte() throws ScriptException {
+        e.eval("var p_byte = o.publicByte;");
+        assertEquals(o.publicByte, e.get("p_byte"));
+        e.eval("o.publicByte = 16;");
+        assertEquals(16, o.publicByte);
+    }
+
+    @Test
+    public void accessFieldByteArray() throws ScriptException {
+        e.eval("var p_byte_array = o.publicByteArray;");
+        assertEquals(o.publicByteArray[0], e.eval("o.publicByteArray[0];"));
+        assertArrayEquals(o.publicByteArray, (byte[])e.get("p_byte_array"));
+        e.eval("var t_byte_arr = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 3);" +
+                "t_byte_arr[0] = -18;" +
+                "t_byte_arr[1] = 56;" +
+                "t_byte_arr[2] = 60;" +
+                "o.publicByteArray = t_byte_arr;");
+        assertArrayEquals(new byte[] { -18, 56, 60 }, o.publicByteArray);
+        e.eval("o.publicByteArray[0] = 100;");
+        assertEquals(100, o.publicByteArray[0]);
+    }
+
+    @Test
+    public void accessStaticFieldByte() throws ScriptException {
+        e.eval("var ps_byte = SharedObject.publicStaticByte;");
+        assertEquals(SharedObject.publicStaticByte, e.get("ps_byte"));
+        e.eval("SharedObject.publicStaticByte = 16;");
+        assertEquals(16, SharedObject.publicStaticByte);
+    }
+
+    @Test
+    public void accessStaticFieldByteArray() throws ScriptException {
+        e.eval("var ps_byte_array = SharedObject.publicStaticByteArray;");
+        assertEquals(SharedObject.publicStaticByteArray[0], e.eval("SharedObject.publicStaticByteArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticByteArray, (byte[])e.get("ps_byte_array"));
+        e.eval("var ts_byte_arr = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 3);" +
+                "ts_byte_arr[0] = -18;" +
+                "ts_byte_arr[1] = 56;" +
+                "ts_byte_arr[2] = 60;" +
+                "SharedObject.publicStaticByteArray = ts_byte_arr;");
+        assertArrayEquals(new byte[] { -18, 56, 60 }, SharedObject.publicStaticByteArray);
+        e.eval("SharedObject.publicStaticByteArray[0] = -90;");
+        assertEquals(-90, SharedObject.publicStaticByteArray[0]);
+    }
+
+    @Test
+    public void accessFinalFieldByte() throws ScriptException {
+        e.eval("var pf_byte = o.publicFinalByte;");
+        assertEquals(o.publicFinalByte, e.get("pf_byte"));
+        e.eval("o.publicFinalByte = 16;");
+        assertEquals(-7, o.publicFinalByte);
+    }
+
+    @Test
+    public void accessFinalFieldByteArray() throws ScriptException {
+        e.eval("var pf_byte_array = o.publicFinalByteArray;");
+        assertEquals(o.publicFinalByteArray[0], e.eval("o.publicFinalByteArray[0];"));
+        assertArrayEquals(o.publicFinalByteArray, (byte[])e.get("pf_byte_array"));
+        e.eval("var tf_byte_arr = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 3);" +
+                "tf_byte_arr[0] = -18;" +
+                "tf_byte_arr[1] = 56;" +
+                "tf_byte_arr[2] = 60;" +
+                "o.publicFinalByteArray = tf_byte_arr;");
+        assertArrayEquals(new byte[] { 1, 3, 6, 17, -128 }, o.publicFinalByteArray);
+        e.eval("o.publicFinalByteArray[0] = -90;");
+        assertEquals(-90, o.publicFinalByteArray[0]);
+    }
+
+    @Test
+    public void accessStaticFinalFieldByte() throws ScriptException {
+        e.eval("var psf_byte = SharedObject.publicStaticFinalByte;");
+        assertEquals(SharedObject.publicStaticFinalByte, e.get("psf_byte"));
+        e.eval("SharedObject.publicStaticFinalByte = 16;");
+        assertEquals(-70, SharedObject.publicStaticFinalByte);
+    }
+
+    @Test
+    public void accessStaticFinalFieldByteArray() throws ScriptException {
+        e.eval("var psf_byte_array = SharedObject.publicStaticFinalByteArray;");
+        assertEquals(SharedObject.publicStaticFinalByteArray[0], e.eval("SharedObject.publicStaticFinalByteArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticFinalByteArray, (byte[])e.get("psf_byte_array"));
+        e.eval("var tsf_byte_arr = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 3);" +
+                "tsf_byte_arr[0] = -18;" +
+                "tsf_byte_arr[1] = 56;" +
+                "tsf_byte_arr[2] = 60;" +
+                "SharedObject.publicStaticFinalByteArray = tsf_byte_arr;");
+        assertArrayEquals(new byte[] { 17, -128, 81 }, SharedObject.publicStaticFinalByteArray);
+        e.eval("SharedObject.publicStaticFinalByteArray[0] = -90;");
+        assertEquals(-90, SharedObject.publicStaticFinalByteArray[0]);
+    }
+
+    // --------------------------------short
+    // tests------------------------------------
+    @Test
+    public void accessFieldShort() throws ScriptException {
+        e.eval("var p_short = o.publicShort;");
+        assertEquals(o.publicShort, e.get("p_short"));
+        e.eval("o.publicShort = 18;");
+        assertEquals(18, o.publicShort);
+    }
+
+    @Test
+    public void accessFieldShortArray() throws ScriptException {
+        e.eval("var p_short_array = o.publicShortArray;");
+        assertEquals(o.publicShortArray[0], e.eval("o.publicShortArray[0];"));
+        assertArrayEquals(o.publicShortArray, (short[])e.get("p_short_array"));
+        e.eval("var t_short_arr = java.lang.reflect.Array.newInstance(java.lang.Short.TYPE, 3);" +
+                "t_short_arr[0] = 90;" +
+                "t_short_arr[1] = 5;" +
+                "t_short_arr[2] = -6000;" +
+                "o.publicShortArray = t_short_arr;");
+        assertArrayEquals(new short[] { 90, 5, -6000 }, o.publicShortArray);
+        e.eval("o.publicShortArray[0] = -1000;");
+        assertEquals(-1000, o.publicShortArray[0]);
+    }
+
+    @Test
+    public void accessStaticFieldShort() throws ScriptException {
+        e.eval("var ps_short = SharedObject.publicStaticShort;");
+        assertEquals(SharedObject.publicStaticShort, e.get("ps_short"));
+        e.eval("SharedObject.publicStaticShort = 180;");
+        assertEquals(180, SharedObject.publicStaticShort);
+    }
+
+    @Test
+    public void accessStaticFieldShortArray() throws ScriptException {
+        e.eval("var ps_short_array = SharedObject.publicStaticShortArray;");
+        assertEquals(SharedObject.publicStaticShortArray[0], e.eval("SharedObject.publicStaticShortArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticShortArray, (short[])e.get("ps_short_array"));
+        e.eval("var ts_short_arr = java.lang.reflect.Array.newInstance(java.lang.Short.TYPE, 3);" +
+                "ts_short_arr[0] = 90;" +
+                "ts_short_arr[1] = 5;" +
+                "ts_short_arr[2] = -6000;" +
+                "SharedObject.publicStaticShortArray = ts_short_arr;");
+        assertArrayEquals(new short[] { 90, 5, -6000 }, SharedObject.publicStaticShortArray);
+        e.eval("SharedObject.publicStaticShortArray[0] = -1000;");
+        assertEquals(-1000, SharedObject.publicStaticShortArray[0]);
+    }
+
+    @Test
+    public void accessFinalFieldShort() throws ScriptException {
+        e.eval("var pf_short = o.publicFinalShort;");
+        assertEquals(o.publicFinalShort, e.get("pf_short"));
+        e.eval("o.publicFinalShort = 180;");
+        assertEquals(31220, o.publicFinalShort);
+    }
+
+    @Test
+    public void accessFinalFieldShortArray() throws ScriptException {
+        e.eval("var pf_short_array = o.publicFinalShortArray;");
+        assertEquals(o.publicFinalShortArray[0], e.eval("o.publicFinalShortArray[0];"));
+        assertArrayEquals(o.publicFinalShortArray, (short[])e.get("pf_short_array"));
+        e.eval("var tf_short_arr = java.lang.reflect.Array.newInstance(java.lang.Short.TYPE, 3);" +
+                "tf_short_arr[0] = 90;" +
+                "tf_short_arr[1] = 5;" +
+                "tf_short_arr[2] = -6000;" +
+                "o.publicFinalShortArray = tf_short_arr;");
+        assertArrayEquals(new short[] { 12240, 9200, -17289, 1200, 12 }, o.publicFinalShortArray);
+        e.eval("o.publicFinalShortArray[0] = -1000;");
+        assertEquals(-1000, o.publicFinalShortArray[0]);
+    }
+
+    @Test
+    public void accessStaticFinalFieldShort() throws ScriptException {
+        e.eval("var psf_short = SharedObject.publicStaticFinalShort;");
+        assertEquals(SharedObject.publicStaticFinalShort, e.get("psf_short"));
+        e.eval("SharedObject.publicStaticFinalShort = 180;");
+        assertEquals(8888, SharedObject.publicStaticFinalShort);
+    }
+
+    @Test
+    public void accessStaticFinalFieldShortArray() throws ScriptException {
+        e.eval("var psf_short_array = SharedObject.publicStaticFinalShortArray;");
+        assertEquals(SharedObject.publicStaticFinalShortArray[0], e.eval("SharedObject.publicStaticFinalShortArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticFinalShortArray, (short[])e.get("psf_short_array"));
+        e.eval("var tsf_short_arr = java.lang.reflect.Array.newInstance(java.lang.Short.TYPE, 3);" +
+                "tsf_short_arr[0] = 90;" +
+                "tsf_short_arr[1] = 5;" +
+                "tsf_short_arr[2] = -6000;" +
+                "SharedObject.publicStaticFinalShortArray = tsf_short_arr;");
+        assertArrayEquals(new short[] { 8240, 9280, -1289, 120, 812 }, SharedObject.publicStaticFinalShortArray);
+        e.eval("SharedObject.publicStaticFinalShortArray[0] = -1000;");
+        assertEquals(-1000, SharedObject.publicStaticFinalShortArray[0]);
+    }
+
+    // --------------------------------char
+    // tests------------------------------------
+    @Test
+    public void accessFieldChar() throws ScriptException {
+        e.eval("var p_char = o.publicChar;");
+        assertEquals(o.publicChar, e.get("p_char"));
+        e.eval("o.publicChar = 'S';");
+        assertEquals('S', o.publicChar);
+        e.eval("o.publicChar = 10;");
+        assertEquals(10, o.publicChar);
+        e.eval("try {"
+                + "    o.publicChar = 'Big string';" +
+                "} catch(e) {" +
+                "    var isThrown = true;" +
+                "}");
+        assertEquals("Exception thrown", true, e.get("isThrown"));
+        assertEquals(10, o.publicChar);
+    }
+
+    @Test
+    public void accessFieldCharArray() throws ScriptException {
+        e.eval("var p_char_array = o.publicCharArray;");
+        assertEquals(o.publicCharArray[0], e.eval("o.publicCharArray[0];"));
+        assertArrayEquals(o.publicCharArray, (char[])e.get("p_char_array"));
+        e.eval("var t_char_arr = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 3);" +
+                "t_char_arr[0] = 'F';" +
+                "t_char_arr[1] = 'o';" +
+                "t_char_arr[2] = 'o';" +
+                "o.publicCharArray = t_char_arr;");
+        assertArrayEquals("Foo".toCharArray(), o.publicCharArray);
+        e.eval("o.publicCharArray[0] = 'Z';");
+        assertEquals('Z', o.publicCharArray[0]);
+    }
+
+    @Test
+    public void accessStaticFieldChar() throws ScriptException {
+        e.eval("var ps_char = SharedObject.publicStaticChar;");
+        assertEquals(SharedObject.publicStaticChar, e.get("ps_char"));
+        e.eval("SharedObject.publicStaticChar = 'Z';");
+        assertEquals('Z', SharedObject.publicStaticChar);
+    }
+
+    @Test
+    public void accessStaticFieldCharArray() throws ScriptException {
+        e.eval("var ps_char_array = SharedObject.publicStaticCharArray;");
+        assertEquals(SharedObject.publicStaticCharArray[0], e.eval("SharedObject.publicStaticCharArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticCharArray, (char[])e.get("ps_char_array"));
+        e.eval("var ts_char_arr = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 3);" +
+                "ts_char_arr[0] = 'G';" +
+                "ts_char_arr[1] = 'o';" +
+                "ts_char_arr[2] = 'o';" +
+                "SharedObject.publicStaticCharArray = ts_char_arr;");
+        assertArrayEquals("Goo".toCharArray(), SharedObject.publicStaticCharArray);
+        e.eval("SharedObject.publicStaticCharArray[0] = 'Z';");
+        assertEquals('Z', SharedObject.publicStaticCharArray[0]);
+    }
+
+    @Test
+    public void accessFinalFieldChar() throws ScriptException {
+        e.eval("var pf_char = o.publicFinalChar;");
+        assertEquals(o.publicFinalChar, e.get("pf_char"));
+        e.eval("o.publicFinalChar = 'S';");
+        assertEquals('E', o.publicFinalChar);
+    }
+
+    @Test
+    public void accessFinalCharArray() throws ScriptException {
+        e.eval("var pf_char_array = o.publicFinalCharArray;");
+        assertEquals(o.publicFinalCharArray[0], e.eval("o.publicFinalCharArray[0];"));
+        assertArrayEquals(o.publicFinalCharArray, (char[])e.get("pf_char_array"));
+        e.eval("var tf_char_arr = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 3);" +
+                "tf_char_arr[0] = 'F';" +
+                "tf_char_arr[1] = 'o';" +
+                "tf_char_arr[2] = 'o';" +
+                "o.publicFinalCharArray = tf_char_arr;");
+        assertArrayEquals("Nashorn hello".toCharArray(), o.publicFinalCharArray);
+        e.eval("o.publicFinalCharArray[0] = 'Z';");
+        assertEquals('Z', o.publicFinalCharArray[0]);
+    }
+
+    @Test
+    public void accessStaticFinalFieldChar() throws ScriptException {
+        e.eval("var psf_char = SharedObject.publicStaticFinalChar;");
+        assertEquals(SharedObject.publicStaticFinalChar, e.get("psf_char"));
+        e.eval("SharedObject.publicStaticFinalChar = 'Z';");
+        assertEquals('K', SharedObject.publicStaticFinalChar);
+    }
+
+    @Test
+    public void accessStaticFinalFieldCharArray() throws ScriptException {
+        e.eval("var psf_char_array = SharedObject.publicStaticFinalCharArray;");
+        assertEquals(SharedObject.publicStaticFinalCharArray[0], e.eval("SharedObject.publicStaticFinalCharArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticFinalCharArray, (char[])e.get("psf_char_array"));
+        e.eval("var tsf_char_arr = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 3);" +
+                "tsf_char_arr[0] = 'Z';" +
+                "tsf_char_arr[1] = 'o';" +
+                "tsf_char_arr[2] = 'o';" +
+                "SharedObject.publicStaticFinalCharArray = tsf_char_arr;");
+        assertArrayEquals("StaticString".toCharArray(), SharedObject.publicStaticFinalCharArray);
+        e.eval("SharedObject.publicStaticFinalCharArray[0] = 'Z';");
+        assertEquals('Z', SharedObject.publicStaticFinalCharArray[0]);
+    }
+
+    // --------------------------------float
+    // tests------------------------------------
+    @Test
+    public void accessFieldFloat() throws ScriptException {
+        e.eval("var p_float = o.publicFloat;");
+        assertEquals(o.publicFloat, e.get("p_float"));
+        o.publicFloat = 0.0f / 0.0f;
+        assertEquals(true, e.eval("isNaN(o.publicFloat)"));
+        o.publicFloat = 1.0f / 0.0f;
+        assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicFloat"));
+        o.publicFloat = -1.0f / 0.0f;
+        assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicFloat"));
+        e.eval("o.publicFloat = 20;");
+        assertEquals(20, o.publicFloat, 1e-10);
+        e.eval("o.publicFloat = 0.0/0.0;");
+        assertTrue(Float.isNaN(o.publicFloat));
+        e.eval("o.publicFloat = 1.0/0.0;");
+        assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(o.publicFloat));
+        e.eval("o.publicFloat = -1.0/0.0;");
+        assertEquals(Float.NEGATIVE_INFINITY, o.publicFloat, 1e-10);
+    }
+
+    @Test
+    public void accessFieldFloatArray() throws ScriptException {
+        e.eval("var p_float_array = o.publicFloatArray;");
+        assertEquals(o.publicFloatArray[0], e.eval("o.publicFloatArray[0];"));
+        assertArrayEquals(o.publicFloatArray, (float[])e.get("p_float_array"), 1e-10f);
+        e.eval("var t_float_arr = java.lang.reflect.Array.newInstance(java.lang.Float.TYPE, 3);" +
+                "t_float_arr[0] = 9.0;" +
+                "t_float_arr[1] = 5.12345;" +
+                "t_float_arr[2] = -60.03;" +
+                "o.publicFloatArray = t_float_arr;");
+        assertArrayEquals(new float[] { 9.0f, 5.12345f, -60.03f }, o.publicFloatArray, 1e-10f);
+        e.eval("o.publicFloatArray[0] = -513.2;");
+        assertArrayEquals(new float[] { -513.2f, 5.12345f, -60.03f }, o.publicFloatArray, 1e-10f);
+    }
+
+    @Test
+    public void accessStaticFieldFloat() throws ScriptException {
+        e.eval("var ps_float = SharedObject.publicStaticFloat;");
+        assertEquals(SharedObject.publicStaticFloat, e.get("ps_float"));
+        SharedObject.publicStaticFloat = 0.0f / 0.0f;
+        assertEquals(true, e.eval("isNaN(SharedObject.publicStaticFloat)"));
+        SharedObject.publicStaticFloat = 1.0f / 0.0f;
+        assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticFloat"));
+        SharedObject.publicStaticFloat = -1.0f / 0.0f;
+        assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticFloat"));
+        e.eval("SharedObject.publicStaticFloat = 20.0;");
+        assertEquals(20.0f, SharedObject.publicStaticFloat, 1e-10);
+        e.eval("SharedObject.publicStaticFloat = 0.0/0.0;");
+        assertTrue(Float.isNaN(SharedObject.publicStaticFloat));
+        e.eval("SharedObject.publicStaticFloat = 1.0/0.0;");
+        assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat));
+        e.eval("SharedObject.publicStaticFloat = -1.0/0.0;");
+        assertEquals(Float.floatToIntBits(Float.NEGATIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat));
+    }
+
+    @Test
+    public void accessStaticFieldFloatArray() throws ScriptException {
+        e.eval("var ps_float_array = SharedObject.publicStaticFloatArray;");
+        assertEquals(SharedObject.publicStaticFloatArray[0], e.eval("SharedObject.publicStaticFloatArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticFloatArray, (float[])e.get("ps_float_array"), 1e-10f);
+        e.eval("var ts_float_arr = java.lang.reflect.Array.newInstance(java.lang.Float.TYPE, 3);" +
+                "ts_float_arr[0] = 9.0;" +
+                "ts_float_arr[1] = 5.12345;" +
+                "ts_float_arr[2] = -60.03;" +
+                "SharedObject.publicStaticFloatArray = ts_float_arr;");
+        assertArrayEquals(new float[] { 9.0f, 5.12345f, -60.03f }, SharedObject.publicStaticFloatArray, 1e-10f);
+        e.eval("SharedObject.publicStaticFloatArray[0] = -513.2;");
+        assertArrayEquals(new float[] { -513.2f, 5.12345f, -60.03f }, SharedObject.publicStaticFloatArray, 1e-10f);
+    }
+
+    @Test
+    public void accessFinalFloat() throws ScriptException {
+        e.eval("var pf_float = o.publicFinalFloat;");
+        assertEquals(o.publicFinalFloat, e.get("pf_float"));
+        e.eval("o.publicFinalFloat = 20.0;");
+        assertEquals(7.72e8f, o.publicFinalFloat, 1e-10);
+    }
+
+    @Test
+    public void accessFinalFloatArray() throws ScriptException {
+        e.eval("var pf_float_array = o.publicFinalFloatArray;");
+        assertEquals(o.publicFinalFloatArray[0], e.eval("o.publicFinalFloatArray[0];"));
+        assertArrayEquals(o.publicFinalFloatArray, (float[])e.get("pf_float_array"), 1e-10f);
+        e.eval("var tf_float_arr = java.lang.reflect.Array.newInstance(java.lang.Float.TYPE, 3);" +
+                "tf_float_arr[0] = 9.0;" +
+                "tf_float_arr[1] = 5.12345;" +
+                "tf_float_arr[2] = -60.03;" +
+                "o.publicFinalFloatArray = tf_float_arr;");
+        assertArrayEquals(new float[] { -131.012f, 189.32f, -31.32e8f, 3.72f }, o.publicFinalFloatArray, 1e-10f);
+        e.eval("o.publicFinalFloatArray[0] = -513.2;");
+        assertEquals(-513.2f, o.publicFinalFloatArray[0], 1e-10f);
+    }
+
+    @Test
+    public void accessStaticFinalFieldFloat() throws ScriptException {
+        e.eval("var psf_float = SharedObject.publicStaticFinalFloat;");
+        assertEquals(SharedObject.publicStaticFinalFloat, e.get("psf_float"));
+        e.eval("SharedObject.publicStaticFinalFloat = 20.0;");
+        assertEquals(0.72e8f, SharedObject.publicStaticFinalFloat, 1e-10);
+    }
+
+    @Test
+    public void accessStaticFinalFieldFloatArray() throws ScriptException {
+        e.eval("var psf_float_array = SharedObject.publicStaticFinalFloatArray;");
+        assertEquals(SharedObject.publicStaticFinalFloatArray[0], e.eval("SharedObject.publicStaticFinalFloatArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticFinalFloatArray, (float[])e.get("psf_float_array"), 1e-10f);
+        e.eval("var tsf_float_arr = java.lang.reflect.Array.newInstance(java.lang.Float.TYPE, 3);" +
+                "tsf_float_arr[0] = 9.0;" +
+                "tsf_float_arr[1] = 5.12345;" +
+                "tsf_float_arr[2] = -60.03;" +
+                "SharedObject.publicStaticFinalFloatArray = tsf_float_arr;");
+        assertArrayEquals(new float[] { -8131.012f, 9.32f, -138.32e8f, 0.72f }, SharedObject.publicStaticFinalFloatArray, 1e-10f);
+        e.eval("SharedObject.publicStaticFinalFloatArray[0] = -513.2;");
+        assertEquals(-513.2f, SharedObject.publicStaticFinalFloatArray[0], 1e-10f);
+    }
+
+    // --------------------------------double
+    // tests------------------------------------
+    @Test
+    public void accessFieldDouble() throws ScriptException {
+        e.eval("var p_double = o.publicDouble;");
+        assertEquals(o.publicDouble, e.get("p_double"));
+        o.publicDouble = 0.0 / 0.0;
+        assertEquals(true, e.eval("isNaN(o.publicDouble)"));
+        o.publicDouble = 1.0 / 0.0;
+        assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicDouble"));
+        o.publicDouble = -1.0 / 0.0;
+        assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicDouble"));
+        e.eval("o.publicDouble = 30;");
+        assertEquals(Double.doubleToLongBits(30.0), Double.doubleToLongBits(o.publicDouble));
+        e.eval("o.publicDouble = 0.0/0.0;");
+        assertTrue(Double.isNaN(o.publicDouble));
+        e.eval("o.publicDouble = 1.0/0.0;");
+        assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(o.publicDouble));
+        e.eval("o.publicDouble = -1.0/0.0;");
+        assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(o.publicDouble));
+    }
+
+    @Test
+    public void accessFieldDoubleArrayRead() throws ScriptException {
+        e.eval("var p_double_array = o.publicDoubleArray;");
+        assertEquals(o.publicDoubleArray[0], e.eval("o.publicDoubleArray[0];"));
+        assertArrayEquals(o.publicDoubleArray, (double[])e.get("p_double_array"), 1e-10);
+        e.eval("var t_double_arr = java.lang.reflect.Array.newInstance(java.lang.Double.TYPE, 3);" +
+                "t_double_arr[0] = 9e10;" +
+                "t_double_arr[1] = 0.677777;" +
+                "t_double_arr[2] = -0.0000001;" +
+                "o.publicDoubleArray = t_double_arr;");
+        assertArrayEquals(new double[] { 9e10, 0.677777, -0.0000001 }, o.publicDoubleArray, 1e-10f);
+        e.eval("o.publicDoubleArray[0] = -5.2e10;");
+        assertEquals(-5.2e10, o.publicDoubleArray[0], 1e-10f);
+    }
+
+    @Test
+    public void accessStaticFieldDouble() throws ScriptException {
+        e.eval("var ps_double = SharedObject.publicStaticDouble;");
+        assertEquals(SharedObject.publicStaticDouble, e.get("ps_double"));
+        SharedObject.publicStaticDouble = 0.0 / 0.0;
+        assertEquals(true, e.eval("isNaN(SharedObject.publicStaticDouble)"));
+        SharedObject.publicStaticDouble = 1.0 / 0.0;
+        assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticDouble"));
+        SharedObject.publicStaticDouble = -1.0 / 0.0;
+        assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticDouble"));
+        e.eval("SharedObject.publicStaticDouble = 40.0;");
+        assertEquals(Double.doubleToLongBits(40.0), Double.doubleToLongBits(SharedObject.publicStaticDouble));
+        e.eval("SharedObject.publicStaticDouble = 0.0/0.0;");
+        assertTrue(Double.isNaN(SharedObject.publicStaticDouble));
+        e.eval("SharedObject.publicStaticDouble = 1.0/0.0;");
+        assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble));
+        e.eval("SharedObject.publicStaticDouble = -1.0/0.0;");
+        assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble));
+    }
+
+    @Test
+    public void accessStaticFieldDoubleArrayRead() throws ScriptException {
+        e.eval("var ps_double_array = SharedObject.publicStaticDoubleArray;");
+        assertEquals(SharedObject.publicStaticDoubleArray[0], e.eval("SharedObject.publicStaticDoubleArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticDoubleArray, (double[])e.get("ps_double_array"), 1e-10);
+        e.eval("var ts_double_arr = java.lang.reflect.Array.newInstance(java.lang.Double.TYPE, 3);" +
+                "ts_double_arr[0] = 9e10;" +
+                "ts_double_arr[1] = 0.677777;" +
+                "ts_double_arr[2] = -0.0000001;" +
+                "SharedObject.publicStaticDoubleArray = ts_double_arr;");
+        assertArrayEquals(new double[] { 9e10, 0.677777, -0.0000001 }, SharedObject.publicStaticDoubleArray, 1e-10f);
+        e.eval("SharedObject.publicStaticDoubleArray[0] = -5.2e10;");
+        assertEquals(-5.2e10, SharedObject.publicStaticDoubleArray[0], 1e-10f);
+    }
+
+    @Test
+    public void accessFinalFieldDouble() throws ScriptException {
+        e.eval("var pf_double = o.publicFinalDouble;");
+        assertEquals(o.publicFinalDouble, e.get("pf_double"));
+        e.eval("o.publicFinalDouble = 30.0;");
+        assertEquals(Double.doubleToLongBits(1.3412e20), Double.doubleToLongBits(o.publicFinalDouble));
+    }
+
+    @Test
+    public void accessFinalFieldDoubleArrayRead() throws ScriptException {
+        e.eval("var pf_double_array = o.publicFinalDoubleArray;");
+        assertEquals(o.publicFinalDoubleArray[0], e.eval("o.publicFinalDoubleArray[0];"));
+        assertArrayEquals(o.publicFinalDoubleArray, (double[])e.get("pf_double_array"), 1e-10);
+        e.eval("var tf_double_arr = java.lang.reflect.Array.newInstance(java.lang.Double.TYPE, 3);" +
+                "tf_double_arr[0] = 9e10;" +
+                "tf_double_arr[1] = 0.677777;" +
+                "tf_double_arr[2] = -0.0000001;" +
+                "o.publicFinalDoubleArray = tf_double_arr;");
+        assertArrayEquals(new double[] { 0.725e80, 0.12e10, 8e-3, 1.00077 }, o.publicFinalDoubleArray, 1e-10f);
+        e.eval("o.publicFinalDoubleArray[0] = -5.2e10;");
+        assertEquals(-5.2e10, o.publicFinalDoubleArray[0], 1e-10f);
+    }
+
+    @Test
+    public void accessStaticFinalFieldDouble() throws ScriptException {
+        e.eval("var psf_double = SharedObject.publicStaticFinalDouble;");
+        assertEquals(SharedObject.publicStaticFinalDouble, e.get("psf_double"));
+        e.eval("SharedObject.publicStaticFinalDouble = 40.0;");
+        assertEquals(Double.doubleToLongBits(1.8e12), Double.doubleToLongBits(SharedObject.publicStaticFinalDouble));
+    }
+
+    @Test
+    public void accessStaticFinalFieldDoubleArrayRead() throws ScriptException {
+        e.eval("var psf_double_array = SharedObject.publicStaticFinalDoubleArray;");
+        assertEquals(SharedObject.publicStaticFinalDoubleArray[0], e.eval("SharedObject.publicStaticFinalDoubleArray[0];"));
+        assertArrayEquals(SharedObject.publicStaticFinalDoubleArray, (double[])e.get("psf_double_array"), 1e-10);
+        e.eval("var tsf_double_arr = java.lang.reflect.Array.newInstance(java.lang.Double.TYPE, 3);" +
+                "tsf_double_arr[0] = 9e10;" +
+                "tsf_double_arr[1] = 0.677777;" +
+                "tsf_double_arr[2] = -0.0000001;" +
+                "SharedObject.publicStaticFinalDoubleArray = tsf_double_arr;");
+        assertArrayEquals(new double[] { 8.725e80, 0.82e10, 18e-3, 1.08077 }, SharedObject.publicStaticFinalDoubleArray, 1e-10f);
+        e.eval("SharedObject.publicStaticFinalDoubleArray[0] = -5.2e10;");
+        assertEquals(-5.2e10, SharedObject.publicStaticFinalDoubleArray[0], 1e-10f);
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java
new file mode 100644
index 0000000..ae719e7
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.javaaccess;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import org.testng.TestNG;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.NumberBoxingTest
+ * @run testng jdk.nashorn.api.javaaccess.NumberBoxingTest
+ */
+public class NumberBoxingTest {
+
+    private static ScriptEngine e = null;
+    private static SharedObject o = new SharedObject();
+
+    public static void main(final String[] args) {
+        TestNG.main(args);
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        e = m.getEngineByName("nashorn");
+        e.put("o", o);
+        e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
+    }
+
+    // --------------------------------long
+    // tests------------------------------------
+    @Test
+    public void accessFieldLongBoxing() throws ScriptException {
+        e.eval("var p_long = o.publicLongBox;");
+        assertEquals(o.publicLongBox, e.get("p_long"));
+        e.eval("o.publicLongBox = 12;");
+        assertEquals(Long.valueOf(12), o.publicLongBox);
+    }
+
+    @Test
+    public void accessStaticFieldLongBoxing() throws ScriptException {
+        e.eval("var ps_long = SharedObject.publicStaticLong;");
+        assertEquals(SharedObject.publicStaticLong, e.get("ps_long"));
+        e.eval("SharedObject.publicStaticLong = 120;");
+        assertEquals(120, SharedObject.publicStaticLong);
+    }
+
+    @Test
+    public void accessFinalFieldLongBoxing() throws ScriptException {
+        e.eval("var pf_long = o.publicFinalLongBox;");
+        assertEquals(o.publicFinalLongBox, e.get("pf_long"));
+        e.eval("o.publicFinalLongBox = 120;");
+        assertEquals(Long.valueOf(9377333334L), o.publicFinalLongBox);
+    }
+
+    @Test
+    public void accessStaticFinalFieldLongBoxing() throws ScriptException {
+        e.eval("var psf_long = SharedObject.publicStaticFinalLong;");
+        assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long"));
+        e.eval("SharedObject.publicStaticFinalLong = 120;");
+        assertEquals(8333333333333L, SharedObject.publicStaticFinalLong);
+    }
+
+    // --------------------------------int
+    // tests------------------------------------
+    @Test
+    public void accessFieldIntBoxing() throws ScriptException {
+        e.eval("var p_int = o.publicIntBox;");
+        assertEquals(o.publicIntBox, e.get("p_int"));
+        e.eval("o.publicIntBox = 14;");
+        assertEquals(Integer.valueOf(14), o.publicIntBox);
+    }
+
+    @Test
+    public void accessStaticFieldIntBoxing() throws ScriptException {
+        e.eval("var ps_int = SharedObject.publicStaticInt;");
+        assertEquals(SharedObject.publicStaticInt, e.get("ps_int"));
+        e.eval("SharedObject.publicStaticInt = 140;");
+        assertEquals(140, SharedObject.publicStaticInt);
+    }
+
+    @Test
+    public void accessFinalFieldIntBoxing() throws ScriptException {
+        e.eval("var pf_int = o.publicFinalIntBox;");
+        assertEquals(o.publicFinalIntBox, e.get("pf_int"));
+        e.eval("o.publicFinalIntBox = 10;");
+        assertEquals(Integer.valueOf(207512301), o.publicFinalIntBox);
+    }
+
+    @Test
+    public void accessStaticFinalFieldIntBoxing() throws ScriptException {
+        e.eval("var psf_int = SharedObject.publicStaticFinalInt;");
+        assertEquals(SharedObject.publicStaticFinalInt, e.get("psf_int"));
+        e.eval("SharedObject.publicStaticFinalInt = 140;");
+        assertEquals(207182023, SharedObject.publicStaticFinalInt);
+    }
+
+    // --------------------------------byte
+    // tests------------------------------------
+    @Test
+    public void accessFieldByteBoxing() throws ScriptException {
+        e.eval("var p_byte = o.publicByteBox;");
+        assertEquals(o.publicByteBox, e.get("p_byte"));
+        e.eval("o.publicByteBox = 16;");
+        assertEquals(Byte.valueOf((byte)16), o.publicByteBox);
+    }
+
+    @Test
+    public void accessStaticFieldByteBoxing() throws ScriptException {
+        e.eval("var ps_byte = SharedObject.publicStaticByte;");
+        assertEquals(SharedObject.publicStaticByte, e.get("ps_byte"));
+        e.eval("SharedObject.publicStaticByte = 16;");
+        assertEquals(16, SharedObject.publicStaticByte);
+    }
+
+    @Test
+    public void accessFinalFieldByteBoxing() throws ScriptException {
+        e.eval("var pf_byte = o.publicFinalByteBox;");
+        assertEquals(o.publicFinalByteBox, e.get("pf_byte"));
+        e.eval("o.publicFinalByteBox = 16;");
+        assertEquals(Byte.valueOf((byte)19), o.publicFinalByteBox);
+    }
+
+    @Test
+    public void accessStaticFinalFieldByteBoxing() throws ScriptException {
+        e.eval("var psf_byte = SharedObject.publicStaticFinalByte;");
+        assertEquals(SharedObject.publicStaticFinalByte, e.get("psf_byte"));
+        e.eval("SharedObject.publicStaticFinalByte = 16;");
+        assertEquals(-70, SharedObject.publicStaticFinalByte);
+    }
+
+    // --------------------------------short
+    // tests------------------------------------
+    @Test
+    public void accessFieldShortBoxing() throws ScriptException {
+        e.eval("var p_short = o.publicShortBox;");
+        assertEquals(o.publicShortBox, e.get("p_short"));
+        e.eval("o.publicShortBox = 18;");
+        assertEquals(Short.valueOf((short)18), o.publicShortBox);
+    }
+
+    @Test
+    public void accessStaticFieldShortBoxing() throws ScriptException {
+        e.eval("var ps_short = SharedObject.publicStaticShort;");
+        assertEquals(SharedObject.publicStaticShort, e.get("ps_short"));
+        e.eval("SharedObject.publicStaticShort = 180;");
+        assertEquals(180, SharedObject.publicStaticShort);
+    }
+
+    @Test
+    public void accessFinalFieldShortBoxing() throws ScriptException {
+        e.eval("var pf_short = o.publicFinalShortBox;");
+        assertEquals(o.publicFinalShortBox, e.get("pf_short"));
+        e.eval("o.publicFinalShortBox = 180;");
+        assertEquals(Short.valueOf((short)-26777), o.publicFinalShortBox);
+    }
+
+    @Test
+    public void accessStaticFinalFieldShortBoxing() throws ScriptException {
+        e.eval("var psf_short = SharedObject.publicStaticFinalShort;");
+        assertEquals(SharedObject.publicStaticFinalShort, e.get("psf_short"));
+        e.eval("SharedObject.publicStaticFinalShort = 180;");
+        assertEquals(8888, SharedObject.publicStaticFinalShort);
+    }
+
+    // --------------------------------char
+    // tests------------------------------------
+    @Test
+    public void accessFieldCharBoxing() throws ScriptException {
+        e.eval("var p_char = o.publicCharBox;");
+        assertEquals(o.publicCharBox, e.get("p_char"));
+        e.eval("o.publicCharBox = 'S';");
+        assertEquals(Character.valueOf('S'), o.publicCharBox);
+        e.eval("try {" +
+                "    o.publicCharBox = 'Big string';" +
+                "} catch(e) {" +
+                "    var isThrown = true;" +
+                "}");
+        assertEquals("Exception thrown", true, e.get("isThrown"));
+        assertEquals(Character.valueOf('S'), o.publicCharBox);
+    }
+
+    @Test
+    public void accessStaticFieldCharBoxing() throws ScriptException {
+        e.eval("var ps_char = SharedObject.publicStaticChar;");
+        assertEquals(SharedObject.publicStaticChar, e.get("ps_char"));
+        e.eval("SharedObject.publicStaticChar = 'Z';");
+        assertEquals('Z', SharedObject.publicStaticChar);
+    }
+
+    @Test
+    public void accessFinalFieldCharBoxing() throws ScriptException {
+        e.eval("var pf_char = o.publicFinalCharBox;");
+        assertEquals(o.publicFinalCharBox, e.get("pf_char"));
+        e.eval("o.publicFinalCharBox = 'S';");
+        assertEquals(Character.valueOf('F'), o.publicFinalCharBox);
+    }
+
+    @Test
+    public void accessStaticFinalFieldCharBoxing() throws ScriptException {
+        e.eval("var psf_char = SharedObject.publicStaticFinalChar;");
+        assertEquals(SharedObject.publicStaticFinalChar, e.get("psf_char"));
+        e.eval("SharedObject.publicStaticFinalChar = 'Z';");
+        assertEquals('K', SharedObject.publicStaticFinalChar);
+    }
+
+    // --------------------------------float
+    // tests------------------------------------
+    @Test
+    public void accessFieldFloatBoxing() throws ScriptException {
+        e.eval("var p_float = o.publicFloatBox;");
+        assertEquals(o.publicFloatBox, e.get("p_float"));
+        o.publicFloatBox = 0.0f / 0.0f;
+        assertEquals(true, e.eval("isNaN(o.publicFloatBox)"));
+        o.publicFloatBox = 1.0f / 0.0f;
+        assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicFloatBox"));
+        o.publicFloatBox = -1.0f / 0.0f;
+        assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicFloatBox"));
+        e.eval("o.publicFloatBox = 20;");
+        assertEquals(20, o.publicFloatBox, 1e-10);
+        e.eval("o.publicFloatBox = 0.0/0.0;");
+        assertTrue(Float.isNaN(o.publicFloatBox));
+        e.eval("o.publicFloatBox = 1.0/0.0;");
+        assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(o.publicFloatBox));
+        e.eval("o.publicFloatBox = -1.0/0.0;");
+        assertEquals(Float.NEGATIVE_INFINITY, o.publicFloatBox, 1e-10);
+    }
+
+    @Test
+    public void accessStaticFieldFloatBoxing() throws ScriptException {
+        e.eval("var ps_float = SharedObject.publicStaticFloat;");
+        assertEquals(SharedObject.publicStaticFloat, e.get("ps_float"));
+        SharedObject.publicStaticFloat = 0.0f / 0.0f;
+        assertEquals(true, e.eval("isNaN(SharedObject.publicStaticFloat)"));
+        SharedObject.publicStaticFloat = 1.0f / 0.0f;
+        assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticFloat"));
+        SharedObject.publicStaticFloat = -1.0f / 0.0f;
+        assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticFloat"));
+        e.eval("SharedObject.publicStaticFloat = 20.0;");
+        assertEquals(20.0f, SharedObject.publicStaticFloat, 1e-10);
+        e.eval("SharedObject.publicStaticFloat = 0.0/0.0;");
+        assertTrue(Float.isNaN(SharedObject.publicStaticFloat));
+        e.eval("SharedObject.publicStaticFloat = 1.0/0.0;");
+        assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat));
+        e.eval("SharedObject.publicStaticFloat = -1.0/0.0;");
+        assertEquals(Float.floatToIntBits(Float.NEGATIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat));
+    }
+
+    @Test
+    public void accessFinalFloatBoxing() throws ScriptException {
+        e.eval("var pf_float = o.publicFinalFloatBox;");
+        assertEquals(o.publicFinalFloatBox, e.get("pf_float"));
+        e.eval("o.publicFinalFloatBox = 20.0;");
+        assertEquals(1.372e4f, o.publicFinalFloatBox, 1e-10);
+    }
+
+    @Test
+    public void accessStaticFinalFieldFloatBoxing() throws ScriptException {
+        e.eval("var psf_float = SharedObject.publicStaticFinalFloat;");
+        assertEquals(SharedObject.publicStaticFinalFloat, e.get("psf_float"));
+        e.eval("SharedObject.publicStaticFinalFloat = 20.0;");
+        assertEquals(0.72e8f, SharedObject.publicStaticFinalFloat, 1e-10);
+    }
+
+    // --------------------------------double
+    // tests------------------------------------
+    @Test
+    public void accessFieldDoubleBoxing() throws ScriptException {
+        e.eval("var p_double = o.publicDoubleBox;");
+        assertEquals(o.publicDoubleBox, e.get("p_double"));
+        o.publicDoubleBox = 0.0 / 0.0;
+        assertEquals(true, e.eval("isNaN(o.publicDoubleBox)"));
+        o.publicDoubleBox = 1.0 / 0.0;
+        assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicDoubleBox"));
+        o.publicDoubleBox = -1.0 / 0.0;
+        assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicDoubleBox"));
+        e.eval("o.publicDoubleBox = 30;");
+        assertEquals(Double.doubleToLongBits(30.0), Double.doubleToLongBits(o.publicDoubleBox));
+        e.eval("o.publicDoubleBox = 0.0/0.0;");
+        assertTrue(Double.isNaN(o.publicDoubleBox));
+        e.eval("o.publicDoubleBox = 1.0/0.0;");
+        assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(o.publicDoubleBox));
+        e.eval("o.publicDoubleBox = -1.0/0.0;");
+        assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(o.publicDoubleBox));
+    }
+
+    @Test
+    public void accessStaticFieldDoubleBoxing() throws ScriptException {
+        e.eval("var ps_double = SharedObject.publicStaticDouble;");
+        assertEquals(SharedObject.publicStaticDouble, e.get("ps_double"));
+        SharedObject.publicStaticDouble = 0.0 / 0.0;
+        assertEquals(true, e.eval("isNaN(SharedObject.publicStaticDouble)"));
+        SharedObject.publicStaticDouble = 1.0 / 0.0;
+        assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticDouble"));
+        SharedObject.publicStaticDouble = -1.0 / 0.0;
+        assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticDouble"));
+        e.eval("SharedObject.publicStaticDouble = 40.0;");
+        assertEquals(Double.doubleToLongBits(40.0), Double.doubleToLongBits(SharedObject.publicStaticDouble));
+        e.eval("SharedObject.publicStaticDouble = 0.0/0.0;");
+        assertTrue(Double.isNaN(SharedObject.publicStaticDouble));
+        e.eval("SharedObject.publicStaticDouble = 1.0/0.0;");
+        assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble));
+        e.eval("SharedObject.publicStaticDouble = -1.0/0.0;");
+        assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble));
+    }
+
+    @Test
+    public void accessFinalFieldDoubleBoxing() throws ScriptException {
+        e.eval("var pf_double = o.publicFinalDoubleBox;");
+        assertEquals(o.publicFinalDoubleBox, e.get("pf_double"));
+        e.eval("o.publicFinalDoubleBox = 30.0;");
+        assertEquals(Double.doubleToLongBits(1.412e-12), Double.doubleToLongBits(o.publicFinalDoubleBox));
+    }
+
+    @Test
+    public void accessStaticFinalFieldDoubleBoxing() throws ScriptException {
+        e.eval("var psf_double = SharedObject.publicStaticFinalDouble;");
+        assertEquals(SharedObject.publicStaticFinalDouble, e.get("psf_double"));
+        e.eval("SharedObject.publicStaticFinalDouble = 40.0;");
+        assertEquals(Double.doubleToLongBits(1.8e12), Double.doubleToLongBits(SharedObject.publicStaticFinalDouble));
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java
new file mode 100644
index 0000000..7172051
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.javaaccess;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import org.testng.TestNG;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.ObjectAccessTest
+ * @run testng jdk.nashorn.api.javaaccess.ObjectAccessTest
+ */
+public class ObjectAccessTest {
+
+    private static ScriptEngine e = null;
+    private static SharedObject o = new SharedObject();
+
+    public static void main(final String[] args) {
+        TestNG.main(args);
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        e = m.getEngineByName("nashorn");
+        e.put("o", o);
+        e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
+        e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.Person;");
+    }
+
+    @Test
+    public void accessFieldObject() throws ScriptException {
+        e.eval("var p_object = o.publicObject;");
+        assertEquals(o.publicObject, e.get("p_object"));
+        assertEquals("object", e.eval("typeof p_object;"));
+        e.eval("o.publicObject = new Person(14);");
+        assertEquals(new Person(14), o.publicObject);
+    }
+
+    @Test
+    public void accessFieldObjectArray() throws ScriptException {
+        e.eval("var p_object_array = o.publicObjectArray;");
+        assertEquals(o.publicObjectArray[0], e.eval("o.publicObjectArray[0]"));
+        assertArrayEquals(o.publicObjectArray, (Object[])e.get("p_object_array"));
+        e.eval("var t_object_arr = java.lang.reflect.Array.newInstance(Person.class, 3);" +
+                "t_object_arr[0] = new Person(100);" +
+                "t_object_arr[1] = new Person(120);" +
+                "t_object_arr[2] = new Person(140);" +
+                "o.publicObjectArray = t_object_arr;");
+        assertArrayEquals(new Person[] { new Person(100), new Person(120), new Person(140) }, o.publicObjectArray);
+        e.eval("o.publicObjectArray[0] = new Person(10);");
+        assertEquals(new Person(10), o.publicObjectArray[0]);
+    }
+
+    @Test
+    public void accessStaticFieldObject() throws ScriptException {
+        e.eval("var ps_object = SharedObject.publicStaticObject;");
+        assertEquals(SharedObject.publicStaticObject, e.get("ps_object"));
+        assertEquals("object", e.eval("typeof ps_object;"));
+        e.eval("SharedObject.publicStaticObject = new Person(16);");
+        assertEquals(new Person(16), SharedObject.publicStaticObject);
+    }
+
+    @Test
+    public void accessStaticFieldObjectArray() throws ScriptException {
+        e.eval("var ps_object_array = SharedObject.publicStaticObjectArray;");
+        assertEquals(SharedObject.publicStaticObjectArray[0], e.eval("SharedObject.publicStaticObjectArray[0]"));
+        assertArrayEquals(SharedObject.publicStaticObjectArray, (Object[])e.get("ps_object_array"));
+        e.eval("var ts_object_arr = java.lang.reflect.Array.newInstance(Person.class, 3);" +
+                "ts_object_arr[0] = new Person(100);" +
+                "ts_object_arr[1] = new Person(120);" +
+                "ts_object_arr[2] = new Person(140);" +
+                "SharedObject.publicStaticObjectArray = ts_object_arr;");
+        assertArrayEquals(new Person[] { new Person(100), new Person(120), new Person(140) }, SharedObject.publicStaticObjectArray);
+        e.eval("SharedObject.publicStaticObjectArray[0] = new Person(10);");
+        assertEquals(new Person(10), SharedObject.publicStaticObjectArray[0]);
+    }
+
+    @Test
+    public void accessFinalFieldObject() throws ScriptException {
+        e.eval("var pf_object = o.publicFinalObject;");
+        assertEquals(o.publicFinalObject, e.get("pf_object"));
+        assertEquals("object", e.eval("typeof pf_object;"));
+        e.eval("o.publicFinalObject = new Person(-999);");
+        assertEquals(new Person(1024), o.publicFinalObject);
+    }
+
+    @Test
+    public void accessFinalFieldObjectArray() throws ScriptException {
+        e.eval("var pf_object_array = o.publicFinalObjectArray;");
+        assertEquals(o.publicFinalObjectArray[0], e.eval("o.publicFinalObjectArray[0]"));
+        assertArrayEquals(o.publicFinalObjectArray, (Object[])e.get("pf_object_array"));
+        e.eval("var tf_object_arr = java.lang.reflect.Array.newInstance(Person.class, 3);" +
+                "tf_object_arr[0] = new Person(100);" +
+                "tf_object_arr[1] = new Person(120);" +
+                "tf_object_arr[2] = new Person(140);" +
+                "o.publicOFinalbjectArray = tf_object_arr;");
+        assertArrayEquals(new Person[] { new Person(-900), new Person(1000), new Person(180) }, o.publicFinalObjectArray);
+        e.eval("o.publicFinalObjectArray[0] = new Person(10);");
+        assertEquals(new Person(10), o.publicFinalObjectArray[0]);
+    }
+
+    @Test
+    public void accessStaticFinalFieldObject() throws ScriptException {
+        e.eval("var psf_object = SharedObject.publicStaticFinalObject;");
+        assertEquals(SharedObject.publicStaticFinalObject, e.get("psf_object"));
+        assertEquals("object", e.eval("typeof psf_object;"));
+        e.eval("SharedObject.publicStaticFinalObject = new Person(6);");
+        assertEquals(new Person(2048), SharedObject.publicStaticFinalObject);
+    }
+
+    @Test
+    public void accessStaticFinalFieldObjectArray() throws ScriptException {
+        e.eval("var psf_object_array = SharedObject.publicStaticFinalObjectArray;");
+        assertEquals(SharedObject.publicStaticFinalObjectArray[0], e.eval("SharedObject.publicStaticFinalObjectArray[0]"));
+        assertArrayEquals(SharedObject.publicStaticFinalObjectArray, (Object[])e.get("psf_object_array"));
+        e.eval("var tsf_object_arr = java.lang.reflect.Array.newInstance(Person.class, 3);" +
+                "tsf_object_arr[0] = new Person(100);" +
+                "tsf_object_arr[1] = new Person(120);" +
+                "tsf_object_arr[2] = new Person(140);" +
+                "SharedObject.publicStaticFinalObjectArray = tsf_object_arr;");
+        assertArrayEquals(new Person[] { new Person(-9), new Person(110), new Person(Integer.MAX_VALUE) }, SharedObject.publicStaticFinalObjectArray);
+        e.eval("SharedObject.publicStaticFinalObjectArray[0] = new Person(90);");
+        assertEquals(new Person(90), SharedObject.publicStaticFinalObjectArray[0]);
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/Person.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/Person.java
new file mode 100644
index 0000000..9012e63
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/Person.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.javaaccess;
+
+public class Person {
+
+    public int id = 0;
+
+    public Person() {
+    }
+
+    public Person(final int code) {
+        this.id = code;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj != null && obj instanceof Person) {
+            final Person o = (Person)obj;
+            return this.id == o.id;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return id;
+    }
+
+    @Override
+    public String toString() {
+        return "Person(" + id + ")";
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/SharedObject.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/SharedObject.java
new file mode 100644
index 0000000..a7ef3ab
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/SharedObject.java
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.javaaccess;
+
+import javax.script.Invocable;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+public class SharedObject {
+
+    // Public fields
+    public String                 publicString                  = "PublicString";
+    public String[]               publicStringArray             = { "ArrayString[0]", "ArrayString[1]", "ArrayString[2]", "ArrayString[3]" };
+    public Person                 publicObject                  = new Person(256);
+    public Person[]               publicObjectArray             = { new Person(4), new Person(-422), new Person(14) };
+    public boolean                publicBoolean                 = true;
+    public boolean[]              publicBooleanArray            = { true, false, false, true };
+    public Boolean                publicBooleanBox              = true;
+    public long                   publicLong                    = 933333333333333333L;
+    public long[]                 publicLongArray               = { 99012333333333L, -124355555L, 89777777777L };
+    public Long                   publicLongBox                 = 9333333333L;
+    public int                    publicInt                     = 2076543123;
+    public int[]                  publicIntArray                = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
+    public Integer                publicIntBox                  = 20765123;
+    public byte                   publicByte                    = -128;
+    public byte[]                 publicByteArray               = { 1, 2, 4, 8, 16, 32, 64, 127, -128 };
+    public Byte                   publicByteBox                 = 127;
+    public short                  publicShort                   = 32000;
+    public short[]                publicShortArray              = { 3240, 8900, -16789, 1, 12 };
+    public Short                  publicShortBox                = Short.MIN_VALUE;
+    public float                  publicFloat                   = 0.7e6f;
+    public float[]                publicFloatArray              = { -32.01f, 89.3f, -1.3e8f, 3.1f };
+    public Float                  publicFloatBox                = 1.377e4f;
+    public double                 publicDouble                  = 1.34e20;
+    public double[]               publicDoubleArray             = { 0.75e80, 8e-43, 1.000077, 0.123e10 };
+    public Double                 publicDoubleBox               = 1.4e-19;
+    public char                   publicChar                    = 'A';
+    public char[]                 publicCharArray               = "Hello Nashorn".toCharArray();
+    public Character              publicCharBox                 = 'B';
+    // Public static fields
+    public static String          publicStaticString            = "PublicStaticString";
+    public static String[]        publicStaticStringArray       = { "StaticArrayString[0]", "StaticArrayString[1]", "StaticArrayString[2]", "StaticArrayString[3]" };
+    public static Person          publicStaticObject            = new Person(512);
+    public static Person[]        publicStaticObjectArray       = { new Person(40), new Person(-22), new Person(18) };
+    public static boolean         publicStaticBoolean           = true;
+    public static boolean[]       publicStaticBooleanArray      = { false, false, false, true };
+    public static Boolean         publicStaticBooleanBox        = true;
+    public static long            publicStaticLong              = 13333333333333333L;
+    public static long[]          publicStaticLongArray         = { 19012333333333L, -224355555L, 39777777777L };
+    public static Long            publicStaticLongBox           = 9333333334L;
+    public static int             publicStaticInt               = 207654323;
+    public static int[]           publicStaticIntArray          = { 5, 8, 13, 21, 34 };
+    public static Integer         publicStaticIntBox            = 2075123;
+    public static byte            publicStaticByte              = -12;
+    public static byte[]          publicStaticByteArray         = { 16, 32, 64, 127, -128 };
+    public static Byte            publicStaticByteBox           = 17;
+    public static short           publicStaticShort             = 320;
+    public static short[]         publicStaticShortArray        = { 1240, 900, -1789, 100, 12 };
+    public static Short           publicStaticShortBox          = -16777;
+    public static float           publicStaticFloat             = 7.7e8f;
+    public static float[]         publicStaticFloatArray        = { -131.01f, 189.3f, -31.3e8f, 3.7f };
+    public static Float           publicStaticFloatBox          = 1.37e4f;
+    public static double          publicStaticDouble            = 1.341e20;
+    public static double[]        publicStaticDoubleArray       = { 0.75e80, 0.123e10, 8e-43, 1.000077 };
+    public static Double          publicStaticDoubleBox         = 1.41e-12;
+    public static char            publicStaticChar              = 'C';
+    public static char[]          publicStaticCharArray         = "Nashorn".toCharArray();
+    public static Character       publicStaticCharBox           = 'D';
+    // Public final fields
+    public final String           publicFinalString             = "PublicFinalString";
+    public final String[]         publicFinalStringArray        = { "FinalArrayString[0]", "FinalArrayString[1]", "FinalArrayString[2]", "FinalArrayString[3]" };
+    public final Person           publicFinalObject             = new Person(1024);
+    public final Person[]         publicFinalObjectArray        = { new Person(-900), new Person(1000), new Person(180) };
+    public final boolean          publicFinalBoolean            = true;
+    public final boolean[]        publicFinalBooleanArray       = { false, false, true, false };
+    public final Boolean          publicFinalBooleanBox         = true;
+    public final long             publicFinalLong               = 13353333333333333L;
+    public final long[]           publicFinalLongArray          = { 1901733333333L, -2247355555L, 3977377777L };
+    public final Long             publicFinalLongBox            = 9377333334L;
+    public final int              publicFinalInt                = 20712023;
+    public final int[]            publicFinalIntArray           = { 50, 80, 130, 210, 340 };
+    public final Integer          publicFinalIntBox             = 207512301;
+    public final byte             publicFinalByte               = -7;
+    public final byte[]           publicFinalByteArray          = { 1, 3, 6, 17, -128 };
+    public final Byte             publicFinalByteBox            = 19;
+    public final short            publicFinalShort              = 31220;
+    public final short[]          publicFinalShortArray         = { 12240, 9200, -17289, 1200, 12 };
+    public final Short            publicFinalShortBox           = -26777;
+    public final float            publicFinalFloat              = 7.72e8f;
+    public final float[]          publicFinalFloatArray         = { -131.012f, 189.32f, -31.32e8f, 3.72f };
+    public final Float            publicFinalFloatBox           = 1.372e4f;
+    public final double           publicFinalDouble             = 1.3412e20;
+    public final double[]         publicFinalDoubleArray        = { 0.725e80, 0.12e10, 8e-3, 1.00077 };
+    public final Double           publicFinalDoubleBox          = 1.412e-12;
+    public final char             publicFinalChar               = 'E';
+    public final char[]           publicFinalCharArray          = "Nashorn hello".toCharArray();
+    public final Character        publicFinalCharBox            = 'F';
+    // Public static final fields
+    public static final String    publicStaticFinalString       = "PublicStaticFinalString";
+    public static final String[]  publicStaticFinalStringArray  = { "StaticFinalArrayString[0]", "StaticFinalArrayString[1]", "StaticFinalArrayString[2]", "StaticFinalArrayString[3]" };
+    public static final Person    publicStaticFinalObject       = new Person(2048);
+    public static final Person[]  publicStaticFinalObjectArray  = { new Person(-9), new Person(110), new Person(Integer.MAX_VALUE) };
+    public static final boolean   publicStaticFinalBoolean      = true;
+    public static final boolean[] publicStaticFinalBooleanArray = { false, true, false, false };
+    public static final Boolean   publicStaticFinalBooleanBox   = true;
+    public static final long      publicStaticFinalLong         = 8333333333333L;
+    public static final long[]    publicStaticFinalLongArray    = { 19017383333L, -2247358L, 39773787L };
+    public static final Long      publicStaticFinalLongBox      = 9377388334L;
+    public static final int       publicStaticFinalInt          = 207182023;
+    public static final int[]     publicStaticFinalIntArray     = { 1308, 210, 340 };
+    public static final Integer   publicStaticFinalIntBox       = 2078301;
+    public static final byte      publicStaticFinalByte         = -70;
+    public static final byte[]    publicStaticFinalByteArray    = { 17, -128, 81 };
+    public static final Byte      publicStaticFinalByteBox      = 91;
+    public static final short     publicStaticFinalShort        = 8888;
+    public static final short[]   publicStaticFinalShortArray   = { 8240, 9280, -1289, 120, 812 };
+    public static final Short     publicStaticFinalShortBox     = -26;
+    public static final float     publicStaticFinalFloat        = 0.72e8f;
+    public static final float[]   publicStaticFinalFloatArray   = { -8131.012f, 9.32f, -138.32e8f, 0.72f };
+    public static final Float     publicStaticFinalFloatBox     = 1.2e4f;
+    public static final double    publicStaticFinalDouble       = 1.8e12;
+    public static final double[]  publicStaticFinalDoubleArray  = { 8.725e80, 0.82e10, 18e-3, 1.08077 };
+    public static final Double    publicStaticFinalDoubleBox    = 1.5612e-13;
+    public static final char      publicStaticFinalChar         = 'K';
+    public static final char[]    publicStaticFinalCharArray    = "StaticString".toCharArray();
+    public static final Character publicStaticFinalCharBox      = 'L';
+
+    // Special vars
+    public volatile boolean       volatileBoolean               = true;
+    public transient boolean      transientBoolean              = true;
+
+    // For methods testing
+    public boolean                isAccessed                    = false;
+    public volatile boolean       isFinished                    = false;
+
+    private ScriptEngine engine;
+
+    public ScriptEngine getEngine() {
+        return engine;
+    }
+
+    public void setEngine(ScriptEngine engine) {
+        this.engine = engine;
+    }
+
+    public void voidMethod() {
+        isAccessed = true;
+    }
+
+    public boolean booleanMethod(final boolean arg) {
+        return !arg;
+    }
+
+    public Boolean booleanBoxingMethod(final Boolean arg) {
+        return !arg.booleanValue();
+    }
+
+    public boolean[] booleanArrayMethod(final boolean arg[]) {
+        final boolean[] res = new boolean[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            res[i] = !arg[i];
+        }
+        return res;
+    }
+
+    public int intMethod(final int arg) {
+        return arg + arg;
+    }
+
+    public Integer intBoxingMethod(final Integer arg) {
+        return arg + arg;
+    }
+
+    public int[] intArrayMethod(final int arg[]) {
+        final int[] res = new int[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            res[i] = arg[i] * 2;
+        }
+        return res;
+    }
+
+    public long longMethod(final long arg) {
+        return arg + arg;
+    }
+
+    public Long longBoxingMethod(final Long arg) {
+        return arg + arg;
+    }
+
+    public long[] longArrayMethod(final long[] arg) {
+        final long[] res = new long[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            res[i] = arg[i] * 2;
+        }
+        return res;
+    }
+
+    public byte byteMethod(final byte arg) {
+        return (byte)(arg + arg);
+    }
+
+    public Byte byteBoxingMethod(final Byte arg) {
+        return (byte)(arg + arg);
+    }
+
+    public byte[] byteArrayMethod(final byte[] arg) {
+        final byte[] res = new byte[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            res[i] = (byte)(arg[i] * 2);
+        }
+        return res;
+    }
+
+    public char charMethod(final char arg) {
+        return Character.toUpperCase(arg);
+    }
+
+    public Character charBoxingMethod(final Character arg) {
+        return Character.toUpperCase(arg);
+    }
+
+    public char[] charArrayMethod(final char[] arg) {
+        final char[] res = new char[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            res[i] = Character.toUpperCase(arg[i]);
+        }
+        return res;
+    }
+
+    public short shortMethod(final short arg) {
+        return (short)(arg + arg);
+    }
+
+    public Short shortBoxingMethod(final Short arg) {
+        return (short)(arg + arg);
+    }
+
+    public short[] shortArrayMethod(final short[] arg) {
+        final short[] res = new short[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            res[i] = (short)(arg[i] * 2);
+        }
+        return res;
+    }
+
+    public float floatMethod(final float arg) {
+        return arg + arg;
+    }
+
+    public Float floatBoxingMethod(final Float arg) {
+        return arg + arg;
+    }
+
+    public float[] floatArrayMethod(final float[] arg) {
+        final float[] res = new float[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            res[i] = arg[i] * 2;
+        }
+        return res;
+    }
+
+    public double doubleMethod(final double arg) {
+        return arg + arg;
+    }
+
+    public Double doubleBoxingMethod(final Double arg) {
+        return arg + arg;
+    }
+
+    public double[] doubleArrayMethod(final double[] arg) {
+        final double[] res = new double[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            res[i] = arg[i] * 2;
+        }
+        return res;
+    }
+
+    public String stringMethod(final String str) {
+        return str + str;
+    }
+
+    public String[] stringArrayMethod(final String[] arr) {
+        final int l = arr.length;
+        final String[] res = new String[l];
+        for (int i = 0; i < l; i++) {
+            res[i] = arr[l - i - 1];
+        }
+        return res;
+    }
+
+    public Person[] objectArrayMethod(final Person[] arr) {
+        final Person[] res = new Person[arr.length];
+        for (int i = 0; i < arr.length; i++) {
+            res[i] = new Person(i + 100);
+        }
+        return res;
+    }
+
+    public Person objectMethod(final Person t) {
+        t.id *= 2;
+        return t;
+    }
+
+    public int twoParamMethod(final long l, final double d) {
+        return (int)(l + d);
+    }
+
+    public int threeParamMethod(final short s, final long l, final char c) {
+        return (int)(s + l + c);
+    }
+
+    public Person[] twoObjectParamMethod(final Person arg1, final Person arg2) {
+        return new Person[] { arg2, arg1 };
+    }
+
+    public Person[] threeObjectParamMethod(final Person arg1, final Person arg2, final Person arg3) {
+        return new Person[] { arg3, arg2, arg1 };
+    }
+
+    public Person[] eightObjectParamMethod(final Person arg1, final Person arg2, final Person arg3, final Person arg4, final Person arg5, final Person arg6, final Person arg7, final Person arg8) {
+        return new Person[] { arg8, arg7, arg6, arg5, arg4, arg3, arg2, arg1 };
+    }
+
+    public Person[] nineObjectParamMethod(final Person arg1, final Person arg2, final Person arg3, final Person arg4, final Person arg5, final Person arg6, final Person arg7, final Person arg8, final Person arg9) {
+        return new Person[] { arg9, arg8, arg7, arg6, arg5, arg4, arg3, arg2, arg1 };
+    }
+
+    public Person[] methodObjectEllipsis(final Person... args) {
+        final int l = args.length;
+        final Person[] res = new Person[l];
+        for (int i = 0; i < l; i++) {
+            res[i] = args[l - i - 1];
+        }
+        return res;
+    }
+
+    public Person[] methodPrimitiveEllipsis(final int... args) {
+        final int l = args.length;
+        final Person[] res = new Person[l];
+        for (int i = 0; i < l; i++) {
+            res[i] = new Person(args[i]);
+        }
+        return res;
+    }
+
+    public Object[] methodMixedEllipsis(final Object... args) {
+        return args;
+    }
+
+    public Object[] methodObjectWithEllipsis(final String arg, final int... args) {
+        final Object[] res = new Object[args.length + 1];
+        res[0] = arg;
+        for (int i = 0; i < args.length; i++) {
+            res[i + 1] = args[i];
+        }
+        return res;
+    }
+
+    public Object[] methodPrimitiveWithEllipsis(final int arg, final long... args) {
+        final Object[] res = new Object[args.length + 1];
+        res[0] = arg;
+        for (int i = 0; i < args.length; i++) {
+            res[i + 1] = args[i];
+        }
+        return res;
+    }
+
+    public Object[] methodMixedWithEllipsis(final String arg1, final int arg2, final Object... args) {
+        final Object[] res = new Object[args.length + 2];
+        res[0] = arg1;
+        res[1] = arg2;
+        System.arraycopy(args, 0, res, 2, args.length);
+        return res;
+    }
+
+    public void methodStartsThread() {
+        isFinished = false;
+
+        final Thread t = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Thread.sleep(1000);
+                    isFinished = true;
+                } catch (final InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+
+        t.start();
+    }
+
+    public String overloadedMethodDoubleVSint(int arg) {
+        return "int";
+    }
+
+    public String overloadedMethodDoubleVSint(double arg) {
+        return "double";
+    }
+
+    public int overloadedMethod(int arg) {
+        return arg*2;
+    }
+
+    public int overloadedMethod(String arg) {
+        return arg.length();
+    }
+
+    public int overloadedMethod(boolean arg) {
+        return (arg) ? 1 : 0;
+    }
+
+    public int overloadedMethod(Person arg) {
+        return arg.id*2;
+    }
+
+    public int firstLevelMethodInt(int arg) throws ScriptException, NoSuchMethodException {
+        return (int) ((Invocable)engine).invokeFunction("secondLevelMethodInt", arg);
+    }
+
+    public int thirdLevelMethodInt(int arg) {
+        return arg*5;
+    }
+
+    public int firstLevelMethodInteger(Integer arg) throws ScriptException, NoSuchMethodException {
+        return (int) ((Invocable)engine).invokeFunction("secondLevelMethodInteger", arg);
+    }
+
+    public int thirdLevelMethodInteger(Integer arg) {
+        return arg*10;
+    }
+
+    public Person firstLevelMethodObject(Person p) throws ScriptException, NoSuchMethodException {
+        return (Person) ((Invocable)engine).invokeFunction("secondLevelMethodObject", p);
+    }
+
+    public Person thirdLevelMethodObject(Person p) {
+        p.id *= 10;
+        return p;
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java
new file mode 100644
index 0000000..6a7713b
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.javaaccess;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import org.testng.TestNG;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.StringAccessTest
+ * @run testng jdk.nashorn.api.javaaccess.StringAccessTest
+ */
+public class StringAccessTest {
+
+    private static ScriptEngine e = null;
+    private static SharedObject o = new SharedObject();
+
+    public static void main(final String[] args) {
+        TestNG.main(args);
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        e = m.getEngineByName("nashorn");
+        e.put("o", o);
+        e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
+    }
+
+    @Test
+    public void accessFieldString() throws ScriptException {
+        e.eval("var p_string = o.publicString;");
+        assertEquals(o.publicString, e.get("p_string"));
+        assertEquals("string", e.eval("typeof p_string;"));
+        e.eval("o.publicString = 'changedString';");
+        assertEquals("changedString", o.publicString);
+    }
+
+    @Test
+    public void accessFieldStringArray() throws ScriptException {
+        e.eval("var p_string_array = o.publicStringArray;");
+        assertEquals(o.publicStringArray[0], e.eval("o.publicStringArray[0]"));
+        assertArrayEquals(o.publicStringArray, (String[])e.get("p_string_array"));
+        e.eval("var t_string_arr = java.lang.reflect.Array.newInstance(java.lang.String.class, 3);" +
+                "t_string_arr[0] = 'abc';" +
+                "t_string_arr[1] = '123';" +
+                "t_string_arr[2] = 'xyzzzz';" +
+                "o.publicStringArray = t_string_arr;");
+        assertArrayEquals(new String[] { "abc", "123", "xyzzzz" }, o.publicStringArray);
+        e.eval("o.publicStringArray[0] = 'nashorn';");
+        assertEquals("nashorn", o.publicStringArray[0]);
+    }
+
+    @Test
+    public void accessStaticFieldString() throws ScriptException {
+        e.eval("var ps_string = SharedObject.publicStaticString;");
+        assertEquals(SharedObject.publicStaticString, e.get("ps_string"));
+        assertEquals("string", e.eval("typeof ps_string;"));
+        e.eval("SharedObject.publicStaticString = 'changedString';");
+        assertEquals("changedString", SharedObject.publicStaticString);
+    }
+
+    @Test
+    public void accessStaticFieldStringArray() throws ScriptException {
+        e.eval("var ps_string_array = SharedObject.publicStaticStringArray;");
+        assertEquals(SharedObject.publicStaticStringArray[0], e.eval("SharedObject.publicStaticStringArray[0]"));
+        assertArrayEquals(SharedObject.publicStaticStringArray, (String[])e.get("ps_string_array"));
+        e.eval("var ts_string_arr = java.lang.reflect.Array.newInstance(java.lang.String.class, 3);" +
+                "ts_string_arr[0] = 'abc';" +
+                "ts_string_arr[1] = '123';" +
+                "ts_string_arr[2] = 'xyzzzz';" +
+                "SharedObject.publicStaticStringArray = ts_string_arr;");
+        assertArrayEquals(new String[] { "abc", "123", "xyzzzz" }, SharedObject.publicStaticStringArray);
+        e.eval("SharedObject.publicStaticStringArray[0] = 'nashorn';");
+        assertEquals("nashorn", SharedObject.publicStaticStringArray[0]);
+    }
+
+    @Test
+    public void accessFinalFieldString() throws ScriptException {
+        e.eval("var pf_string = o.publicFinalString;");
+        assertEquals(o.publicFinalString, e.get("pf_string"));
+        assertEquals("string", e.eval("typeof pf_string;"));
+        e.eval("o.publicFinalString = 'changedString';");
+        assertEquals("PublicFinalString", o.publicFinalString);
+    }
+
+    @Test
+    public void accessFinalFieldStringArray() throws ScriptException {
+        e.eval("var pf_string_array = o.publicFinalStringArray;");
+        assertEquals(o.publicFinalStringArray[0], e.eval("o.publicFinalStringArray[0]"));
+        assertArrayEquals(o.publicFinalStringArray, (String[])e.get("pf_string_array"));
+        e.eval("var tf_string_arr = java.lang.reflect.Array.newInstance(java.lang.String.class, 3);" +
+                "tf_string_arr[0] = 'abc';" +
+                "tf_string_arr[1] = '123';" +
+                "tf_string_arr[2] = 'xyzzzz';" +
+                "o.publicFinalStringArray = tf_string_arr;");
+        assertArrayEquals(new String[] { "FinalArrayString[0]", "FinalArrayString[1]", "FinalArrayString[2]", "FinalArrayString[3]" }, o.publicFinalStringArray);
+        e.eval("o.publicFinalStringArray[0] = 'nashorn';");
+        assertEquals("nashorn", o.publicFinalStringArray[0]);
+    }
+
+    @Test
+    public void accessStaticFinalFieldString() throws ScriptException {
+        e.eval("var psf_string = SharedObject.publicStaticFinalString;");
+        assertEquals(SharedObject.publicStaticFinalString, e.get("psf_string"));
+        assertEquals("string", e.eval("typeof psf_string;"));
+        e.eval("SharedObject.publicStaticFinalString = 'changedString';");
+        assertEquals("PublicStaticFinalString", SharedObject.publicStaticFinalString);
+    }
+
+    @Test
+    public void accessStaticFinalFieldStringArray() throws ScriptException {
+        e.eval("var psf_string_array = SharedObject.publicStaticFinalStringArray;");
+        assertEquals(SharedObject.publicStaticFinalStringArray[0], e.eval("SharedObject.publicStaticFinalStringArray[0]"));
+        assertArrayEquals(SharedObject.publicStaticFinalStringArray, (String[])e.get("psf_string_array"));
+        e.eval("var tsf_string_arr = java.lang.reflect.Array.newInstance(java.lang.String.class, 3);" +
+                "tsf_string_arr[0] = 'abc';" +
+                "tsf_string_arr[1] = '123';" +
+                "tsf_string_arr[2] = 'xyzzzz';" +
+                "SharedObject.publicStaticFinalStringArray = tsf_string_arr;");
+        assertArrayEquals(new String[] { "StaticFinalArrayString[0]",
+                    "StaticFinalArrayString[1]",
+                    "StaticFinalArrayString[2]",
+                    "StaticFinalArrayString[3]" },
+                SharedObject.publicStaticFinalStringArray);
+        e.eval("SharedObject.publicStaticFinalStringArray[0] = 'nashorn';");
+        assertEquals("nashorn", SharedObject.publicStaticFinalStringArray[0]);
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/MultipleEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/MultipleEngineTest.java
new file mode 100644
index 0000000..f72f8e6
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/MultipleEngineTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import org.testng.annotations.Test;
+
+/**
+ * Test that we can create multiple, independent script engines and use those
+ * independently.
+ *
+ * @test
+ * @run testng jdk.nashorn.api.scripting.MultipleEngineTest
+ */
+
+public class MultipleEngineTest {
+    @Test
+    public void createAndUseManyEngine() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+
+        final ScriptEngine e1 = m.getEngineByName("nashorn");
+        e1.eval("var  x = 33; print(x);");
+
+        final ScriptEngine e2 = m.getEngineByName("nashorn");
+        e2.eval("try { print(x) } catch(e) { print(e); }");
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java
new file mode 100644
index 0000000..6346313
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import static org.testng.Assert.fail;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import org.testng.annotations.Test;
+
+/**
+ * jsr223 tests for security access checks.
+ */
+public class ScriptEngineSecurityTest {
+
+    private void log(String msg) {
+        org.testng.Reporter.log(msg, true);
+    }
+
+    @Test
+    public void securityPackagesTest() {
+        if (System.getSecurityManager() == null) {
+            // pass vacuously
+        }
+
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("var v = Packages.sun.misc.Unsafe;");
+            fail("should have thrown SecurityException");
+        } catch (final Exception exp) {
+            if (exp instanceof SecurityException) {
+                log("got " + exp + " as expected");
+            } else {
+                fail(exp.getMessage());
+            }
+        }
+    }
+
+    @Test
+    public void securityJavaTypeTest() {
+        if (System.getSecurityManager() == null) {
+            // pass vacuously
+        }
+
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("var v = Java.type('sun.misc.Unsafe');");
+            fail("should have thrown SecurityException");
+        } catch (final Exception exp) {
+            if (exp instanceof SecurityException) {
+                log("got " + exp + " as expected");
+            } else {
+                fail(exp.getMessage());
+            }
+        }
+    }
+
+    @Test
+    public void securityClassForNameTest() {
+        if (System.getSecurityManager() == null) {
+            // pass vacuously
+        }
+
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("var v = java.lang.Class.forName('sun.misc.Unsafe');");
+            fail("should have thrown SecurityException");
+        } catch (final Exception exp) {
+            if (exp instanceof SecurityException) {
+                log("got " + exp + " as expected");
+            } else {
+                fail(exp.getMessage());
+            }
+        }
+    }
+
+    @Test
+    public void securitySystemExit() {
+        if (System.getSecurityManager() == null) {
+            // pass vacuously
+        }
+
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("java.lang.System.exit(0);");
+            fail("should have thrown SecurityException");
+        } catch (final Exception exp) {
+            if (exp instanceof SecurityException) {
+                log("got " + exp + " as expected");
+            } else {
+                fail(exp.getMessage());
+            }
+        }
+    }
+
+    @Test
+    public void securitySystemLoadLibrary() {
+        if (System.getSecurityManager() == null) {
+            // pass vacuously
+        }
+
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("java.lang.System.loadLibrary('foo');");
+            fail("should have thrown SecurityException");
+        } catch (final Exception exp) {
+            if (exp instanceof SecurityException) {
+                log("got " + exp + " as expected");
+            } else {
+                fail(exp.getMessage());
+            }
+        }
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
new file mode 100644
index 0000000..f4fd114
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
@@ -0,0 +1,899 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.Invocable;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleScriptContext;
+import jdk.nashorn.internal.runtime.Version;
+import netscape.javascript.JSObject;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for JSR-223 script engine for Nashorn.
+ *
+ * @test
+ * @build jdk.nashorn.api.scripting.Window jdk.nashorn.api.scripting.WindowEventHandler jdk.nashorn.api.scripting.ScriptEngineTest
+ * @run testng jdk.nashorn.api.scripting.ScriptEngineTest
+ */
+public class ScriptEngineTest {
+
+    private void log(String msg) {
+        org.testng.Reporter.log(msg, true);
+    }
+
+    @Test
+    public void argumentsTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        String[] args = new String[] { "hello", "world" };
+        try {
+            e.put("arguments", args);
+            Object arg0 = e.eval("arguments[0]");
+            Object arg1 = e.eval("arguments[1]");
+            assertEquals(args[0], arg0);
+            assertEquals(args[1], arg1);
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void argumentsWithTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        String[] args = new String[] { "hello", "world" };
+        try {
+            e.put("arguments", args);
+            Object arg0 = e.eval("var imports = new JavaImporter(java.io); " +
+                    " with(imports) { arguments[0] }");
+            Object arg1 = e.eval("var imports = new JavaImporter(java.util, java.io); " +
+                    " with(imports) { arguments[1] }");
+            assertEquals(args[0], arg0);
+            assertEquals(args[1], arg1);
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void argumentsEmptyTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        try {
+            assertEquals(e.eval("arguments instanceof Array"), true);
+            assertEquals(e.eval("arguments.length == 0"), true);
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void factoryTests() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        assertNotNull(e);
+
+        final ScriptEngineFactory fac = e.getFactory();
+
+        assertEquals(fac.getLanguageName(), "ECMAScript");
+        assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript");
+        assertEquals(fac.getLanguageVersion(), "ECMA - 262 Edition 5.1");
+        assertEquals(fac.getEngineName(), "Oracle Nashorn");
+        assertEquals(fac.getEngineVersion(), Version.version());
+        assertEquals(fac.getOutputStatement("context"), "print(context)");
+        assertEquals(fac.getProgram("print('hello')", "print('world')"), "print('hello');print('world');");
+        assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript");
+
+        boolean seenJS = false;
+        for (String ext : fac.getExtensions()) {
+            if (ext.equals("js")) {
+                seenJS = true;
+            }
+        }
+
+        assertEquals(seenJS, true);
+        String str = fac.getMethodCallSyntax("obj", "foo", "x");
+        assertEquals(str, "obj.foo(x)");
+
+        boolean seenNashorn = false, seenJavaScript = false, seenECMAScript = false;
+        for (String name : fac.getNames()) {
+            switch (name) {
+                case "nashorn": seenNashorn = true; break;
+                case "javascript": seenJavaScript = true; break;
+                case "ECMAScript": seenECMAScript = true; break;
+            }
+        }
+
+        assertTrue(seenNashorn);
+        assertTrue(seenJavaScript);
+        assertTrue(seenECMAScript);
+
+        boolean seenAppJS = false, seenAppECMA = false, seenTextJS = false, seenTextECMA = false;
+        for (String mime : fac.getMimeTypes()) {
+            switch (mime) {
+                case "application/javascript": seenAppJS = true; break;
+                case "application/ecmascript": seenAppECMA = true; break;
+                case "text/javascript": seenTextJS = true; break;
+                case "text/ecmascript": seenTextECMA = true; break;
+            }
+        }
+
+        assertTrue(seenAppJS);
+        assertTrue(seenAppECMA);
+        assertTrue(seenTextJS);
+        assertTrue(seenTextECMA);
+    }
+
+    @Test
+    public void evalTests() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        e.put(ScriptEngine.FILENAME, "myfile.js");
+
+        try {
+            e.eval("print('hello')");
+        } catch (final ScriptException se) {
+            fail(se.getMessage());
+        }
+        try {
+            e.eval("print('hello)");
+            fail("script exception expected");
+        } catch (final ScriptException se) {
+            assertEquals(se.getLineNumber(), 1);
+            assertEquals(se.getColumnNumber(), 13);
+            assertEquals(se.getFileName(), "myfile.js");
+            // se.printStackTrace();
+        }
+
+        try {
+            Object obj = e.eval("34 + 41");
+            assertTrue(34.0 + 41.0 == ((Number)obj).doubleValue());
+            obj = e.eval("x = 5");
+            assertTrue(5.0 == ((Number)obj).doubleValue());
+        } catch (final ScriptException se) {
+            se.printStackTrace();
+            fail(se.getMessage());
+        }
+    }
+
+    @Test
+    public void compileTests() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        CompiledScript script = null;
+
+        try {
+            script = ((Compilable)e).compile("print('hello')");
+        } catch (final ScriptException se) {
+            fail(se.getMessage());
+        }
+
+        try {
+            script.eval();
+        } catch (final ScriptException | NullPointerException se) {
+            se.printStackTrace();
+            fail(se.getMessage());
+        }
+
+        // try to compile from a Reader
+        try {
+            script = ((Compilable)e).compile(new StringReader("print('world')"));
+        } catch (final ScriptException se) {
+            fail(se.getMessage());
+        }
+
+        try {
+            script.eval();
+        } catch (final ScriptException | NullPointerException se) {
+            se.printStackTrace();
+            fail(se.getMessage());
+        }
+    }
+
+    @Test
+    public void createBindingsTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        Bindings b = e.createBindings();
+        b.put("foo", 42.0);
+        Object res = null;
+        try {
+            res = e.eval("foo == 42.0", b);
+        } catch (final ScriptException | NullPointerException se) {
+            se.printStackTrace();
+            fail(se.getMessage());
+        }
+
+        assertEquals(res, Boolean.TRUE);
+    }
+
+    @Test
+    public void getInterfaceTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Invocable inv = (Invocable)e;
+
+        // try to get interface from global functions
+        try {
+            e.eval("function run() { print('run'); };");
+            final Runnable runnable = inv.getInterface(Runnable.class);
+            runnable.run();
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+
+        // try interface on specific script object
+        try {
+            e.eval("var obj = { run: function() { print('run from obj'); } };");
+            Object obj = e.get("obj");
+            final Runnable runnable = inv.getInterface(obj, Runnable.class);
+            runnable.run();
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void accessGlobalTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        try {
+            e.eval("var x = 'hello'");
+            assertEquals(e.get("x"), "hello");
+        } catch (final ScriptException exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void exposeGlobalTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        try {
+            e.put("y", "foo");
+            e.eval("print(y)");
+        } catch (final ScriptException exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    public static void alert(final Object msg) {
+        System.out.println(msg);
+    }
+
+    @Test
+    public void exposeMethodTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        try {
+            final Method alert = ScriptEngineTest.class.getMethod("alert", Object.class);
+            // expose a Method object as global var.
+            e.put("alert", alert);
+            // call the global var.
+            e.eval("alert.invoke(null, 'alert! alert!!')");
+        } catch (final NoSuchMethodException | SecurityException | ScriptException exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void putGlobalFunctionTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        e.put("callable", new Callable<String>() {
+            @Override
+            public String call() throws Exception {
+                return "callable was called";
+            }
+        });
+
+        try {
+            e.eval("print(callable.call())");
+        } catch (final ScriptException exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void windowAlertTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Window window = new Window();
+
+        try {
+            e.put("window", window);
+            e.eval("print(window.alert)");
+            e.eval("window.alert('calling window.alert...')");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void windowLocationTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Window window = new Window();
+
+        try {
+            e.put("window", window);
+            e.eval("print(window.location)");
+            final Object locationValue = e.eval("window.getLocation()");
+            assertEquals(locationValue, "http://localhost:8080/window");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void windowItemTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Window window = new Window();
+
+        try {
+            e.put("window", window);
+            final String item1 = (String)e.eval("window.item(65535)");
+            assertEquals(item1, "ffff");
+            final String item2 = (String)e.eval("window.item(255)");
+            assertEquals(item2, "ff");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void windowEventTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Window window = new Window();
+
+        try {
+            e.put("window", window);
+            e.eval("window.onload = function() { print('window load event fired'); return true }");
+            assertTrue((Boolean)e.eval("window.onload.loaded()"));
+            final WindowEventHandler handler = window.getOnload();
+            assertNotNull(handler);
+            assertTrue(handler.loaded());
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void throwTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        e.put(ScriptEngine.FILENAME, "throwtest.js");
+
+        try {
+            e.eval("throw 'foo'");
+        } catch (final ScriptException exp) {
+            log(exp.getMessage());
+            assertEquals(exp.getMessage(), "foo in throwtest.js at line number 1 at column number 0");
+            assertEquals(exp.getFileName(), "throwtest.js");
+            assertEquals(exp.getLineNumber(), 1);
+        }
+    }
+
+    @Test
+    public void setTimeoutTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Window window = new Window();
+
+        try {
+            final Class<?> setTimeoutParamTypes[] = { Window.class, String.class, int.class };
+            final Method setTimeout = Window.class.getDeclaredMethod("setTimeout", setTimeoutParamTypes);
+            assertNotNull(setTimeout);
+            e.put("window", window);
+            e.eval("window.setTimeout('foo()', 100)");
+
+            // try to make setTimeout global
+            e.put("setTimeout", setTimeout);
+            // TODO: java.lang.ClassCastException: required class
+            // java.lang.Integer but encountered class java.lang.Double
+            // e.eval("setTimeout('foo2()', 200)");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void setWriterTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final StringWriter sw = new StringWriter();
+        e.getContext().setWriter(sw);
+
+        try {
+            e.eval("print('hello world')");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+        // dos2unix - fix line endings if running on windows
+        assertEquals(sw.toString().replaceAll("\r", ""), "hello world\n");
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void reflectionTest() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        e.eval("var obj = { x: 344, y: 'nashorn' }");
+
+        int count = 0;
+        Map<Object, Object> map = (Map<Object, Object>)e.get("obj");
+        assertFalse(map.isEmpty());
+        assertTrue(map.keySet().contains("x"));
+        assertTrue(map.containsKey("x"));
+        assertTrue(map.values().contains("nashorn"));
+        assertTrue(map.containsValue("nashorn"));
+        for (final Map.Entry<?, ?> ex : map.entrySet()) {
+            final Object key = ex.getKey();
+            if (key.equals("x")) {
+                assertTrue(344 == ((Number)ex.getValue()).doubleValue());
+                count++;
+            } else if (key.equals("y")) {
+                assertEquals(ex.getValue(), "nashorn");
+                count++;
+            }
+        }
+        assertEquals(2, count);
+        assertEquals(2, map.size());
+
+        // add property
+        map.put("z", "hello");
+        assertEquals(e.eval("obj.z"), "hello");
+        assertEquals(map.get("z"), "hello");
+        assertTrue(map.keySet().contains("z"));
+        assertTrue(map.containsKey("z"));
+        assertTrue(map.values().contains("hello"));
+        assertTrue(map.containsValue("hello"));
+        assertEquals(map.size(), 3);
+
+        final Map<Object, Object> newMap = new HashMap<>();
+        newMap.put("foo", 23.0);
+        newMap.put("bar", true);
+        map.putAll(newMap);
+
+        assertEquals(e.eval("obj.foo"), 23.0);
+        assertEquals(e.eval("obj.bar"), true);
+
+        // remove using map method
+        map.remove("foo");
+        assertEquals(e.eval("typeof obj.foo"), "undefined");
+
+        count = 0;
+        e.eval("var arr = [ true, 'hello' ]");
+        map = (Map<Object, Object>)e.get("arr");
+        assertFalse(map.isEmpty());
+        assertTrue(map.containsKey("length"));
+        assertTrue(map.containsValue("hello"));
+        for (final Map.Entry<?, ?> ex : map.entrySet()) {
+            final Object key = ex.getKey();
+            if (key.equals("0")) {
+                assertEquals(ex.getValue(), Boolean.TRUE);
+                count++;
+            } else if (key.equals("1")) {
+                assertEquals(ex.getValue(), "hello");
+                count++;
+            }
+        }
+        assertEquals(count, 2);
+        assertEquals(map.size(), 2);
+
+        // add element
+        map.put("2", "world");
+        assertEquals(map.get("2"), "world");
+        assertEquals(map.size(), 3);
+
+        // remove all
+        map.clear();
+        assertTrue(map.isEmpty());
+        assertEquals(e.eval("typeof arr[0]"), "undefined");
+        assertEquals(e.eval("typeof arr[1]"), "undefined");
+        assertEquals(e.eval("typeof arr[2]"), "undefined");
+    }
+
+    @Test
+    public void redefineEchoTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        try {
+            e.eval("var echo = {}; if (typeof echo !== 'object') { throw 'echo is a '+typeof echo; }");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void invokeMethodTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        try {
+            e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();");
+            final Object obj = e.get("myExample");
+            final Object res = ((Invocable)e).invokeMethod(obj, "hello");
+            assertEquals(res, "Hello World!");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void versionTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        assertEquals(e.getFactory().getEngineVersion(), Version.version());
+    }
+
+    @Test
+    public void noEnumerablePropertiesTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("for (i in this) { throw 'found property: ' + i }");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void noRefErrorForGlobalThisAccessTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("this.foo");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void refErrorForUndeclaredAccessTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("try { print(foo); throw 'no ref error' } catch (e) { if (!(e instanceof ReferenceError)) throw e; }");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void typeErrorForGlobalThisCallTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("try { this.foo() } catch(e) { if (! (e instanceof TypeError)) throw 'no type error' }");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void refErrorForUndeclaredCallTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("try { foo() } catch(e) { if (! (e instanceof ReferenceError)) throw 'no ref error' }");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void jsobjectTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }");
+            JSObject obj = (JSObject) e.get("obj");
+
+            // try basic get on existing properties
+            if (! obj.getMember("bar").equals("hello")) {
+                fail("obj.bar != 'hello'");
+            }
+
+            if (! obj.getSlot(1).equals("world")) {
+                fail("obj[1] != 'world'");
+            }
+
+            if (! obj.call("func", new Object[0]).equals("hello")) {
+                fail("obj.call('func') != 'hello'");
+            }
+
+            // try setting properties
+            obj.setMember("bar", "new-bar");
+            obj.setSlot(1, "new-element-1");
+            if (! obj.getMember("bar").equals("new-bar")) {
+                fail("obj.bar != 'new-bar'");
+            }
+
+            if (! obj.getSlot(1).equals("new-element-1")) {
+                fail("obj[1] != 'new-element-1'");
+            }
+
+            // try adding properties
+            obj.setMember("prop", "prop-value");
+            obj.setSlot(12, "element-12");
+            if (! obj.getMember("prop").equals("prop-value")) {
+                fail("obj.prop != 'prop-value'");
+            }
+
+            if (! obj.getSlot(12).equals("element-12")) {
+                fail("obj[12] != 'element-12'");
+            }
+
+            // delete properties
+            obj.removeMember("prop");
+            if ("prop-value".equals(obj.getMember("prop"))) {
+                fail("obj.prop is not deleted!");
+            }
+
+            // Simple eval tests
+            assertEquals(obj.eval("typeof Object"), "function");
+            assertEquals(obj.eval("'nashorn'.substring(3)"), "horn");
+        } catch (final Exception exp) {
+            exp.printStackTrace();
+            fail(exp.getMessage());
+        }
+    }
+
+    @Test
+    public void invokeFunctionExceptionTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("function func() { throw new TypeError(); }");
+        } catch (final Throwable t) {
+            t.printStackTrace();
+            fail(t.getMessage());
+        }
+
+        try {
+            ((Invocable)e).invokeFunction("func");
+            fail("should have thrown exception");
+        } catch (final ScriptException se) {
+            // ECMA TypeError property wrapped as a ScriptException
+            log("got " + se + " as expected");
+        } catch (final Throwable t) {
+            t.printStackTrace();
+            fail(t.getMessage());
+        }
+    }
+
+    @Test
+    public void invokeMethodExceptionTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }");
+        } catch (final Throwable t) {
+            t.printStackTrace();
+            fail(t.getMessage());
+        }
+
+        try {
+            final Object sobj = e.get("sobj");
+            ((Invocable)e).invokeMethod(sobj, "foo");
+            fail("should have thrown exception");
+        } catch (final ScriptException se) {
+            // ECMA TypeError property wrapped as a ScriptException
+            log("got " + se + " as expected");
+        } catch (final Throwable t) {
+            t.printStackTrace();
+            fail(t.getMessage());
+        }
+    }
+
+    @Test
+    public void scriptObjectMirrorToStringTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        try {
+            Object obj = e.eval("new TypeError('wrong type')");
+            assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value");
+        } catch (final Throwable t) {
+            t.printStackTrace();
+            fail(t.getMessage());
+        }
+
+        try {
+            Object obj = e.eval("function func() { print('hello'); }");
+            assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value");
+        } catch (final Throwable t) {
+            t.printStackTrace();
+            fail(t.getMessage());
+        }
+    }
+
+    @Test
+    public void engineScopeTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE);
+
+        // check few ECMA standard built-in global properties
+        assertNotNull(engineScope.get("Object"));
+        assertNotNull(engineScope.get("TypeError"));
+        assertNotNull(engineScope.get("eval"));
+
+        // can access via ScriptEngine.get as well
+        assertNotNull(e.get("Object"));
+        assertNotNull(e.get("TypeError"));
+        assertNotNull(e.get("eval"));
+
+        // Access by either way should return same object
+        assertEquals(engineScope.get("Array"), e.get("Array"));
+        assertEquals(engineScope.get("EvalError"), e.get("EvalError"));
+        assertEquals(engineScope.get("undefined"), e.get("undefined"));
+
+        // try exposing a new variable from scope
+        engineScope.put("myVar", "foo");
+        try {
+            assertEquals(e.eval("myVar"), "foo");
+        } catch (final ScriptException se) {
+            se.printStackTrace();
+            fail(se.getMessage());
+        }
+
+        // update "myVar" in script an check the value from scope
+        try {
+            e.eval("myVar = 'nashorn';");
+        } catch (final ScriptException se) {
+            se.printStackTrace();
+            fail(se.getMessage());
+        }
+
+        // now check modified value from scope and engine
+        assertEquals(engineScope.get("myVar"), "nashorn");
+        assertEquals(e.get("myVar"), "nashorn");
+    }
+
+    @Test
+    public void multiGlobalTest() {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+        try {
+            Object obj1 = e.eval("Object");
+            Object obj2 = e.eval("Object", newCtxt);
+            Assert.assertNotEquals(obj1, obj2);
+            Assert.assertNotNull(obj1);
+            Assert.assertNotNull(obj2);
+            Assert.assertEquals(obj1.toString(), obj2.toString());
+
+            e.eval("x = 'hello'");
+            e.eval("x = 'world'", newCtxt);
+            Object x1 = e.getContext().getAttribute("x");
+            Object x2 = newCtxt.getAttribute("x");
+            Assert.assertNotEquals(x1, x2);
+            Assert.assertEquals(x1, "hello");
+            Assert.assertEquals(x2, "world");
+
+            x1 = e.eval("x");
+            x2 = e.eval("x", newCtxt);
+            Assert.assertNotEquals(x1, x2);
+            Assert.assertEquals(x1, "hello");
+            Assert.assertEquals(x2, "world");
+
+            final ScriptContext origCtxt = e.getContext();
+            e.setContext(newCtxt);
+            e.eval("y = new Object()");
+            e.eval("y = new Object()", origCtxt);
+
+            Object y1 = origCtxt.getAttribute("y");
+            Object y2 = newCtxt.getAttribute("y");
+            Assert.assertNotEquals(y1, y2);
+            Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt));
+            Assert.assertEquals("[object Object]", y1.toString());
+            Assert.assertEquals("[object Object]", y2.toString());
+        } catch (final ScriptException se) {
+            se.printStackTrace();
+            fail(se.getMessage());
+        }
+    }
+
+    @Test
+    public void factoryOptionsTest() {
+        final ScriptEngineManager sm = new ScriptEngineManager();
+        for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+            if (fac instanceof NashornScriptEngineFactory) {
+                final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+                // specify --no-syntax-extensions flag
+                final String[] options = new String[] { "--no-syntax-extensions" };
+                final ScriptEngine e = nfac.getScriptEngine(options);
+                try {
+                    // try nashorn specific extension
+                    e.eval("var f = funtion(x) 2*x;");
+                    fail("should have thrown exception!");
+                } catch (final ScriptException se) {
+                }
+                return;
+            }
+        }
+
+        fail("Cannot find nashorn factory!");
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/Window.java b/nashorn/test/src/jdk/nashorn/api/scripting/Window.java
new file mode 100644
index 0000000..bde2394
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/Window.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+public class Window {
+
+    private String location = "http://localhost:8080/window";
+
+    private WindowEventHandler onload   = null;
+
+    public void alert(final String message) {
+        System.out.println("alert: " + message);
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    public void setLocation(final String location) {
+        this.location = location;
+    }
+
+    public String item(final int index) {
+        return Integer.toHexString(index);
+    }
+
+    public WindowEventHandler getOnload() {
+        return onload;
+    }
+
+    public void setOnload(final WindowEventHandler onload) {
+        this.onload = onload;
+    }
+
+    public static int setTimeout(final Window self, final String code, final int delay) {
+        return self.setTimeout(code, delay);
+    }
+
+    public int setTimeout(final String code, final int delay) {
+        System.out.println("window.setTimeout: " + delay + ", code: " + code);
+        return 0;
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/WindowEventHandler.java b/nashorn/test/src/jdk/nashorn/api/scripting/WindowEventHandler.java
new file mode 100644
index 0000000..8889299
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/WindowEventHandler.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting;
+
+public interface WindowEventHandler {
+
+    public boolean loaded();
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java
new file mode 100644
index 0000000..adf361f
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java
@@ -0,0 +1,185 @@
+/*
+ * 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.codegen;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.options.Options;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests to check Nashorn JS compiler - just compiler and not execution of scripts.
+ */
+public class CompilerTest {
+    private static final boolean VERBOSE  = Boolean.valueOf(System.getProperty("compilertest.verbose"));
+    private static final boolean TEST262  = Boolean.valueOf(System.getProperty("compilertest.test262"));
+    private static final String TEST_BASIC_DIR  = System.getProperty("test.basic.dir");
+    private static final String TEST262_SUITE_DIR = System.getProperty("test262.suite.dir");
+
+    interface TestFilter {
+        public boolean exclude(File file, String content);
+    }
+
+    private void log(String msg) {
+        org.testng.Reporter.log(msg, true);
+    }
+
+    private Context context;
+    private ScriptObject global;
+
+    public CompilerTest() {
+        final Options options = new Options("nashorn");
+        options.set("anon.functions", true);
+        options.set("compile.only", true);
+        options.set("print.ast", true);
+        options.set("print.parse", true);
+        options.set("scripting", true);
+
+        final ErrorManager errors = new ErrorManager() {
+            @Override
+            public void error(final String msg) {
+                log(msg);
+            }
+        };
+
+        final StringWriter sw = new StringWriter();
+        final PrintWriter pw = new PrintWriter(sw);
+        this.context = new Context(options, errors, pw, pw, Thread.currentThread().getContextClassLoader());
+        this.global = context.createGlobal();
+    }
+
+    @Test
+    public void compileAllTests() {
+        if (TEST262) {
+            compileTestSet(TEST262_SUITE_DIR, new TestFilter() {
+                @Override
+                public boolean exclude(final File file, final String content) {
+                    return content.indexOf("@negative") != -1;
+                }
+            });
+        }
+        compileTestSet(TEST_BASIC_DIR, null);
+    }
+
+    private void compileTestSet(final String testSet, final TestFilter filter) {
+        passed = 0;
+        failed = 0;
+        skipped = 0;
+        final File testSetDir = new File(testSet);
+        if (! testSetDir.isDirectory()) {
+            log("WARNING: " + testSetDir + " not found or not a directory");
+            return;
+        }
+        log(testSetDir.getAbsolutePath());
+        compileJSDirectory(testSetDir, filter);
+
+        log(testSet + " compile done!");
+        log("compile ok: " + passed);
+        log("compile failed: " + failed);
+        log("compile skipped: " + skipped);
+        if (failed != 0) {
+            Assert.fail(failed + " tests failed to compile in " + testSetDir.getAbsolutePath());
+        }
+    }
+
+    // number of scripts that compiled fine
+    private int passed;
+    // number of scripts resulting in compile failure
+    private int failed;
+    // scripts that were skipped - all tests with @negative are
+    // skipped for now.
+    private int skipped;
+
+    private void compileJSDirectory(final File dir, final TestFilter filter) {
+        for (final File f : dir.listFiles()) {
+            if (f.isDirectory()) {
+                compileJSDirectory(f, filter);
+            } else if (f.getName().endsWith(".js")) {
+                compileJSFile(f, filter);
+            }
+        }
+    }
+
+    private void compileJSFile(final File file, final TestFilter filter) {
+        if (VERBOSE) {
+            log("Begin compiling " + file.getAbsolutePath());
+        }
+
+        final ScriptObject oldGlobal = Context.getGlobal();
+        final boolean globalChanged = (oldGlobal != global);
+
+        try {
+            final char[] buffer = Source.readFully(file);
+            boolean excluded = false;
+
+            if (filter != null) {
+                final String content = new String(buffer);
+                excluded = filter.exclude(file, content);
+            }
+
+            if (excluded) {
+                if (VERBOSE) {
+                    log("Skipping " + file.getAbsolutePath());
+                }
+                skipped++;
+                return;
+            }
+
+            if (globalChanged) {
+                Context.setGlobal(global);
+            }
+            final Source source = new Source(file.getAbsolutePath(), buffer);
+            final ScriptFunction script = context.compileScript(source, global);
+            if (script == null || context.getErrorManager().getNumberOfErrors() > 0) {
+                log("Compile failed: " + file.getAbsolutePath());
+                failed++;
+            } else {
+                passed++;
+            }
+        } catch (final Throwable t) {
+            log("Compile failed: " + file.getAbsolutePath() + " : " + t);
+            if (VERBOSE) {
+                t.printStackTrace(System.out);
+            }
+            failed++;
+        } finally {
+            if (globalChanged) {
+                Context.setGlobal(oldGlobal);
+            }
+        }
+
+        if (VERBOSE) {
+            log("Done compiling " + file.getAbsolutePath());
+        }
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java b/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java
new file mode 100644
index 0000000..afffe05
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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.parser;
+
+import java.io.File;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.options.Options;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Run tests to check Nashorn's parser.
+ */
+public class ParserTest {
+    private static final boolean VERBOSE   = Boolean.valueOf(System.getProperty("parsertest.verbose"));
+    private static final boolean TEST262   = Boolean.valueOf(System.getProperty("parsertest.test262"));
+
+    private static final String TEST_BASIC_DIR  = System.getProperty("test.basic.dir");
+    private static final String TEST262_SUITE_DIR = System.getProperty("test262.suite.dir");
+
+
+    interface TestFilter {
+        public boolean exclude(File file, String content);
+    }
+
+    private void log(String msg) {
+        org.testng.Reporter.log(msg, true);
+    }
+
+    private Context context;
+    private ScriptObject global;
+
+    public ParserTest() {
+        final Options options = new Options("nashorn");
+        options.set("anon.functions", true);
+        options.set("parse.only", true);
+        options.set("scripting", true);
+
+        ErrorManager errors = new ErrorManager();
+        this.context = new Context(options, errors, Thread.currentThread().getContextClassLoader());
+        this.global = context.createGlobal();
+    }
+
+    @Test
+    public void parseAllTests() {
+        if (TEST262) {
+            parseTestSet(TEST262_SUITE_DIR, new TestFilter() {
+                @Override
+                public boolean exclude(final File file, final String content) {
+                    return content.indexOf("@negative") != -1;
+                }
+            });
+        }
+        parseTestSet(TEST_BASIC_DIR, null);
+    }
+
+    private void parseTestSet(final String testSet, final TestFilter filter) {
+        passed  = 0;
+        failed  = 0;
+        skipped = 0;
+
+        final File testSetDir = new File(testSet);
+        if (! testSetDir.isDirectory()) {
+            log("WARNING: " + testSetDir + " not found or not a directory");
+            return;
+        }
+        log(testSetDir.getAbsolutePath());
+        parseJSDirectory(testSetDir, filter);
+
+        log(testSet + " parse done!");
+        log("parse ok: " + passed);
+        log("parse failed: " + failed);
+        log("parse skipped: " + skipped);
+        if (failed != 0) {
+            Assert.fail(failed + " tests failed to compile in " + testSetDir.getAbsolutePath());
+        }
+    }
+
+    // number of scripts that parsed fine
+    private int passed;
+    // number of scripts resulting in parse failure
+    private int failed;
+    // scripts that were skipped - all tests with @negative are
+    // skipped for now.
+    private int skipped;
+
+    private void parseJSDirectory(final File dir, final TestFilter filter) {
+        for (final File f : dir.listFiles()) {
+            if (f.isDirectory()) {
+                parseJSDirectory(f, filter);
+            } else if (f.getName().endsWith(".js")) {
+                parseJSFile(f, filter);
+            }
+        }
+    }
+
+    private void parseJSFile(final File file, final TestFilter filter) {
+        if (VERBOSE) {
+            log("Begin parsing " + file.getAbsolutePath());
+        }
+
+        final ScriptObject oldGlobal = Context.getGlobal();
+        final boolean globalChanged = (oldGlobal != global);
+        try {
+            final char[] buffer = Source.readFully(file);
+            boolean excluded = false;
+            if (filter != null) {
+                final String content = new String(buffer);
+                excluded = filter.exclude(file, content);
+            }
+
+            if (excluded) {
+                if (VERBOSE) {
+                    log("Skipping " + file.getAbsolutePath());
+                }
+                skipped++;
+                return;
+            }
+
+            final ErrorManager errors = new ErrorManager() {
+                @Override
+                public void error(final String msg) {
+                    log(msg);
+                }
+            };
+            errors.setLimit(0);
+            if (globalChanged) {
+                Context.setGlobal(global);
+            }
+            final Source   source   = new Source(file.getAbsolutePath(), buffer);
+            new Parser(context.getEnv(), source, errors).parse();
+            if (errors.getNumberOfErrors() > 0) {
+                log("Parse failed: " + file.getAbsolutePath());
+                failed++;
+            } else {
+                passed++;
+            }
+        } catch (final Throwable exp) {
+            log("Parse failed: " + file.getAbsolutePath() + " : " + exp);
+            if (VERBOSE) {
+                exp.printStackTrace(System.out);
+            }
+            failed++;
+        } finally {
+            if (globalChanged) {
+                Context.setGlobal(oldGlobal);
+            }
+        }
+
+        if (VERBOSE) {
+            log("Done parsing " + file.getAbsolutePath());
+        }
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/performance/AuroraWrapper.java b/nashorn/test/src/jdk/nashorn/internal/performance/AuroraWrapper.java
new file mode 100644
index 0000000..a3f4caa
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/performance/AuroraWrapper.java
@@ -0,0 +1,214 @@
+/*
+ * 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.performance;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+public class AuroraWrapper {
+
+    public static String fileName = "report.xml";
+
+    public static void deleteReportDocument() {
+        final File f = new File(fileName);
+        if (f.exists()) {
+            f.delete();
+        }
+    }
+
+    public static Document createOrOpenDocument() throws ParserConfigurationException, SAXException, IOException {
+        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        final DocumentBuilder documentBuilder = factory.newDocumentBuilder();
+
+        Document document;
+        final File f = new File(fileName);
+        if (!f.exists()) {
+            document = documentBuilder.newDocument();
+            final Element root = document.createElement("entity");
+            document.appendChild(root);
+            root.setAttribute("type", "REFWORKLOADRUN");
+            root.setAttribute("name", "default");
+        } else {
+            document = documentBuilder.parse(f);
+        }
+
+        return document;
+    }
+
+    public static void addBenchmarkResults(final Document doc, final Element root, final String name, final String score, final String higherBetter) {
+        final Element results = addEntity(doc, root, name, "BENCHMARK_RESULTS");
+        addAttribute(doc, results, "benchmark", name);
+        addAttribute(doc, results, "is_higher_better", higherBetter);
+
+        final Element iteration = addEntity(doc, results, "1", "ITERATION");
+        addAttribute(doc, iteration, "score", score);
+        addAttribute(doc, iteration, "successful", "true");
+
+        addConfig(doc, results, name);
+    }
+
+    public static Element getRootEntity(final org.w3c.dom.Document doc) {
+        final Element rootEntity = doc.getDocumentElement();
+        Element resultsEntity = null;
+
+        final NodeList entities = rootEntity.getChildNodes();
+        for (int i = 0; i < entities.getLength(); i++) {
+            if (entities.item(i).getNodeName().equals("entity")) {
+                resultsEntity = (Element)entities.item(i);
+                break;
+            }
+        }
+
+        if (resultsEntity == null) {
+            resultsEntity = addResults(doc);
+        }
+        //System.out.println(resultsEntity);
+        return resultsEntity;
+    }
+
+    public static void addAttribute(final Document doc, final Element entity, final String attributeName, final String attributeValue) {
+        final Element attr = doc.createElement("attribute");
+        entity.appendChild(attr);
+        attr.setAttribute("name", attributeName);
+        attr.setTextContent(attributeValue);
+    }
+
+    public static Element addEntity(final Document doc, final Element entity, final String entityName, final String entityType) {
+        final Element newEntity = doc.createElement("entity");
+        entity.appendChild(newEntity);
+
+        if (entityType != null) {
+            newEntity.setAttribute("type", entityType);
+        }
+        if (entityName != null) {
+            newEntity.setAttribute("name", entityName);
+        }
+        return newEntity;
+    }
+
+    public static Element addResults(final Document doc) {
+
+        String _benchmark = "nashorn-octaneperf";
+
+        final String vmName = java.lang.System.getProperties().getProperty("java.vm.name");
+        try {
+            String vmType;
+            if (vmName.toLowerCase().contains("client")) {
+                vmType = "client";
+            } else {
+                vmType = "server";
+            }
+            _benchmark += "-" + vmType;
+        } catch (final Exception e) {
+            // In case VM name has different format
+        }
+
+        final Element root = doc.getDocumentElement();
+
+        final Element result = doc.createElement("entity");
+
+        root.appendChild(result);
+        result.setAttribute("name", _benchmark);
+        result.setAttribute("type", "BENCHMARK_RESULTS");
+
+        addAttribute(doc, result, "benchmark", _benchmark);
+        addAttribute(doc, result, "score", "0");
+        addAttribute(doc, result, "mean", "0");
+        addAttribute(doc, result, "stdev", "0");
+        addAttribute(doc, result, "var", "0");
+        addAttribute(doc, result, "attempts", "1");
+        addAttribute(doc, result, "successes", "1");
+        addAttribute(doc, result, "failures", "0");
+        addAttribute(doc, result, "jvmOptions", "");
+        addAttribute(doc, result, "is_workload", "0");
+        addAttribute(doc, result, "is_higher_better", "1");
+
+        addConfig(doc, result, _benchmark);
+
+        final Element iteration = addEntity(doc, result, "1", "ITERATION");
+        addAttribute(doc, iteration, "score", "0");
+        addAttribute(doc, iteration, "successful", "true");
+
+        return result;
+    }
+
+    public static void addConfig(final Document doc, final Element result, final String _benchmark) {
+        final Element config = addEntity(doc, result, "default", "BENCHMARK_CONFIG");
+        addAttribute(doc, config, "settings", "benchmarks=" + _benchmark + "\ncomponent=j2se\niterations=1\n");
+        addAttribute(doc, config, "info", "");
+    }
+
+    public static void addResults(final Document doc, final String _benchmark, final String _score) throws TransformerConfigurationException, TransformerException, IOException {
+        final Element result = getRootEntity(doc);
+
+        addBenchmarkResults(doc, result, _benchmark, _score, "1");
+
+        final TransformerFactory tranformerFactory = TransformerFactory.newInstance();
+        final Transformer tr = tranformerFactory.newTransformer();
+        tr.setOutputProperty(OutputKeys.INDENT, "yes");
+        try (FileOutputStream fos = new FileOutputStream(fileName)) {
+            tr.transform(new DOMSource(doc), new StreamResult(fos));
+        }
+    }
+
+    /**
+     * Test
+     */
+    @SuppressWarnings("UseSpecificCatch")
+    public static void main(final String... args) {
+        try {
+            deleteReportDocument();
+            Document document = createOrOpenDocument();
+            addResults(document, "benchmark1", "0.01");
+            document = createOrOpenDocument();
+            addResults(document, "benchmark2", "0.02");
+            document = createOrOpenDocument();
+            addResults(document, "benchmark3", "0.03");
+
+            final TransformerFactory tranformerFactory = TransformerFactory.newInstance();
+            final Transformer tr = tranformerFactory.newTransformer();
+            tr.setOutputProperty(OutputKeys.INDENT, "yes");
+            tr.transform(new DOMSource(document), new StreamResult(System.out));
+        } catch (final Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/performance/OctaneTest.java b/nashorn/test/src/jdk/nashorn/internal/performance/OctaneTest.java
new file mode 100644
index 0000000..7e402c6
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/performance/OctaneTest.java
@@ -0,0 +1,307 @@
+/*
+ * 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.performance;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.text.NumberFormat;
+import java.util.List;
+import org.testng.annotations.Test;
+
+public class OctaneTest {
+
+    @Test
+    public void box2DTest() {
+        genericTest("Box2D");
+    }
+
+    @Test
+    public void codeLoadTest() {
+        genericTest("Code-Load");
+    }
+
+    @Test
+    public void cryptoTest() {
+        genericTest("Crypto");
+    }
+
+    @Test
+    public void deltaBlueTest() {
+        genericTest("DeltaBlue");
+    }
+
+    @Test
+    public void earleyBoyerTest() {
+    genericTest("Earley-Boyer");
+    }
+
+    @Test
+    public void gbEMUTest() {
+        genericTest("GBEMU");
+    }
+
+    /*    @Test
+    public void mandreelTest() {
+        genericTest("Mandreel");
+    }*/
+
+    @Test
+    public void navierStokesTest() {
+        genericTest("Navier-Stokes");
+    }
+
+    @Test
+    public void pdfJSTest() {
+        genericTest("PDFJS");
+    }
+
+    @Test
+    public void raytraceTest() {
+        genericTest("RayTrace");
+    }
+
+    @Test
+    public void regexpTest() {
+        genericTest("RegExp");
+    }
+
+    @Test
+    public void richardsTest() {
+        genericTest("Richards");
+    }
+
+    @Test
+    public void splayTest() {
+        genericTest("Splay");
+    }
+
+    public void genericTest(final String benchmark) {
+        try {
+            final String mainScript      = "test/script/basic/run-octane.js";
+            final String benchmarkScript = "test/script/external/octane/benchmarks/"+benchmark.toLowerCase() + ".js";
+            String[] args = {
+                "--",
+                benchmarkScript,
+                "--verbose"
+            };
+            final Double score = genericNashornTest(benchmark, mainScript, args);
+
+            Double rhinoScore = null;
+            if (checkRhinoPresence()) {
+                args[0]=mainScript; //rhino does not need this "--"
+                rhinoScore = genericRhinoTest(benchmark,  args, System.getProperty("rhino.jar"));
+            }
+
+            Double v8Score = null;
+            if (checkV8Presence()) {
+                v8Score = genericV8Test(benchmark, "test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/" + benchmark.toLowerCase() + ".js --verbose");
+            }
+
+            generateOutput(benchmark.toLowerCase(), score, rhinoScore, v8Score);
+
+        } catch (final Throwable e) {
+            e.printStackTrace();
+        }
+    }
+
+    public Double genericNashornTest(final String benchmark, final String testPath, String[] args) throws Throwable {
+        try {
+            final PerformanceWrapper wrapper = new PerformanceWrapper();
+
+            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            final PrintStream ps = new PrintStream(baos);
+
+            java.io.File test=new java.io.File(testPath);
+            File absoluteFile=test.getAbsoluteFile();
+            @SuppressWarnings("deprecation")
+            URL testURL=absoluteFile.toURL();
+
+            wrapper.runExecuteOnlyTest(testPath, 0, 0, testURL.toString(), ps, System.err, args);
+
+            final byte[] output = baos.toByteArray();
+            final List<String> result = outputToStrings(output);
+
+            Double _result = filterBenchmark(result, benchmark);
+
+            return _result;
+        } catch (final Throwable e) {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    public Double genericRhinoTest(final String benchmark, final String[] testPath, final String jarPath) throws Throwable {
+
+        final PrintStream systemOut = System.out;
+
+        try {
+            final ClassLoader loader = java.net.URLClassLoader.newInstance(new URL[] { new URL(jarPath) }, getClass().getClassLoader());
+            final Class<?> clazz = Class.forName("org.mozilla.javascript.tools.shell.Main", true, loader);
+
+            final Class<?>[] pars = { String[].class };
+            final Method mthd = clazz.getMethod("main", pars);
+
+            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            final PrintStream ps = new PrintStream(baos);
+
+            System.setOut(ps);
+            //final String[] realArgs = testPath.split(" ");//{ testPath };
+            mthd.invoke(null, ((Object)testPath));
+            System.setOut(systemOut);
+
+            final byte[] output = baos.toByteArray();
+            final List<String> result = outputToStrings(output);
+            return filterBenchmark(result, benchmark);
+
+        } catch (final Throwable e) {
+            System.setOut(systemOut);
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    public Double genericV8Test(final String benchmark, final String testPath) throws Throwable {
+
+        System.out.println("genericV8Test");
+        if (!checkV8Presence()) {
+            return null;
+        }
+        final String v8shell = System.getProperty("v8.shell.full.path");
+        final PrintStream systemOut = System.out;
+
+        try {
+
+            final Process process = Runtime.getRuntime().exec(v8shell + " " + testPath);
+            process.waitFor();
+            final InputStream processOut = process.getInputStream();
+            final BufferedInputStream bis = new BufferedInputStream(processOut);
+
+            final byte[] output = new byte[bis.available()];
+            bis.read(output, 0, bis.available());
+            final List<String> result = outputToStrings(output);
+            return filterBenchmark(result, benchmark);
+
+        } catch (final Throwable e) {
+            System.setOut(systemOut);
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    protected List<String> outputToStrings(final byte[] output) throws IOException {
+        final ByteArrayInputStream bais = new ByteArrayInputStream(output);
+        final InputStreamReader reader = new InputStreamReader(bais);
+        final BufferedReader bufReader = new BufferedReader(reader);
+        final List<String> list = new java.util.LinkedList<>();
+        while (bufReader.ready()) {
+            list.add(bufReader.readLine());
+        }
+        return list;
+    }
+
+    protected Double filterBenchmark(final List<String> output, final String benchmarkName) throws Exception {
+        Double currentScore = 0.;
+        for (final String s : output) {
+            //if (s.trim().startsWith(benchmarkName)) {
+            if (s.trim().startsWith("Score")) {
+                final String[] split = s.split(":");
+                if (split.length != 2) {
+                    for (final String outString : output) {
+                        System.out.println("outString (score format)"+outString);
+                    }
+                    throw new IllegalArgumentException("Invalid benchmark output format");
+                }
+
+                final NumberFormat nf = NumberFormat.getInstance();
+                final Number _newCurrentScore = nf.parse(split[1].trim());
+                final Double newCurrentScore = _newCurrentScore.doubleValue();
+                if (currentScore < newCurrentScore) {
+                    currentScore = newCurrentScore;
+                }
+            }
+        }
+//        System.out.println("filterBenchmark current score:"+currentScore);
+        return currentScore;
+    }
+
+    void generateOutput(final String benchmark, final Double nashorn, final Double rhino, final Double v8) throws Exception {
+        Double nashornToRhino = null;
+        Double nashornToV8 = null;
+        if (rhino != null && rhino != 0) {
+            nashornToRhino = nashorn.doubleValue() / rhino.doubleValue();
+        }
+        if (v8 != null && rhino != 0) {
+            nashornToV8 = nashorn.doubleValue() / v8.doubleValue();
+        }
+        String normalizedBenchmark=benchmark.replace("-", "");
+        System.out.println("benchmark-" + normalizedBenchmark + "-nashorn=" + nashorn);
+        AuroraWrapper.addResults(AuroraWrapper.createOrOpenDocument(), "benchmark-" + normalizedBenchmark + "-nashorn", nashorn.toString());
+
+        if (rhino != null) {
+            System.out.println("benchmark-" + normalizedBenchmark + "-rhino=" + rhino);
+            AuroraWrapper.addResults(AuroraWrapper.createOrOpenDocument(), "benchmark-" + normalizedBenchmark + "-rhino", rhino.toString());
+        }
+        if (v8 != null) {
+            AuroraWrapper.addResults(AuroraWrapper.createOrOpenDocument(), "benchmark-" + normalizedBenchmark + "-v8", v8.toString());
+        }
+        if (nashornToRhino != null) {
+            System.out.println("benchmark-" + normalizedBenchmark + "-nashorn-to-rhino=" + ((float)((int)(nashornToRhino * 100))) / 100);
+            AuroraWrapper.addResults(AuroraWrapper.createOrOpenDocument(), "benchmark-" + normalizedBenchmark + "-nashorn-to-rhino", "" + ((float)((int)(nashornToRhino * 100))) / 100);
+        }
+        if (nashornToV8 != null) {
+            System.out.println("benchmark-" + normalizedBenchmark + "-nashorn-to-v8=" + ((float)((int)(nashornToV8 * 100))) / 100);
+            AuroraWrapper.addResults(AuroraWrapper.createOrOpenDocument(), "benchmark-" + normalizedBenchmark + "-nashorn-to-v8", "" + ((float)((int)(nashornToV8 * 100))) / 100);
+        }
+    }
+
+    boolean checkRhinoPresence() {
+        final String rhinojar = System.getProperty("rhino.jar");
+        if (rhinojar != null) {
+            // System.out.println("Rhino jar found; performing comparison testing");
+            return true;
+        }
+        return false;
+    }
+
+    boolean checkV8Presence() {
+        final String v8shell = System.getProperty("v8.shell.full.path");
+        if (v8shell != null) {
+            // System.out.println("d8 found; performing comparison testing");
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java b/nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java
new file mode 100644
index 0000000..999f6fa
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java
@@ -0,0 +1,155 @@
+/*
+ * 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.performance;
+
+import java.io.OutputStream;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ *
+ * @author Pavel Stepanov
+ */
+public class PerformanceWrapper extends jdk.nashorn.tools.Shell {
+
+    int _numberOfIterations;
+    int _runsPerIteration;
+
+    protected void runCompileOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL) throws Throwable {
+        final String[] args = { name, "--compile-only=true", "-dump-on-error", "--", testURL };
+
+        final long[] times = new long[numberOfIterations + 1];
+        times[0] = System.nanoTime(); // Calendar.getInstance().getTimeInMillis();
+
+        for (int iteration = 1; iteration <= numberOfIterations; iteration++) {
+            for (int i = 0; i < runsPerIteration; i++) {
+                run(System.in, System.out, System.err, args);
+            }
+            times[iteration] = System.nanoTime();
+        }
+
+        for (int i = 0; i < numberOfIterations; i++) {
+            System.out.println("Iteration " + (i + 1) + " average time: " + ((times[i + 1] - times[i]) / (float)runsPerIteration) / 1000000.0 + " ms.");
+        }
+    }
+
+    protected void runExecuteOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL) throws Throwable {
+        runExecuteOnlyTest(name, numberOfIterations, runsPerIteration, testURL, System.out, System.err, new String[0]);
+    }
+
+    protected void runExecuteOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL, final OutputStream out, final OutputStream err) throws Throwable {
+        runExecuteOnlyTest(name, numberOfIterations, runsPerIteration, testURL, out, err, new String[0]);
+    }
+
+
+    protected void runExecuteOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL, final OutputStream out, final OutputStream err, String[] newargs) throws Throwable {
+        String[] args=new String[newargs.length+1];
+        System.arraycopy(newargs, 0, args, 1, newargs.length);
+        args[0]=name;
+
+//      for (String s: args)
+//          System.out.println(s);
+
+        _numberOfIterations = numberOfIterations;
+        _runsPerIteration = runsPerIteration;
+        run(System.in, out, err, args);
+//      System.out.println("overridableRun finished");
+    }
+
+    @Override
+    protected Object apply(final ScriptFunction target, final Object self) {
+        if (_runsPerIteration == 0 && _numberOfIterations == 0) {
+            final ScriptObject global = jdk.nashorn.internal.runtime.Context.getGlobal();
+            final ScriptFunction _target = target;
+            final Object _self = self;
+
+            class MyThread implements Callable<Object> {
+                @Override
+                public Object call() {
+                    Context.setGlobal(global);
+                    //just execute and return script is sufficient
+                    final Object scriptRuntimeApplyResult = ScriptRuntime.apply(_target, _self);
+                    return scriptRuntimeApplyResult;
+                }
+            }
+
+            final java.util.concurrent.ThreadPoolExecutor executor = new java.util.concurrent.ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, new java.util.concurrent.ArrayBlockingQueue<Runnable>(10));
+            final MyThread myThread = new MyThread();
+            // executor.execute(myThread);
+            Object result;
+            Future<?> futureResult = null;
+
+            try {
+                futureResult = executor.submit(myThread);
+                final String timeout = System.getProperty("timeout.value");
+                int tmout = 0;
+                if (timeout != null) {
+                    try {
+                        tmout = Integer.parseInt(timeout);
+                    } catch (final Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+                if (tmout != 0) {
+                    result = futureResult.get(10, TimeUnit.MINUTES);
+                } else {
+                    result = futureResult.get();
+                }
+            } catch (final InterruptedException | ExecutionException e) {
+                e.printStackTrace();
+                return null;
+            } catch (final TimeoutException e) {
+                System.out.println("timeout while script execution");
+                futureResult.cancel(true);
+                return null;
+            }
+
+            return result;
+        }
+
+        final long[] times = new long[_numberOfIterations + 1];
+        times[0] = System.nanoTime();
+        for (int iteration = 1; iteration <= _numberOfIterations; iteration++) {
+            for (int i = 0; i < _runsPerIteration; i++) {
+                // empty
+            }
+            times[iteration] = System.nanoTime();
+        }
+
+        for (int i = 0; i < _numberOfIterations; i++) {
+            System.out.println("Iteration " + (i + 1) + " average time: " + ((times[i + 1] - times[i]) / (float)_runsPerIteration) / 1000000.0 + " ms.");
+        }
+
+        return ScriptRuntime.apply(target, self);
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/performance/SplayTest.java b/nashorn/test/src/jdk/nashorn/internal/performance/SplayTest.java
new file mode 100644
index 0000000..e937a0f
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/performance/SplayTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.performance;
+
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Pavel Stepanov
+ */
+public class SplayTest {
+
+    @Test
+    public void test() {
+        try {
+            final PerformanceWrapper wrapper = new PerformanceWrapper();
+            System.out.println("run Compile Only test");
+            wrapper.runCompileOnlyTest("test/performance/perf.js", 20, 100, "file:test/performance/splay.js");
+            System.out.println("run Execute Only test");
+            wrapper.runExecuteOnlyTest("test/performance/perf.js", 20, 10, "file:test/performance/splay.js");
+        } catch (final Throwable e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java
new file mode 100644
index 0000000..16165ce
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Map;
+import jdk.nashorn.internal.runtime.options.Options;
+import org.testng.annotations.Test;
+
+/**
+ * Basic Context API tests.
+ *
+ * @test
+ * @run testng jdk.nashorn.internal.runtime.ContextTest
+ */
+public class ContextTest {
+    // basic context eval test
+    @Test
+    public void evalTest() {
+        final Options options = new Options("");
+        final ErrorManager errors = new ErrorManager();
+        final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
+        final ScriptObject oldGlobal = Context.getGlobal();
+        Context.setGlobal(cx.createGlobal());
+        try {
+            String code = "22 + 10";
+            assertTrue(32.0 == ((Number)(eval(cx, "<evalTest>", code))).doubleValue());
+
+            code = "obj = { js: 'nashorn' }; obj.js";
+            assertEquals(eval(cx, "<evalTest2>", code), "nashorn");
+        } finally {
+            Context.setGlobal(oldGlobal);
+        }
+    }
+
+    // basic check for JS reflection access - java.util.Map-like access on ScriptObject
+    @Test
+    public void reflectionTest() {
+        final Options options = new Options("");
+        final ErrorManager errors = new ErrorManager();
+        final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
+        final ScriptObject oldGlobal = Context.getGlobal();
+        Context.setGlobal(cx.createGlobal());
+
+        try {
+            final String code = "var obj = { x: 344, y: 42 }";
+            eval(cx, "<reflectionTest>", code);
+
+            final Object obj = cx.getGlobal().get("obj");
+
+            assertTrue(obj instanceof ScriptObject);
+
+            final ScriptObject sobj = (ScriptObject)obj;
+            int count = 0;
+            for (final Map.Entry<?, ?> ex : sobj.entrySet()) {
+                final Object key = ex.getKey();
+                if (key.equals("x")) {
+                    assertTrue(ex.getValue() instanceof Number);
+                    assertTrue(344.0 == ((Number)ex.getValue()).doubleValue());
+
+                    count++;
+                } else if (key.equals("y")) {
+                    assertTrue(ex.getValue() instanceof Number);
+                    assertTrue(42.0 == ((Number)ex.getValue()).doubleValue());
+
+                    count++;
+                }
+            }
+            assertEquals(count, 2);
+            assertEquals(sobj.size(), 2);
+
+            // add property
+            sobj.put("zee", "hello");
+            assertEquals(sobj.get("zee"), "hello");
+            assertEquals(sobj.size(), 3);
+
+        } finally {
+            Context.setGlobal(oldGlobal);
+        }
+    }
+
+    private Object eval(final Context cx, final String name, final String code) {
+        final Source source = new Source(name, code);
+        final ScriptObject global = Context.getGlobal();
+        final ScriptFunction func = cx.compileScript(source, global);
+        return func != null ? ScriptRuntime.apply(func, global) : null;
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/JSTypeTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/JSTypeTest.java
new file mode 100644
index 0000000..6cf18d0
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/JSTypeTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+
+/**
+ * Tests for JSType methods.
+ *
+ * @test
+ * @run testng jdk.nashorn.internal.runtime.JSTypeTest
+ */
+public class JSTypeTest {
+    /**
+     * Test of isPrimitive method, of class Runtime.
+     */
+    @Test
+    public void testIsPrimitive() {
+        assertTrue(JSType.isPrimitive(null));
+        assertTrue(JSType.isPrimitive(ScriptRuntime.UNDEFINED));
+        assertTrue(JSType.isPrimitive(Double.NaN));
+        assertTrue(JSType.isPrimitive(Double.NEGATIVE_INFINITY));
+        assertTrue(JSType.isPrimitive(Double.POSITIVE_INFINITY));
+        assertTrue(JSType.isPrimitive(0.0));
+        assertTrue(JSType.isPrimitive(3.14));
+        assertTrue(JSType.isPrimitive("hello"));
+        assertTrue(JSType.isPrimitive(""));
+        assertFalse(JSType.isPrimitive(new Object()));
+    }
+
+    /**
+     * Test of toBoolean method, of class Runtime.
+     */
+    @Test
+    public void testToBoolean() {
+        assertFalse(JSType.toBoolean(ScriptRuntime.UNDEFINED));
+        assertFalse(JSType.toBoolean(null));
+        assertFalse(JSType.toBoolean(Boolean.FALSE));
+        assertTrue(JSType.toBoolean(Boolean.TRUE));
+        assertFalse(JSType.toBoolean(-0.0));
+        assertFalse(JSType.toBoolean(0.0));
+        assertFalse(JSType.toBoolean(Double.NaN));
+        assertTrue(JSType.toBoolean(3.14));
+        assertFalse(JSType.toBoolean(""));
+        assertTrue(JSType.toBoolean("javascript"));
+        assertTrue(JSType.toBoolean(new Object()));
+    }
+
+    /**
+     * Test of toNumber method, of class Runtime.
+     */
+    @Test
+    public void testToNumber_Object() {
+        assertTrue(Double.isNaN(JSType.toNumber(ScriptRuntime.UNDEFINED)));
+        assertEquals(JSType.toNumber((Object)null), 0.0, 0.0);
+        assertEquals(JSType.toNumber(Boolean.TRUE), 1.0, 0.0);
+        assertEquals(JSType.toNumber(Boolean.FALSE), 0.0, 0.0);
+        assertEquals(JSType.toNumber(3.14), 3.14, 0.0);
+        // FIXME: add more assertions for specific String to number cases
+        // FIXME: add case for Object type (JSObject with getDefaultValue)
+    }
+
+    /**
+     * Test of toString method, of class Runtime.
+     */
+    @Test
+    public void testToString_Object() {
+        assertEquals(JSType.toString(ScriptRuntime.UNDEFINED), "undefined");
+        assertEquals(JSType.toString(null), "null");
+        assertEquals(JSType.toString(Boolean.TRUE), "true");
+        assertEquals(JSType.toString(Boolean.FALSE), "false");
+        assertEquals(JSType.toString(""), "");
+        assertEquals(JSType.toString("nashorn"), "nashorn");
+        assertEquals(JSType.toString(Double.NaN), "NaN");
+        assertEquals(JSType.toString(Double.POSITIVE_INFINITY), "Infinity");
+        assertEquals(JSType.toString(Double.NEGATIVE_INFINITY), "-Infinity");
+        assertEquals(JSType.toString(0.0), "0");
+        // FIXME: add more number-to-string test cases
+        // FIXME: add case for Object type (JSObject with getDefaultValue)
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/Nashorn401TestSubject.java b/nashorn/test/src/jdk/nashorn/internal/runtime/Nashorn401TestSubject.java
new file mode 100644
index 0000000..ed6475d
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/Nashorn401TestSubject.java
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+public class Nashorn401TestSubject {
+    public String method2(int arg) {
+        return "int method 2";
+    }
+
+    public String method2(double arg) {
+        return "double method 2";
+    }
+
+    public String method2(String arg) {
+        return "string method 2";
+    }
+
+    public String method3(double arg) {
+        return "double method 3: " + arg;
+    }
+
+    public String method3(int arg) {
+        return "int method 3: " + arg;
+    }
+
+    public String method4(Double arg) {
+        return "double method 4: " + arg;
+    }
+
+    public String method4(int arg) {
+        return "int method 4: " + arg;
+    }
+
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java
new file mode 100644
index 0000000..0f14756
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for trusted client usage of nashorn script engine factory extension API
+ */
+public class TrustedScriptEngineTest {
+    private static class MyClassLoader extends ClassLoader {
+        // to check if script engine uses the specified class loader
+        private final boolean[] reached = new boolean[1];
+
+        @Override
+        protected Class findClass(final String name) throws ClassNotFoundException {
+            // flag that it reached here
+            reached[0] = true;
+            return super.findClass(name);
+        }
+
+        public boolean reached() {
+            return reached[0];
+        }
+    };
+
+    // These are for "private" extension API of NashornScriptEngineFactory that
+    // accepts a ClassLoader and/or command line options.
+
+    @Test
+    public void factoryClassLoaderTest() {
+        final ScriptEngineManager sm = new ScriptEngineManager();
+        for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+            if (fac instanceof NashornScriptEngineFactory) {
+                final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+                final MyClassLoader loader = new MyClassLoader();
+                // set the classloader as app class loader
+                final ScriptEngine e = nfac.getScriptEngine(loader);
+                try {
+                    e.eval("Packages.foo");
+                    // check that the class loader was attempted
+                    assertTrue(loader.reached(), "did not reach class loader!");
+                } catch (final ScriptException se) {
+                    se.printStackTrace();
+                    fail(se.getMessage());
+                }
+                return;
+            }
+        }
+
+        fail("Cannot find nashorn factory!");
+    }
+
+    @Test
+    public void factoryClassLoaderAndOptionsTest() {
+        final ScriptEngineManager sm = new ScriptEngineManager();
+        for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+            if (fac instanceof NashornScriptEngineFactory) {
+                final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+                final String[] options = new String[] { "-strict" };
+                final MyClassLoader loader = new MyClassLoader();
+                // set the classloader as app class loader
+                final ScriptEngine e = nfac.getScriptEngine(options, loader);
+                try {
+                    e.eval("Packages.foo");
+                    // check that the class loader was attempted
+                    assertTrue(loader.reached(), "did not reach class loader!");
+                } catch (final ScriptException se) {
+                    se.printStackTrace();
+                    fail(se.getMessage());
+                }
+
+                try {
+                    // strict mode - delete of a var should throw SyntaxError
+                    e.eval("var d = 2; delete d;");
+                } catch (final ScriptException se) {
+                    // check that the error message contains "SyntaxError"
+                    assertTrue(se.getMessage().contains("SyntaxError"));
+                }
+
+                return;
+            }
+        }
+
+        fail("Cannot find nashorn factory!");
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java
new file mode 100644
index 0000000..3fd5c21
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java
@@ -0,0 +1,297 @@
+/*
+ * 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.test.framework;
+
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_CHECK_COMPILE_MSG;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_COMPARE;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_EXPECT_COMPILE_FAIL;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_EXPECT_RUN_FAIL;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_IGNORE_STD_ERROR;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_RUN;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_FAIL_LIST;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_SHARED_CONTEXT;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+
+/**
+ * Abstract class to compile and run one .js script file.
+ */
+public abstract class AbstractScriptRunnable {
+    // some test scripts need a "framework" script - whose features are used
+    // in the test script. This optional framework script can be null.
+
+    protected final String framework;
+    // Script file that is being tested
+    protected final File testFile;
+    // build directory where test output, stderr etc are redirected
+    protected final File buildDir;
+    // should run the test or just compile?
+    protected final boolean shouldRun;
+    // is compiler error expected?
+    protected final boolean expectCompileFailure;
+    // is runtime error expected?
+    protected final boolean expectRunFailure;
+    // is compiler error captured and checked against known error strings?
+    protected final boolean checkCompilerMsg;
+    // .EXPECTED file compared for this or test?
+    protected final boolean compare;
+    // ignore stderr output?
+    protected final boolean ignoreStdError;
+    // Foo.js.OUTPUT file where test stdout messages go
+    protected final String outputFileName;
+    // Foo.js.ERROR where test's stderr messages go.
+    protected final String errorFileName;
+    // copy of Foo.js.EXPECTED file
+    protected final String copyExpectedFileName;
+    // Foo.js.EXPECTED - output expected by running Foo.js
+    protected final String expectedFileName;
+    // options passed to Nashorn engine
+    protected final List<String> engineOptions;
+    // arguments passed to script - these are visible as "arguments" array to script
+    protected final List<String> scriptArguments;
+    // Tests that are forced to fail always
+    protected final Set<String> failList = new HashSet<>();
+
+    public AbstractScriptRunnable(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions, final List<String> scriptArguments) {
+        this.framework = framework;
+        this.testFile = testFile;
+        this.buildDir = TestHelper.makeBuildDir(testFile);
+        this.engineOptions = engineOptions;
+        this.scriptArguments = scriptArguments;
+
+        this.expectCompileFailure = testOptions.containsKey(OPTIONS_EXPECT_COMPILE_FAIL);
+        this.shouldRun = testOptions.containsKey(OPTIONS_RUN);
+        this.expectRunFailure = testOptions.containsKey(OPTIONS_EXPECT_RUN_FAIL);
+        this.checkCompilerMsg = testOptions.containsKey(OPTIONS_CHECK_COMPILE_MSG);
+        this.ignoreStdError = testOptions.containsKey(OPTIONS_IGNORE_STD_ERROR);
+        this.compare = testOptions.containsKey(OPTIONS_COMPARE);
+
+        final String testName = testFile.getName();
+        this.outputFileName = buildDir + File.separator + testName + ".OUTPUT";
+        this.errorFileName = buildDir + File.separator + testName + ".ERROR";
+        this.copyExpectedFileName = buildDir + File.separator + testName + ".EXPECTED";
+        this.expectedFileName = testFile.getPath() + ".EXPECTED";
+
+        final String failListString = System.getProperty(TEST_JS_FAIL_LIST);
+        if (failListString != null) {
+            final String[] failedTests = failListString.split(" ");
+            for (final String failedTest : failedTests) {
+                failList.add(failedTest.trim());
+            }
+        }
+    }
+
+    // run this test - compile or compile-and-run depending on option passed
+    public void runTest() throws IOException {
+        log(toString());
+
+        if (shouldRun) {
+            // Analysis of failing tests list -
+            // if test is in failing list it must fail
+            // to not wrench passrate (used for crashing tests).
+            if (failList.contains(testFile.getName())) {
+                fail(String.format("Test %s is forced to fail (see %s)", testFile, TEST_JS_FAIL_LIST));
+            }
+
+            execute();
+        } else {
+            compile();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Test(compile" + (expectCompileFailure ? "-" : "") + (shouldRun ? ", run" : "") + (expectRunFailure ? "-" : "") + "): " + testFile;
+    }
+
+    // compile-only command line arguments
+    protected List<String> getCompilerArgs() {
+        final List<String> args = new ArrayList<>();
+        args.add("--compile-only");
+        args.addAll(engineOptions);
+        args.add(testFile.getPath());
+        return args;
+    }
+
+    // shared context or not?
+    protected static final boolean sharedContext;
+    static {
+        sharedContext = Boolean.getBoolean(TEST_JS_SHARED_CONTEXT);
+    }
+    private static ThreadLocal<ScriptEvaluator> evaluators = new ThreadLocal<>();
+
+    /**
+     * Create a script evaluator or return from cache
+     * @return a ScriptEvaluator object
+     */
+    protected ScriptEvaluator getEvaluator() {
+        synchronized (AbstractScriptRunnable.class) {
+            ScriptEvaluator evaluator = evaluators.get();
+            if (evaluator == null) {
+                if (sharedContext) {
+                    final String[] args;
+                    if (framework.indexOf(' ') > 0) {
+                        args = framework.split("\\s+");
+                    } else {
+                        args = new String[] { framework };
+                    }
+                    evaluator = new SharedContextEvaluator(args);
+                    evaluators.set(evaluator);
+                } else {
+                    evaluator = new SeparateContextEvaluator();
+                    evaluators.set(evaluator);
+                }
+            }
+            return evaluator;
+        }
+    }
+
+    /**
+     * Evaluate one or more scripts with given output and error streams
+     *
+     * @param out OutputStream for script output
+     * @param err OutputStream for script errors
+     * @param args arguments for script evaluation
+     * @return success or error code from script execution
+     */
+    protected int evaluateScript(final OutputStream out, final OutputStream err, final String[] args) {
+        try {
+            return getEvaluator().run(out, err, args);
+        } catch (final IOException e) {
+            throw new UnsupportedOperationException("I/O error in initializing shell - cannot redirect output to file");
+        }
+    }
+
+    // arguments to be passed to compile-and-run this script
+    protected List<String> getRuntimeArgs() {
+        final ArrayList<String> args = new ArrayList<>();
+        // add engine options first
+        args.addAll(engineOptions);
+
+        // framework script if any
+        if (framework != null) {
+            if (framework.indexOf(' ') > 0) {
+                args.addAll(Arrays.asList(framework.split("\\s+")));
+            } else {
+                args.add(framework);
+            }
+        }
+
+        // test script
+        args.add(testFile.getPath());
+
+        // script arguments
+        if (!scriptArguments.isEmpty()) {
+            args.add("--");
+            args.addAll(scriptArguments);
+        }
+
+        return args;
+    }
+
+    // compares actual test output with .EXPECTED output
+    protected void compare(final BufferedReader actual, final BufferedReader expected, final boolean compareCompilerMsg) throws IOException {
+        int lineCount = 0;
+        while (true) {
+            final String es = expected.readLine();
+            String as = actual.readLine();
+            if (compareCompilerMsg) {
+                while (as != null && as.startsWith("--")) {
+                    as = actual.readLine();
+                }
+            }
+            ++lineCount;
+
+            if (es == null && as == null) {
+                if (expectRunFailure) {
+                    fail("Expected runtime failure");
+                } else {
+                    break;
+                }
+            } else if (expectRunFailure && ((es == null) || as == null || !es.equals(as))) {
+                break;
+            } else if (es == null) {
+                fail("Expected output for " + testFile + " ends prematurely at line " + lineCount);
+            } else if (as == null) {
+                fail("Program output for " + testFile + " ends prematurely at line " + lineCount);
+            } else if (es.equals(as)) {
+                continue;
+            } else if (compareCompilerMsg && equalsCompilerMsgs(es, as)) {
+                continue;
+            } else {
+                fail("Test " + testFile + " failed at line " + lineCount + " - " + " \n  expected: '" + escape(es) + "'\n     found: '" + escape(as) + "'");
+            }
+        }
+    }
+
+    // logs the message
+    protected abstract void log(String msg);
+    // throw failure message
+    protected abstract void fail(String msg);
+    // compile this script but don't run it
+    protected abstract void compile() throws IOException;
+    // compile and run this script
+    protected abstract void execute();
+
+    private boolean equalsCompilerMsgs(final String es, final String as) {
+        final int split = es.indexOf(':');
+        // Replace both types of separators ('/' and '\') with the one from
+        // current environment
+        return (split >= 0) && as.equals(es.substring(0, split).replaceAll("[/\\\\]", Matcher.quoteReplacement(File.separator)) + es.substring(split));
+    }
+
+    private void escape(final String value, final StringBuilder out) {
+        final int len = value.length();
+        for (int i = 0; i < len; i++) {
+            final char ch = value.charAt(i);
+            if (ch == '\n') {
+                out.append("\\n");
+            } else if (ch < ' ' || ch == 127) {
+                out.append(String.format("\\%03o", (int) ch));
+            } else if (ch > 127) {
+                out.append(String.format("\\u%04x", (int) ch));
+            } else {
+                out.append(ch);
+            }
+        }
+    }
+
+    private String escape(final String value) {
+        final StringBuilder sb = new StringBuilder();
+        escape(value, sb);
+        return sb.toString();
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/JSJUnitReportReporter.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/JSJUnitReportReporter.java
new file mode 100644
index 0000000..7f6bd8f
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/JSJUnitReportReporter.java
@@ -0,0 +1,41 @@
+/*
+ * 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.test.framework;
+
+import org.testng.ITestResult;
+import org.testng.reporters.JUnitReportReporter;
+
+/**
+ * Modify JUnit reports to include script file name as "method name" rather
+ * than the Java method name that uses the script file for testing.
+ */
+public class JSJUnitReportReporter extends JUnitReportReporter {
+    @Override
+    protected String getTestName(ITestResult tr) {
+        final String testName = tr.getTestName();
+        return (testName != null && testName.endsWith(".js"))? testName : super.getTestName(tr);
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/OrphanTestFinder.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/OrphanTestFinder.java
new file mode 100644
index 0000000..c9c567d
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/OrphanTestFinder.java
@@ -0,0 +1,67 @@
+/*
+ * 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.test.framework;
+
+import java.util.Set;
+import org.testng.Assert;
+import org.testng.ITest;
+import org.testng.annotations.Test;
+
+/**
+ * Test case used by JSCompilerTest to complain if test files are marked as
+ * neither test nor subtest.
+ */
+public final class OrphanTestFinder implements ITest {
+    private final Set<String> orphanFiles;
+
+    public OrphanTestFinder(final Set<String> orphanFiles) {
+        this.orphanFiles = orphanFiles;
+    }
+
+    @Override
+    public String getTestName() {
+        return getClass().getName();
+    }
+
+    @Test
+    public void test() {
+        if (orphanFiles == null || orphanFiles.isEmpty()) {
+            return;
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        final String NL = System.getProperty("line.separator");
+        sb.append(orphanFiles.size());
+        sb.append(" files found with neither @test nor @subtest: ");
+        sb.append(NL);
+        for (final String s : orphanFiles) {
+            sb.append("  ");
+            sb.append(s);
+            sb.append(NL);
+        }
+        Assert.fail(sb.toString());
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java
new file mode 100644
index 0000000..cc0e1cd
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java
@@ -0,0 +1,492 @@
+/*
+ * 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.test.framework;
+
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_ENABLE_STRICT_MODE;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDES_FILE;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDE_LIST;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_FRAMEWORK;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_ROOTS;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import jdk.nashorn.internal.test.framework.TestFinder.TestFactory;
+
+/**
+ * Parallel test runner runs tests in multiple threads - but avoids any dependency
+ * on third-party test framework library such as TestNG.
+ */
+public class ParallelTestRunner {
+
+    // ParallelTestRunner-specific
+    private static final String    TEST_JS_THREADS     = "test.js.threads";
+    private static final String    TEST_JS_REPORT_FILE = "test.js.report.file";
+    private static final int       THREADS             = Integer.getInteger(TEST_JS_THREADS, Runtime.getRuntime().availableProcessors());
+
+    private final List<ScriptRunnable> tests    = new ArrayList<>();
+    private final Set<String>      orphans  = new TreeSet<>();
+    private final ExecutorService  executor = Executors.newFixedThreadPool(THREADS);
+
+    // Ctrl-C handling
+    private final CountDownLatch   finishedLatch = new CountDownLatch(1);
+    private final Thread           shutdownHook  = new Thread() {
+                                                       @Override
+                                                       public void run() {
+                                                           if (!executor.isTerminated()) {
+                                                               executor.shutdownNow();
+                                                               try {
+                                                                   executor.awaitTermination(25, TimeUnit.SECONDS);
+                                                                   finishedLatch.await(5, TimeUnit.SECONDS);
+                                                               } catch (final InterruptedException e) {
+                                                                   // empty
+                                                               }
+                                                           }
+                                                       }
+                                                   };
+
+    public ParallelTestRunner() throws Exception {
+        suite();
+    }
+
+    private static PrintStream outputStream() {
+        final String reportFile = System.getProperty(TEST_JS_REPORT_FILE, "");
+        PrintStream output = System.out;
+
+        if (!reportFile.isEmpty()) {
+            try {
+                output = new PrintStream(new OutputStreamDelegator(System.out, new FileOutputStream(reportFile)));
+            } catch (final IOException e) {
+                System.err.println(e);
+            }
+        }
+
+        return output;
+    }
+
+    public static final class ScriptRunnable extends AbstractScriptRunnable implements Callable<ScriptRunnable.Result> {
+        private final Result                result   = new Result();
+
+        public class Result {
+            private boolean  passed = true;
+            public String    expected;
+            public String    out;
+            public String    err;
+            public Throwable exception;
+
+            public ScriptRunnable getTest() {
+                return ScriptRunnable.this;
+            }
+
+            public boolean passed() {
+                return passed;
+            }
+
+            @Override
+            public String toString() {
+                return getTest().toString();
+            }
+        }
+
+        public ScriptRunnable(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions, final List<String> scriptArguments) {
+            super(framework, testFile, engineOptions, testOptions, scriptArguments);
+        }
+
+        @Override
+        protected void log(String msg) {
+            System.err.println(msg);
+        }
+
+        @Override
+        protected void fail(final String message) {
+            throw new TestFailedError(message);
+        }
+
+        @Override
+        protected void compile() throws IOException {
+            final ByteArrayOutputStream out = new ByteArrayOutputStream();
+            final ByteArrayOutputStream err = new ByteArrayOutputStream();
+            final List<String> args = getCompilerArgs();
+            int errors;
+            try {
+                errors = evaluateScript(out, err, args.toArray(new String[args.size()]));
+            } catch (final AssertionError e) {
+                final PrintWriter writer = new PrintWriter(err);
+                e.printStackTrace(writer);
+                writer.flush();
+                errors = 1;
+            }
+            if (errors != 0 || checkCompilerMsg) {
+                result.err = err.toString();
+                if (expectCompileFailure || checkCompilerMsg) {
+                    final PrintStream outputDest = new PrintStream(new FileOutputStream(getErrorFileName()));
+                    TestHelper.dumpFile(outputDest, new StringReader(new String(err.toByteArray())));
+                    outputDest.println("--");
+                }
+                if (errors != 0 && !expectCompileFailure) {
+                    fail(String.format("%d errors compiling %s", errors, testFile));
+                }
+                if (checkCompilerMsg) {
+                    compare(getErrorFileName(), expectedFileName, true);
+                }
+            }
+            if (expectCompileFailure && errors == 0) {
+                fail(String.format("No errors encountered compiling negative test %s", testFile));
+            }
+        }
+
+        @Override
+        protected void execute() {
+            final List<String> args = getRuntimeArgs();
+            final ByteArrayOutputStream out = new ByteArrayOutputStream();
+            final ByteArrayOutputStream err = new ByteArrayOutputStream();
+
+            try {
+                final int errors = evaluateScript(out, err, args.toArray(new String[args.size()]));
+
+                if (errors != 0 || err.size() > 0) {
+                    if (expectRunFailure) {
+                        return;
+                    }
+                    if (!ignoreStdError) {
+
+                        try (OutputStream outputFile = new FileOutputStream(getOutputFileName()); OutputStream errorFile = new FileOutputStream(getErrorFileName())) {
+                            outputFile.write(out.toByteArray());
+                            errorFile.write(err.toByteArray());
+                        }
+
+                        result.out = out.toString();
+                        result.err = err.toString();
+                        fail(err.toString());
+                    }
+                }
+
+                if (compare) {
+                    final File expectedFile = new File(expectedFileName);
+                    try {
+                        BufferedReader expected;
+                        if (expectedFile.exists()) {
+                            expected = new BufferedReader(new FileReader(expectedFile));
+                        } else {
+                            expected = new BufferedReader(new StringReader(""));
+                        }
+                        compare(new BufferedReader(new StringReader(out.toString())), expected, false);
+                    } catch (final Throwable ex) {
+                        if (expectedFile.exists()) {
+                            copyExpectedFile();
+                        }
+                        try (OutputStream outputFile = new FileOutputStream(getOutputFileName()); OutputStream errorFile = new FileOutputStream(getErrorFileName())) {
+                            outputFile.write(out.toByteArray());
+                            errorFile.write(err.toByteArray());
+                        }
+                        throw ex;
+                    }
+                }
+            } catch (final IOException e) {
+                if (!expectRunFailure) {
+                    fail("Failure running test " + testFile + ": " + e.getMessage());
+                } // else success
+            }
+        }
+
+        private void compare(final String outputFileName, final String expected, final boolean compareCompilerMsg) throws IOException {
+            final File expectedFile = new File(expected);
+
+            BufferedReader expectedReader;
+            if (expectedFile.exists()) {
+                expectedReader = new BufferedReader(new InputStreamReader(new FileInputStream(expectedFileName)));
+            } else {
+                expectedReader = new BufferedReader(new StringReader(""));
+            }
+
+            final BufferedReader actual = new BufferedReader(new InputStreamReader(new FileInputStream(outputFileName)));
+
+            compare(actual, expectedReader, compareCompilerMsg);
+        }
+
+        private void copyExpectedFile() {
+            if (!new File(expectedFileName).exists()) {
+                return;
+            }
+            // copy expected file overwriting existing file and preserving last
+            // modified time of source
+            try {
+                Files.copy(FileSystems.getDefault().getPath(expectedFileName), FileSystems.getDefault().getPath(getCopyExpectedFileName()), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
+            } catch (final IOException ex) {
+                fail("failed to copy expected " + expectedFileName + " to " + getCopyExpectedFileName() + ": " + ex.getMessage());
+            }
+        }
+
+        @Override
+        public Result call() {
+            try {
+                runTest();
+            } catch (final Throwable ex) {
+                result.exception = ex;
+                result.passed = false;
+            }
+            return result;
+        }
+
+        private String getOutputFileName() {
+            buildDir.mkdirs();
+            return outputFileName;
+        }
+
+        private String getErrorFileName() {
+            buildDir.mkdirs();
+            return errorFileName;
+        }
+
+        private String getCopyExpectedFileName() {
+            buildDir.mkdirs();
+            return copyExpectedFileName;
+        }
+    }
+
+    private void suite() throws Exception {
+        Locale.setDefault(new Locale(""));
+        System.setOut(outputStream());
+
+        final TestFactory<ScriptRunnable> testFactory = new TestFactory<ScriptRunnable>() {
+            @Override
+            public ScriptRunnable createTest(String framework, File testFile, List<String> engineOptions, Map<String, String> testOptions, List<String> arguments) {
+                return new ScriptRunnable(framework, testFile, engineOptions, testOptions, arguments);
+            }
+
+            @Override
+            public void log(String msg) {
+                System.err.println(msg);
+            }
+        };
+
+        TestFinder.findAllTests(tests, orphans, testFactory);
+
+        Collections.sort(tests, new Comparator<ScriptRunnable>() {
+            @Override
+            public int compare(final ScriptRunnable o1, final ScriptRunnable o2) {
+                return o1.testFile.compareTo(o2.testFile);
+            }
+        });
+    }
+
+    public void run() {
+        final int testCount = tests.size();
+        int passCount = 0;
+        int doneCount = 0;
+        System.out.printf("Found %d tests.\n", testCount);
+        final long startTime = System.nanoTime();
+
+        Runtime.getRuntime().addShutdownHook(shutdownHook);
+
+        final List<Future<ScriptRunnable.Result>> futures = new ArrayList<>();
+        for (final ScriptRunnable test : tests) {
+            futures.add(executor.submit(test));
+        }
+
+        executor.shutdown();
+        try {
+            executor.awaitTermination(60, TimeUnit.MINUTES);
+        } catch (final InterruptedException ex) {
+            // empty
+        }
+
+        final List<ScriptRunnable.Result> results = new ArrayList<>();
+        for (final Future<ScriptRunnable.Result> future : futures) {
+            if (future.isDone()) {
+                try {
+                    final ScriptRunnable.Result result = future.get();
+                    results.add(result);
+                    doneCount++;
+                    if (result.passed()) {
+                        passCount++;
+                    }
+                } catch (CancellationException | ExecutionException ex) {
+                    ex.printStackTrace();
+                } catch (final InterruptedException ex) {
+                    assert false : "should not reach here";
+                }
+            }
+        }
+
+        Collections.sort(results, new Comparator<ScriptRunnable.Result>() {
+            @Override
+            public int compare(final ScriptRunnable.Result o1, final ScriptRunnable.Result o2) {
+                return o1.getTest().testFile.compareTo(o2.getTest().testFile);
+            }
+        });
+
+        boolean hasFailed = false;
+        for (final ScriptRunnable.Result result : results) {
+            if (!result.passed()) {
+                if (hasFailed == false) {
+                    hasFailed = true;
+                    System.out.println();
+                    System.out.println("FAILED TESTS");
+                }
+
+                System.out.println(result.getTest());
+                if (result.exception != null) {
+                    final String exceptionString = result.exception instanceof TestFailedError ? result.exception.getMessage() : result.exception.toString();
+                    System.out.print(exceptionString.endsWith("\n") ? exceptionString : exceptionString + "\n");
+                    System.out.print(result.out != null ? result.out : "");
+                }
+            }
+        }
+
+        final double timeElapsed = (System.nanoTime() - startTime) / 1e9; // [s]
+        System.out.printf("Tests run: %d/%d tests, passed: %d (%.2f%%), failed: %d. Time elapsed: %.0fmin %.0fs.\n", doneCount, testCount, passCount, 100d * passCount / doneCount, doneCount - passCount, timeElapsed / 60, timeElapsed % 60);
+        System.out.flush();
+
+        finishedLatch.countDown();
+
+        if (hasFailed) {
+            throw new AssertionError("TEST FAILED");
+        }
+    }
+
+    public static void main(final String[] args) throws Exception {
+        parseArgs(args);
+
+        new ParallelTestRunner().run();
+    }
+
+    private static void parseArgs(final String[] args) {
+        if (args.length > 0) {
+            String roots = "";
+            String reportFile = "";
+            for (int i = 0; i < args.length; i++) {
+                if (args[i].equals("--roots") && i != args.length - 1) {
+                    roots += args[++i] + " ";
+                } else if (args[i].equals("--report-file") && i != args.length - 1) {
+                    reportFile = args[++i];
+                } else if (args[i].equals("--test262")) {
+                    try {
+                        setTest262Properties();
+                    } catch (final IOException ex) {
+                        System.err.println(ex);
+                    }
+                }
+            }
+            if (!roots.isEmpty()) {
+                System.setProperty(TEST_JS_ROOTS, roots.trim());
+            }
+            if (!reportFile.isEmpty()) {
+                System.setProperty(TEST_JS_REPORT_FILE, reportFile);
+            }
+        }
+    }
+
+    private static void setTest262Properties() throws IOException {
+        System.setProperty(TEST_JS_ROOTS, "test/test262/test/suite/");
+        System.setProperty(TEST_JS_FRAMEWORK, "test/script/test262.js test/test262/test/harness/framework.js test/test262/test/harness/sta.js");
+        System.setProperty(TEST_JS_EXCLUDES_FILE, "test/test262/test/config/excludelist.xml");
+        System.setProperty(TEST_JS_ENABLE_STRICT_MODE, "true");
+
+        final Properties projectProperties = new Properties();
+        projectProperties.load(new FileInputStream("project.properties"));
+        String excludeList = projectProperties.getProperty("test262-test-sys-prop.test.js.exclude.list", "");
+        final Pattern pattern = Pattern.compile("\\$\\{([^}]+)}");
+        for (;;) {
+            final Matcher matcher = pattern.matcher(excludeList);
+            if (!matcher.find()) {
+                break;
+            }
+            final String propertyValue = projectProperties.getProperty(matcher.group(1), "");
+            excludeList = excludeList.substring(0, matcher.start()) + propertyValue + excludeList.substring(matcher.end());
+        }
+        System.setProperty(TEST_JS_EXCLUDE_LIST, excludeList);
+    }
+
+    public static final class OutputStreamDelegator extends OutputStream {
+        private final OutputStream[] streams;
+
+        public OutputStreamDelegator(final OutputStream... streams) {
+            this.streams = streams;
+        }
+
+        @Override
+        public void write(final int b) throws IOException {
+            for (final OutputStream stream : streams) {
+                stream.write(b);
+            }
+        }
+
+        @Override
+        public void flush() throws IOException {
+            for (final OutputStream stream : streams) {
+                stream.flush();
+            }
+        }
+    }
+}
+
+final class TestFailedError extends Error {
+    private static final long serialVersionUID = 1L;
+
+    public TestFailedError(final String message) {
+        super(message);
+    }
+
+    public TestFailedError(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+    public TestFailedError(final Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptEvaluator.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptEvaluator.java
new file mode 100644
index 0000000..6a2eebb
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptEvaluator.java
@@ -0,0 +1,45 @@
+/*
+ * 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.test.framework;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Support for script evaluation.
+ */
+public interface ScriptEvaluator {
+    /**
+     * Runs one or more scripts files with given output and error stream set in the context
+     *
+     * @param out OutputStream for output from script evaluation
+     * @param err OutputStream for errors from script evaluation
+     * @param args one or more script arguments
+     * @return success or error code - the codes used are same as used by Shell class
+     * @throws IOException throws if there are issues with stream handling
+     */
+    public int run(OutputStream out, OutputStream err, String[] args) throws IOException;
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java
new file mode 100644
index 0000000..20548d7
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java
@@ -0,0 +1,236 @@
+/*
+ * 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.test.framework;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import org.testng.Assert;
+import org.testng.ITest;
+import org.testng.annotations.Test;
+
+/**
+ * Compiles a single JavaScript script source file and executes the resulting
+ * class. Optionally, output from running the script is compared against the
+ * corresponding .EXPECTED file.
+ */
+public final class ScriptRunnable extends AbstractScriptRunnable implements ITest {
+    // when test is run in a separate process, this is the command line
+    protected final ArrayList<String> separateProcessArgs;
+
+    public ScriptRunnable(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions,  final List<String> scriptArguments) {
+        super(framework, testFile, engineOptions, testOptions, scriptArguments);
+
+        if (this.shouldRun) {
+          // add --dump-on-error option always so that we can get detailed error msg.
+          engineOptions.add("-doe");
+        }
+
+        final String separateProcess = System.getProperty("test.js.separateprocess");
+        this.separateProcessArgs = separateProcess == null ? null : new ArrayList<>(Arrays.asList(separateProcess.split(" ")));
+    }
+
+    @Override
+    public String getTestName() {
+        return testFile.getAbsolutePath();
+    }
+
+    @Test
+    @Override
+    public void runTest() throws IOException {
+        super.runTest();
+    }
+
+    @Override
+    protected void execute() {
+        if (separateProcessArgs != null) {
+            executeInNewProcess();
+        } else {
+            executeInThisProcess();
+        }
+    }
+
+    // avoid direct System.out.println - use reporter to capture
+    @Override
+    protected void log(String msg) {
+        org.testng.Reporter.log(msg, true);
+    }
+
+    // throw Assert fail - but log as well so that user can see this at console
+    @Override
+    protected void fail(final String msg) {
+        log(msg);
+        Assert.fail(msg);
+    }
+
+    @Override
+    protected void compile() throws IOException {
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final ByteArrayOutputStream err = new ByteArrayOutputStream();
+        final List<String> args = getCompilerArgs();
+        int errors;
+
+        try {
+            errors = evaluateScript(out, err, args.toArray(new String[args.size()]));
+        } catch (final AssertionError e) {
+            final PrintWriter writer = new PrintWriter(err);
+            e.printStackTrace(writer);
+            writer.flush();
+            errors = 1;
+        }
+
+        if (errors != 0 || checkCompilerMsg) {
+            if (expectCompileFailure || checkCompilerMsg) {
+                final PrintStream outputDest = new PrintStream(new FileOutputStream(errorFileName));
+                TestHelper.dumpFile(outputDest, new StringReader(new String(err.toByteArray())));
+                outputDest.println("--");
+            } else {
+                log(new String(err.toByteArray()));
+            }
+
+            if (errors != 0 && !expectCompileFailure) {
+                fail(String.format("%d errors compiling %s", errors, testFile));
+            }
+            if (checkCompilerMsg) {
+                compare(errorFileName, expectedFileName, true);
+            }
+        }
+
+        if (expectCompileFailure && errors == 0) {
+            fail(String.format("No errors encountered compiling negative test %s", testFile));
+        }
+    }
+
+    private void executeInThisProcess() {
+        final List<String> args = getRuntimeArgs();
+        final File outputFileHandle = new File(outputFileName);
+        final File errorFileHandle  = new File(errorFileName);
+
+        try (OutputStream outputFile = new FileOutputStream(outputFileName); OutputStream errorFile = new FileOutputStream(errorFileName)) {
+            final int errors = evaluateScript(outputFile, errorFile, args.toArray(new String[args.size()]));
+
+            if (errors != 0 || errorFileHandle.length() > 0) {
+                if (expectRunFailure) {
+                    return;
+                }
+
+                if (!ignoreStdError) {
+                    if (outputFileHandle.length() > 0) {
+                        TestHelper.dumpFile(outputFileHandle);
+                    }
+                    fail(TestHelper.fullContent(errorFileHandle));
+                }
+            }
+
+            if (compare) {
+                compare(outputFileName, expectedFileName, false);
+            }
+        } catch (final IOException e) {
+            if (!expectRunFailure) {
+                fail("Failure running test " + testFile + ": " + e.getMessage());
+                // else success
+            }
+        }
+    }
+
+    private void executeInNewProcess() {
+        final List<String> args = separateProcessArgs;
+        // now add the rest of the "in process" runtime arguments
+        args.addAll(getRuntimeArgs());
+
+        final File outputFileHandle = new File(outputFileName);
+        final File errorFileHandle = new File(errorFileName);
+
+        try {
+            final ProcessBuilder pb = new ProcessBuilder(args);
+            pb.redirectOutput(outputFileHandle);
+            pb.redirectError(errorFileHandle);
+            final Process process = pb.start();
+
+            process.waitFor();
+
+            if (errorFileHandle.length() > 0) {
+                if (expectRunFailure) {
+                    return;
+                }
+                if (!ignoreStdError) {
+                    if (outputFileHandle.length() > 0) {
+                        TestHelper.dumpFile(outputFileHandle);
+                    }
+                    fail(TestHelper.fullContent(errorFileHandle));
+                }
+            }
+
+            if (compare) {
+                compare(outputFileName, expectedFileName, false);
+            }
+        } catch (final IOException | InterruptedException e) {
+            if (!expectRunFailure) {
+                fail("Failure running test " + testFile + ": " + e.getMessage());
+                // else success
+            }
+        }
+    }
+
+    private void compare(final String outputFileName0, final String expectedFileName0, final boolean compareCompilerMsg) throws IOException {
+        final File expectedFile = new File(expectedFileName0);
+
+        BufferedReader expected;
+        if (expectedFile.exists()) {
+            expected = new BufferedReader(new InputStreamReader(new FileInputStream(expectedFileName0)));
+            // copy expected file overwriting existing file and preserving last
+            // modified time of source
+            try {
+                Files.copy(FileSystems.getDefault().getPath(expectedFileName0),
+                        FileSystems.getDefault().getPath(copyExpectedFileName),
+                        StandardCopyOption.REPLACE_EXISTING,
+                        StandardCopyOption.COPY_ATTRIBUTES);
+            } catch (final IOException ex) {
+                fail("failed to copy expected " + expectedFileName + " to " + copyExpectedFileName + ": " + ex.getMessage());
+            }
+        } else {
+            expected = new BufferedReader(new StringReader(""));
+        }
+
+        final BufferedReader actual = new BufferedReader(new InputStreamReader(new FileInputStream(outputFileName0)));
+        compare(actual, expected, compareCompilerMsg);
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptTest.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptTest.java
new file mode 100644
index 0000000..acaf542
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.test.framework;
+
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_INCLUDES;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import jdk.nashorn.internal.test.framework.TestFinder.TestFactory;
+import org.testng.ITest;
+import org.testng.annotations.Factory;
+import org.testng.annotations.Listeners;
+
+/**
+ * Simple test suite Factory for the JavaScript tests - runs tests in the name order.
+ */
+@Listeners({ TestReorderInterceptor.class })
+public final class ScriptTest {
+    /**
+     * Creates a test factory for the set of .js source tests.
+     *
+     * @return a Object[] of test objects.
+     */
+    @Factory
+    public Object[] suite() throws Exception {
+        Locale.setDefault(new Locale(""));
+
+        final List<ITest> tests = new ArrayList<>();
+        final Set<String> orphans = new TreeSet<>();
+
+        final TestFactory<ITest> testFactory = new TestFactory<ITest>() {
+            @Override
+            public ITest createTest(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions, final List<String> scriptArguments) {
+                return new ScriptRunnable(framework, testFile, engineOptions, testOptions,  scriptArguments);
+            }
+
+            @Override
+            public void log(String msg) {
+                org.testng.Reporter.log(msg, true);
+            }
+        };
+
+        TestFinder.findAllTests(tests, orphans, testFactory);
+
+        if (System.getProperty(TEST_JS_INCLUDES) == null) {
+            tests.add(new OrphanTestFinder(orphans));
+        }
+
+        return tests.toArray();
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/SeparateContextEvaluator.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/SeparateContextEvaluator.java
new file mode 100644
index 0000000..d108a1b
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/SeparateContextEvaluator.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.test.framework;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import jdk.nashorn.tools.Shell;
+
+/**
+ * A script evaluator that uses a fresh Nashorn Context to evaluate scripts.
+ */
+public final class SeparateContextEvaluator implements ScriptEvaluator {
+    @Override
+    public int run(final OutputStream out, final OutputStream err, final String[] args) throws IOException {
+        return Shell.main(System.in, out, err, args);
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java
new file mode 100644
index 0000000..ac2dc17
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java
@@ -0,0 +1,153 @@
+/*
+ * 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.test.framework;
+
+import static jdk.nashorn.tools.Shell.COMPILATION_ERROR;
+import static jdk.nashorn.tools.Shell.RUNTIME_ERROR;
+import static jdk.nashorn.tools.Shell.SUCCESS;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * A script evaluator that shares a single Nashorn Context instance to run
+ * scripts many times on it.
+ */
+public final class SharedContextEvaluator implements ScriptEvaluator {
+    // The shared Nashorn Context
+    private final Context context;
+
+    // We can't replace output and error streams after Context is created
+    // So, we create these delegating streams - so that we can replace underlying
+    // delegate streams for each script run call
+    private final DelegatingOutputStream ctxOut;
+    private final DelegatingOutputStream ctxErr;
+
+    private static class DelegatingOutputStream extends OutputStream {
+        private OutputStream underlying;
+
+        public DelegatingOutputStream(final OutputStream out) {
+            this.underlying = out;
+        }
+
+        @Override
+        public void close() throws IOException {
+            underlying.close();
+        }
+
+        @Override
+        public void flush() throws IOException {
+            underlying.flush();
+        }
+
+        @Override
+        public void write(byte[] b) throws IOException {
+            underlying.write(b);
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+            underlying.write(b, off, len);
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            underlying.write(b);
+        }
+
+        void setDelegatee(OutputStream stream) {
+            this.underlying = stream;
+        }
+    }
+
+    /**
+     * SharedContextEvaluator constructor
+     * @param args initial script arguments to create shared context
+     */
+    public SharedContextEvaluator(final String[] args) {
+        this.ctxOut = new DelegatingOutputStream(System.out);
+        this.ctxErr = new DelegatingOutputStream(System.err);
+        PrintWriter wout = new PrintWriter(ctxOut, true);
+        PrintWriter werr = new PrintWriter(ctxErr, true);
+        Options options = new Options("nashorn", werr);
+        options.process(args);
+        ErrorManager errors = new ErrorManager(werr);
+        this.context = new Context(options, errors, wout, werr, Thread.currentThread().getContextClassLoader());
+    }
+
+    @Override
+    public int run(final OutputStream out, final OutputStream err, final String[] args) throws IOException {
+        final ScriptObject oldGlobal = Context.getGlobal();
+        try {
+            ctxOut.setDelegatee(out);
+            ctxErr.setDelegatee(err);
+            final ErrorManager errors = context.getErrorManager();
+            final ScriptObject global = context.createGlobal();
+            Context.setGlobal(global);
+
+            // For each file on the command line.
+            for (final String fileName : args) {
+                if (fileName.startsWith("-")) {
+                    // ignore options in shared context mode (which was initialized upfront!)
+                    continue;
+                }
+                final File file = new File(fileName);
+                ScriptFunction script = context.compileScript(new Source(fileName, file.toURI().toURL()), global);
+
+                if (script == null || errors.getNumberOfErrors() != 0) {
+                    return COMPILATION_ERROR;
+                }
+
+                try {
+                    ScriptRuntime.apply(script, global);
+                } catch (final NashornException e) {
+                    errors.error(e.toString());
+                    if (context.getEnv()._dump_on_error) {
+                        e.printStackTrace(context.getErr());
+                    }
+
+                    return RUNTIME_ERROR;
+                }
+            }
+        } finally {
+            context.getOut().flush();
+            context.getErr().flush();
+            Context.setGlobal(oldGlobal);
+        }
+
+        return SUCCESS;
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java
new file mode 100644
index 0000000..cf798f6
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java
@@ -0,0 +1,75 @@
+/*
+ * 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.test.framework;
+
+/**
+ * Configuration info for script tests.
+ */
+public interface TestConfig {
+    // Test options inferred from various test @foo tags and passed to test factory.
+    public static final String   OPTIONS_RUN                 = "run";
+    public static final String   OPTIONS_EXPECT_COMPILE_FAIL = "expect-compile-fail";
+    public static final String   OPTIONS_CHECK_COMPILE_MSG   = "check-compile-msg";
+    public static final String   OPTIONS_EXPECT_RUN_FAIL     = "expect-run-fail";
+    public static final String   OPTIONS_IGNORE_STD_ERROR    = "ignore-std-error";
+    public static final String   OPTIONS_COMPARE             = "compare";
+
+    // System property names used for various test configurations
+
+    // A list of test directories under which to look for the TEST_JS_INCLUDES
+    // patterns
+    static final String  TEST_JS_ROOTS                       = "test.js.roots";
+
+    // A pattern of tests to include under the TEST_JS_ROOTS
+    static final String TEST_JS_INCLUDES                    = "test.js.includes";
+
+    // explicit list of tests specified to run
+    static final String TEST_JS_LIST                        = "test.js.list";
+
+    // framework script that runs before the test scripts
+    static final String TEST_JS_FRAMEWORK                   = "test.js.framework";
+
+    // test directory to skip
+    static final String TEST_JS_EXCLUDE_DIR                 = "test.js.exclude.dir";
+
+    // test directory where everything should be run
+    static final String TEST_JS_UNCHECKED_DIR               = "test.js.unchecked.dir";
+
+    // specific tests to skip
+    static final String TEST_JS_EXCLUDE_LIST                = "test.js.exclude.list";
+
+    // file containing list of tests to skip
+    static final String TEST_JS_EXCLUDES_FILE               = "test.js.excludes.file";
+
+    // strict mode or not
+    static final String TEST_JS_ENABLE_STRICT_MODE          = "test.js.enable.strict.mode";
+
+    // always fail test list
+    static final String TEST_JS_FAIL_LIST                   = "test.js.fail.list";
+
+    // shared context mode or not
+    static final String TEST_JS_SHARED_CONTEXT              = "test.js.shared.context";
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java
new file mode 100644
index 0000000..a326a59
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java
@@ -0,0 +1,362 @@
+/*
+ * 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.test.framework;
+
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_CHECK_COMPILE_MSG;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_COMPARE;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_EXPECT_COMPILE_FAIL;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_EXPECT_RUN_FAIL;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_IGNORE_STD_ERROR;
+import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_RUN;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_ENABLE_STRICT_MODE;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDES_FILE;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDE_DIR;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDE_LIST;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_FRAMEWORK;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_INCLUDES;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_LIST;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_ROOTS;
+import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_UNCHECKED_DIR;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+/**
+ * Utility class to find/parse script test files and to create 'test' instances.
+ * Actual 'test' object type is decided by clients of this class.
+ */
+final class TestFinder {
+    private TestFinder() {}
+
+    interface TestFactory<T> {
+        // 'test' instance type is decided by the client.
+        T createTest(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions, final List<String> arguments);
+        // place to log messages from TestFinder
+        void log(String mg);
+    }
+
+
+    // finds all tests from configuration and calls TestFactory to create 'test' instance for each script test found
+    static <T> void findAllTests(final List<T> tests, final Set<String> orphans, final TestFactory<T> testFactory) throws Exception {
+        final String framework = System.getProperty(TEST_JS_FRAMEWORK);
+        final String testList = System.getProperty(TEST_JS_LIST);
+        if (testList == null || testList.length() == 0) {
+            // Run the tests under the test roots dir, selected by the
+            // TEST_JS_INCLUDES patterns
+            final String testRootsString = System.getProperty(TEST_JS_ROOTS, "test/script");
+            if (testRootsString == null || testRootsString.length() == 0) {
+                throw new Exception("Error: " + TEST_JS_ROOTS + " must be set");
+            }
+            final String testRoots[] = testRootsString.split(" ");
+            final FileSystem fileSystem = FileSystems.getDefault();
+            final Set<String> testExcludeSet = getExcludeSet();
+            final Path[] excludePaths = getExcludeDirs();
+            for (final String root : testRoots) {
+                final Path dir = fileSystem.getPath(root);
+                findTests(framework, dir, tests, orphans, excludePaths, testExcludeSet, testFactory);
+            }
+        } else {
+            // TEST_JS_LIST contains a blank speparated list of test file names.
+            final String strArray[] = testList.split(" ");
+            for (final String ss : strArray) {
+                handleOneTest(framework, new File(ss).toPath(), tests, orphans, testFactory);
+            }
+        }
+    }
+
+    private static boolean inExcludePath(final Path file, final Path[] excludePaths) {
+        if (excludePaths == null) {
+            return false;
+        }
+
+        for (final Path excludePath : excludePaths) {
+            if (file.startsWith(excludePath)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static <T> void findTests(final String framework, final Path dir, final List<T> tests, final Set<String> orphanFiles, final Path[] excludePaths, final Set<String> excludedTests, final TestFactory<T> factory) throws Exception {
+        final String pattern = System.getProperty(TEST_JS_INCLUDES);
+        final String extension = pattern == null ? "js" : pattern;
+        final Exception[] exceptions = new Exception[1];
+        final List<String> excludedActualTests = new ArrayList<>();
+
+        if (! dir.toFile().isDirectory()) {
+            factory.log("WARNING: " + dir + " not found or not a directory");
+        }
+
+        Files.walkFileTree(dir, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
+                final String fileName = file.getName(file.getNameCount() - 1).toString();
+                if (fileName.endsWith(extension)) {
+                    final String namex = file.toString().replace('\\', '/');
+                    if (!inExcludePath(file, excludePaths) && !excludedTests.contains(file.getFileName().toString())) {
+                        try {
+                            handleOneTest(framework, file, tests, orphanFiles, factory);
+                        } catch (final Exception ex) {
+                            exceptions[0] = ex;
+                            return FileVisitResult.TERMINATE;
+                        }
+                    } else {
+                        excludedActualTests.add(namex);
+                    }
+                }
+                return FileVisitResult.CONTINUE;
+            }
+        });
+        Collections.sort(excludedActualTests);
+
+        for (final String excluded : excludedActualTests) {
+            factory.log("Excluding " + excluded);
+        }
+
+        if (exceptions[0] != null) {
+            throw exceptions[0];
+        }
+    }
+
+    private static final String uncheckedDirs[] = System.getProperty(TEST_JS_UNCHECKED_DIR, "test/script/external/test262/").split(" ");
+
+    private static boolean isUnchecked(final Path testFile) {
+        for (final String uncheckedDir : uncheckedDirs) {
+            if (testFile.startsWith(uncheckedDir)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static <T> void handleOneTest(final String framework, final Path testFile, final List<T> tests, final Set<String> orphans, TestFactory<T> factory) throws Exception {
+        final String name = testFile.getFileName().toString();
+
+        assert name.lastIndexOf(".js") > 0 : "not a JavaScript: " + name;
+
+        // defaults: testFile is a test and should be run
+        boolean isTest = isUnchecked(testFile);
+        boolean isNotTest = false;
+        boolean shouldRun = true;
+        boolean compileFailure = false;
+        boolean runFailure = false;
+        boolean checkCompilerMsg = false;
+        boolean noCompare = false;
+        boolean ignoreStdError = false;
+
+        final List<String> engineOptions = new ArrayList<>();
+        final List<String> scriptArguments = new ArrayList<>();
+        boolean inComment = false;
+
+        try (Scanner scanner = new Scanner(testFile)) {
+            while (scanner.hasNext()) {
+                // TODO: Scan for /ref=file qualifiers, etc, to determine run
+                // behavior
+                String token = scanner.next();
+                if (token.startsWith("/*")) {
+                    inComment = true;
+                } else if (token.endsWith(("*/"))) {
+                    inComment = false;
+                } else if (!inComment) {
+                    continue;
+                }
+
+                // remove whitespace and trailing semicolons, if any
+                // (trailing semicolons are found in some sputnik tests)
+                token = token.trim();
+                final int semicolon = token.indexOf(';');
+                if (semicolon > 0) {
+                    token = token.substring(0, semicolon);
+                }
+                switch (token) {
+                case "@test":
+                    isTest = true;
+                    break;
+                case "@test/fail":
+                    isTest = true;
+                    compileFailure = true;
+                    break;
+                case "@test/compile-error":
+                    isTest = true;
+                    compileFailure = true;
+                    checkCompilerMsg = true;
+                    shouldRun = false;
+                    break;
+                case "@test/warning":
+                    isTest = true;
+                    checkCompilerMsg = true;
+                    break;
+                case "@test/nocompare":
+                    isTest = true;
+                    noCompare = true;
+                    break;
+                case "@subtest":
+                    isTest = false;
+                    isNotTest = true;
+                    break;
+                case "@runif":
+                    if (System.getProperty(scanner.next()) != null) {
+                        shouldRun = true;
+                    } else {
+                        isTest = false;
+                        isNotTest = true;
+                    }
+                    break;
+                case "@run":
+                    shouldRun = true;
+                    break;
+                case "@run/fail":
+                    shouldRun = true;
+                    runFailure = true;
+                    break;
+                case "@run/ignore-std-error":
+                    shouldRun = true;
+                    ignoreStdError = true;
+                    break;
+                case "@argument":
+                    scriptArguments.add(scanner.next());
+                    break;
+                case "@option":
+                    engineOptions.add(scanner.next());
+                    break;
+                }
+
+                // negative tests are expected to fail at runtime only
+                // for those tests that are expected to fail at compile time,
+                // add @test/compile-error
+                if (token.equals("@negative") || token.equals("@strict_mode_negative")) {
+                    shouldRun = true;
+                    runFailure = true;
+                }
+
+                if (token.equals("@strict_mode") || token.equals("@strict_mode_negative") || token.equals("@onlyStrict") || token.equals("@noStrict")) {
+                    if (!strictModeEnabled()) {
+                        return;
+                    }
+                }
+            }
+        } catch (final Exception ignored) {
+            return;
+        }
+
+        if (isTest) {
+            final Map<String, String> testOptions = new HashMap<>();
+            if (compileFailure) {
+                testOptions.put(OPTIONS_EXPECT_COMPILE_FAIL, "true");
+            }
+            if (shouldRun) {
+                testOptions.put(OPTIONS_RUN, "true");
+            }
+            if (runFailure) {
+                testOptions.put(OPTIONS_EXPECT_RUN_FAIL, "true");
+            }
+            if (checkCompilerMsg) {
+                testOptions.put(OPTIONS_CHECK_COMPILE_MSG, "true");
+            }
+            if (!noCompare) {
+                testOptions.put(OPTIONS_COMPARE, "true");
+            }
+            if (ignoreStdError) {
+                testOptions.put(OPTIONS_IGNORE_STD_ERROR, "true");
+            }
+
+            tests.add(factory.createTest(framework, testFile.toFile(), engineOptions, testOptions, scriptArguments));
+        } else if (!isNotTest) {
+            orphans.add(name);
+        }
+    }
+
+    private static boolean strictModeEnabled() {
+        return Boolean.getBoolean(TEST_JS_ENABLE_STRICT_MODE);
+    }
+
+    private static Set<String> getExcludeSet() throws XPathExpressionException {
+        final String testExcludeList = System.getProperty(TEST_JS_EXCLUDE_LIST);
+
+        String[] testExcludeArray = {};
+        if (testExcludeList != null) {
+            testExcludeArray = testExcludeList.split(" ");
+        }
+        final Set<String> testExcludeSet = new HashSet<>(testExcludeArray.length);
+        for (final String test : testExcludeArray) {
+            testExcludeSet.add(test);
+        }
+
+        final String testExcludesFile = System.getProperty(TEST_JS_EXCLUDES_FILE);
+        if (testExcludesFile != null && !testExcludesFile.isEmpty()) {
+            try {
+                loadExcludesFile(testExcludesFile, testExcludeSet);
+            } catch (final XPathExpressionException e) {
+                System.err.println("Error: unable to load test excludes from " + testExcludesFile);
+                e.printStackTrace();
+                throw e;
+            }
+        }
+        return testExcludeSet;
+    }
+
+    private static void loadExcludesFile(final String testExcludesFile, final Set<String> testExcludeSet) throws XPathExpressionException {
+        final XPath xpath = XPathFactory.newInstance().newXPath();
+        final NodeList testIds = (NodeList)xpath.evaluate("/excludeList/test/@id", new InputSource(testExcludesFile), XPathConstants.NODESET);
+        for (int i = testIds.getLength() - 1; i >= 0; i--) {
+            testExcludeSet.add(testIds.item(i).getNodeValue());
+        }
+    }
+
+    private static Path[] getExcludeDirs() {
+        final String excludeDirs[] = System.getProperty(TEST_JS_EXCLUDE_DIR, "test/script/currently-failing").split(" ");
+        final Path[] excludePaths = new Path[excludeDirs.length];
+        final FileSystem fileSystem = FileSystems.getDefault();
+        int i = 0;
+        for (final String excludeDir : excludeDirs) {
+            excludePaths[i++] = fileSystem.getPath(excludeDir);
+        }
+        return excludePaths;
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestHelper.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestHelper.java
new file mode 100644
index 0000000..b48ed8b
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestHelper.java
@@ -0,0 +1,134 @@
+/*
+ * 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.test.framework;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.Reader;
+
+/**
+ * Simple utilities to deal with build-dir, read/dump files etc.
+ */
+public abstract class TestHelper {
+
+    public static final String TEST_ROOT   = "test";
+    public static final String BUILD_ROOT  = "build/test";
+    public static final String TEST_PREFIX = TEST_ROOT + File.separator;
+
+    private TestHelper() {
+        // empty
+    }
+
+    protected static File makeBuildDir(final File testFile) {
+        final File buildDir = getBuildDir(testFile);
+        if (!new File(BUILD_ROOT).exists()) {
+            throw new IllegalArgumentException("no " + BUILD_ROOT + " directory in " + new File(".").getAbsolutePath());
+        }
+        buildDir.mkdirs();
+        return buildDir;
+    }
+
+    protected static File getBuildDir(final File testFile) {
+        if (!testFile.getPath().startsWith(TEST_PREFIX)) {
+            throw new IllegalArgumentException("test file path not a relative pathname");
+        }
+        final File buildDir = new File(BUILD_ROOT + File.separator + testFile.getParent().substring(TEST_PREFIX.length()));
+        return buildDir;
+    }
+
+    // return the first line of the given file
+    protected static String firstLine(final File file) throws IOException {
+        return content(file, true);
+    }
+
+    // return the full content of the file as a String
+    protected static String fullContent(final File file) throws IOException {
+        return content(file, false);
+    }
+
+    private static String content(final File file, final boolean firstLine) throws IOException {
+        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        final PrintStream ps = new PrintStream(bos);
+        dumpFile(ps, file);
+        final String contents = bos.toString();
+
+        if (! firstLine) {
+            return contents;
+        }
+
+        // else return only the first line, stripping the trailing cr, lf or cr+lf,
+        // if present
+        final int cr = contents.indexOf('\r');
+        if (cr > 0) {
+            return contents.substring(0, cr);
+        }
+        final int lf = contents.indexOf('\n');
+        if (lf > 0) {
+            return contents.substring(0, lf);
+        }
+        return contents;
+    }
+
+    // dump the content of given reader on standard output
+    protected static void dumpFile(final Reader rdr) throws IOException {
+        dumpFile(System.out, rdr);
+    }
+
+    // dump the content of given reader on given output stream
+    protected static void dumpFile(final PrintStream output, final Reader rdr) throws IOException {
+        try (BufferedReader reader = new BufferedReader(rdr)) {
+            while (true) {
+                final String line = reader.readLine();
+                if (line == null) {
+                    break;
+                }
+                output.println(line);
+            }
+        }
+    }
+
+    // dump the content of given file on standard output
+    protected static void dumpFile(final File file) throws IOException {
+        dumpFile(System.out, file);
+    }
+
+    // dump the content of given file on given output stream
+    protected static void dumpFile(final PrintStream output, final File file) throws IOException {
+        try (Reader rdr = new FileReader(file); BufferedReader reader = new BufferedReader(rdr)) {
+            while (true) {
+                final String line = reader.readLine();
+                if (line == null) {
+                    break;
+                }
+                output.println(line);
+            }
+        }
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestReorderInterceptor.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestReorderInterceptor.java
new file mode 100644
index 0000000..7d7a7a3
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestReorderInterceptor.java
@@ -0,0 +1,59 @@
+/*
+ * 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.test.framework;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import org.testng.IMethodInstance;
+import org.testng.IMethodInterceptor;
+import org.testng.ITest;
+import org.testng.ITestContext;
+
+/**
+ * TestNG method interceptor to make sure that the tests are run in the test name order.
+ */
+public final class TestReorderInterceptor implements IMethodInterceptor {
+    @Override
+    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
+        Collections.sort(methods, new Comparator<IMethodInstance>() {
+            @Override
+            public int compare(final IMethodInstance mi1, final IMethodInstance mi2) {
+                // get test instances to order the tests.
+                final Object o1 = mi1.getInstance();
+                final Object o2 = mi2.getInstance();
+                if (o1 instanceof ITest && o2 instanceof ITest) {
+                    return ((ITest)o1).getTestName().compareTo(((ITest)o2).getTestName());
+                } else {
+                    // something else, don't care about the order
+                    return 0;
+                }
+            }
+        });
+
+        return methods;
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/ConstructorWithArgument.java b/nashorn/test/src/jdk/nashorn/internal/test/models/ConstructorWithArgument.java
new file mode 100644
index 0000000..ba4a216
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/ConstructorWithArgument.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.test.models;
+
+public abstract class ConstructorWithArgument {
+    private final String token;
+
+    protected ConstructorWithArgument(String token) {
+        this.token = token;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    protected abstract void doSomething();
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/DessertTopping.java b/nashorn/test/src/jdk/nashorn/internal/test/models/DessertTopping.java
new file mode 100644
index 0000000..8427c83
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/DessertTopping.java
@@ -0,0 +1,30 @@
+/*
+ * 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.test.models;
+
+public interface DessertTopping {
+    public String pourOnDessert();
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/DessertToppingFloorWaxDriver.java b/nashorn/test/src/jdk/nashorn/internal/test/models/DessertToppingFloorWaxDriver.java
new file mode 100644
index 0000000..dc04a0d
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/DessertToppingFloorWaxDriver.java
@@ -0,0 +1,36 @@
+/*
+ * 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.test.models;
+
+public class DessertToppingFloorWaxDriver {
+    public void decorateDessert(DessertTopping dt) {
+        dt.pourOnDessert();
+    }
+
+    public void waxFloor(FloorWax fw) {
+        fw.shineUpTheFloor();
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/FinalClass.java b/nashorn/test/src/jdk/nashorn/internal/test/models/FinalClass.java
new file mode 100644
index 0000000..b20257c
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/FinalClass.java
@@ -0,0 +1,30 @@
+/*
+ * 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.test.models;
+
+public final class FinalClass {
+    //empty
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/FloorWax.java b/nashorn/test/src/jdk/nashorn/internal/test/models/FloorWax.java
new file mode 100644
index 0000000..c094ccf
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/FloorWax.java
@@ -0,0 +1,30 @@
+/*
+ * 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.test.models;
+
+public interface FloorWax {
+    public String shineUpTheFloor();
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/NoAccessibleConstructorClass.java b/nashorn/test/src/jdk/nashorn/internal/test/models/NoAccessibleConstructorClass.java
new file mode 100644
index 0000000..c79edfb
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/NoAccessibleConstructorClass.java
@@ -0,0 +1,30 @@
+/*
+ * 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.test.models;
+
+public class NoAccessibleConstructorClass {
+    NoAccessibleConstructorClass() { }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/NonPublicClass.java b/nashorn/test/src/jdk/nashorn/internal/test/models/NonPublicClass.java
new file mode 100644
index 0000000..046cdf2
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/NonPublicClass.java
@@ -0,0 +1,30 @@
+/*
+ * 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.test.models;
+
+class NonPublicClass {
+    public NonPublicClass() { }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/OuterClass.java b/nashorn/test/src/jdk/nashorn/internal/test/models/OuterClass.java
new file mode 100644
index 0000000..cb9484b
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/OuterClass.java
@@ -0,0 +1,65 @@
+/*
+ * 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.test.models;
+
+public class OuterClass {
+    private final String value;
+
+    public OuterClass(String value) {
+        this.value = value;
+    }
+
+    public static class InnerStaticClass {
+        private final String value;
+
+        public InnerStaticClass(String value) {
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return "InnerStaticClass[value=" + value + "]";
+        }
+    }
+
+    public class InnerNonStaticClass {
+        private final String value;
+
+        public InnerNonStaticClass(String value) {
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return "InnerNonStaticClass[value=" + value + ", outer=" + OuterClass.this + "]";
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "OuterClass[value=" + value + "]";
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/OverloadedSam.java b/nashorn/test/src/jdk/nashorn/internal/test/models/OverloadedSam.java
new file mode 100644
index 0000000..c63da54
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/OverloadedSam.java
@@ -0,0 +1,31 @@
+/*
+ * 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.test.models;
+
+public interface OverloadedSam {
+    public void sam(String s);
+    public void sam(String s1, String s2);
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/OverrideObject.java b/nashorn/test/src/jdk/nashorn/internal/test/models/OverrideObject.java
new file mode 100644
index 0000000..40cf7f9
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/OverrideObject.java
@@ -0,0 +1,44 @@
+/*
+ * 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.test.models;
+
+public class OverrideObject {
+    @Override
+    public int hashCode() {
+        return 5;
+    }
+
+    @Override
+    public String toString() {
+        return "override-object";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        // TODO: add a FindBugs annotation to ignore EQ_ALWAYS_FALSE here. This is just a test.
+        return false;
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/StringArgs.java b/nashorn/test/src/jdk/nashorn/internal/test/models/StringArgs.java
new file mode 100644
index 0000000..8ecdbfd
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/StringArgs.java
@@ -0,0 +1,39 @@
+/*
+ * 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.test.models;
+
+import java.util.List;
+
+public class StringArgs {
+
+    public static void checkString(List<?> list) {
+        for (Object s : list) {
+            if (!(s instanceof String)) {
+                throw new AssertionError("Not a String: " + s);
+            }
+        }
+    }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/Toothpaste.java b/nashorn/test/src/jdk/nashorn/internal/test/models/Toothpaste.java
new file mode 100644
index 0000000..0946eb3
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/test/models/Toothpaste.java
@@ -0,0 +1,34 @@
+/*
+ * 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.test.models;
+
+public abstract class Toothpaste {
+    public void applyToBrush() {
+        applyToBrushImpl();
+    }
+
+    protected abstract void applyToBrushImpl();
+}